- page-break-before: always|left|right - NB any surrounding block tags will be closed before the new page is inserted.
+
+@page - see notes on Paged Media
+
+==========================
+Unsupported HTML attribute
+==========================
+| - not valid HTML - no longer supported
+
+
+=========
+Additions
+=========
+"Keep-with-table"
+$mpdf->use_kwt = true; // default=false
+If set to true, will force any H1-H6 header immediately preceding a table to be kept together with the table
+- automatically sets the table to fit on one page (i.e. page-break-inside=avoid) if it is a rotated table
+- ignored if: Columns on, Keep-block-together active (page-break-inside=avoid for surrounding BLOCK), active Forms
+
+
+=====
+Notes
+=====
+
+NB Not a change - but note you can use this to allow you to feed html code encoded in other than utf-8:
+$mpdf->allow_charset_conversion=true;
+$mpdf->charset_in='windows-1252'; (needs suitable codes for iconv i.e. windows-1252 not win-1252)
+
+Fixing Optional tags
+====================
+php.net website has illegal nesting of .. .. .. and .. .. ..
+The example wich parses the php.net webpage will not show correctly unless you change: $mpdf->allow_html_optional_endtags=false;
+Trying to fix incorrect (X)HTML with $mpdf->allow_html_optional_endtags==true cancels the P when it meets a DIV etc.
+
+
+
+EAN barcode
+===========
+An EAN barcode can be generated
+function writeBarcode($code, $showisbn=1, $x='', $y='', $size=1, $border=0, $paddingL=1, $paddingR=1, $paddingT=2, $paddingB=2) {
+It accepts 12 or 13 digits with or without - hyphens as $code e.g.
+$mpdf->writeBarcode('978-1234-567-890', 1, $mpdf->x, $mpdf->y);
+NB - IMPORTANT***
+A new font - OCR-B font/unifont is required, and needs to be added to the config.php file
+cf. http://www.gs1uk.org/downloads/bar_code/Bar coding getting it right.pdf
+Barcode size must be between 0.8 and 2.0 (80% to 200%)
+
+CMYK Colors
+===========
+Functions - SetDrawColor, SetTextColor and SetFillColor all now take an optional 4th parameter.
+If defined this will interpret the input as CMYK color i.e.
+SetDrawColor(15,82,0,10) // NB all values out of 100 - not 255 as for RGB
+
+htmltoolkit.php fn.ConvertColor() - now interprets custom color definition: cmyk(15,82,0,10)
+like rgb(r,g,b) except values out of 100
+Intended to be used for calling the functions separately - BUT works in a limited way with CSS - does not get reset or inherited correctly
+ does work
+
+
+DEFAULT CSS
+===========
+$defaultCSS has been updated to reflect better the standard HTML default e.g. using serif, table borders separate, cell vertical-align top
+To keep mPDF 1.3 (my favourites) I have introduced:
+$mpdf->useDefaultCSS2 = true;
+
+
+===================================
+Permissions - forms and Annotations - Experimental!
+===================================
+You can set the Permissions for the PDF file to allow the user to make Comments (annotations)
+$mpdf->setUserRights($enabled=true[default]|false, $annots="/Create/Delete/Modify/Copy/Import/Export",
+ $form="/Add/Delete/FillIn/Import/Export/SubmitStandalone/SpawnTemplate", $signature="/Modify") )
+
+If you encrypt the file, make sure the permissions match e.g.:
+$mpdf->setUserRights();
+$mpdf->SetProtection(array('print','annots'),'yourPassword','myPassword');
+
+To allow this, changed the PDF-file version to %PDF1.5 (NB Probably needs PDF version > 1.5 but can't test for this...)
+
+NOTE: If you output the PDF file straight to the browser, it will only allow annotations after you save the document
+
+
+===========================
+Active Forms - Experimental!
+===========================
+At present , using active forms will prevent any internal and external links - that appear before active forms(?) - from working (why?)
+May need to save form for proper use - see example, when scroll forwards and back, the form disappears??
+Need to set Userrights (see above), and $mpdf->useActiveForms=true;
+For Output options, see separate notes.
+
+
+
+============================
+Internal Programming changes
+============================
+NB fn. tablerotate in htmltoolkit no longer used; now uses a 'transform' to shift the whole block of PDF code
+
+Graphics State
+==============
+ExtGState does not need to be redefined - e.g. if a watermark added on every page, turning on and off alpha/transparency
+Unnecessary file size.
+function AddExtGState() edited to check if graphics state already exists before adding new one
+
+ASCII-proof code
+================
+"»¤¬" used as a special identifier in the program changed to "\xbb\xa4\xac" to make the mpdf.php script file immune from someone saving it as a utf-8 encoded file
+
+Images
+======
+1) When copying remote images locally - incorrectly used "unset" now changed to "unlink"
+2) When parsing image files - was using CURL for any image src="http://... - even if this was on the local server - edited so it only uses CURL if necessary/appropriate.
+NB Handling images was updated in v1.3 because my ISP changed allow_url_fopen to false
+Fixed so mPDF tests if the file is available as a local call e.g. getimage('images/test.jpg') even if it is defined as a full URI e.g. http://www.mydomain.com/images/test.jpg as this is quicker(?), and permitted even if allow_url_fopen is false.
+If not available as a local file (and allow_url_fopen is set) mPDF tries to use fopen/file_get_contents using an http wrapper;
+Else, if CURL is available and allow_url_fopen is false: then tries using CURL.
+(Clear as mud???!!)
+
+
+===========================
+mPDF v1.3 (21/09/2008)
+===========================
+--------------
+Page Numbering
+--------------
+Program changes:
+fn. startPageNums() replaced with blank function
+fn. stopPageNums() - deleted
+fn. numPageNo() - deleted (all it did was return this->page anyway).
+var $_numbering - deleted
+var $_numberingFooter - deleted
+var $_numPageNum - deleted
+
+NEW
+New: fn. AddPages() (as for AddPage but with type=NEXT-ODD or NEXT-EVEN see below)
+Edited: fn. AddPage() - new parameters added
+AddPage(orientation(NO),type="E|O", resetpagenum="1|0", pagenumstyle="I|i|A|a|1", suppress="on|off")
+New: fn. docPageNum() - returns the document page number (or '') based on...
+New : PageNumSubstitutions(array)
+New attributes:
+
+
+
+--------------------------------------------
+Changes to allow Rotated Text in table Cells
+--------------------------------------------
+Edited:
+fn. OpenTag()
+fn. _tableColumnWidth()
+fn. _tableHeight()
+fn. _tableWrite()
+fn. tableHeader()
+
+New custom style or attribute -- "text-rotate" -- can be set for either or
+Allowed values: 45 - 90 (written as integers) - rotates text anticlockwise, and -90 (clockwise)
+Positive values less than 90 force cell to: vertical-align:bottom
+
+Limitations:
+Only allows single line of text;
+Font, font-size, and style are determined by those set fro the cell, and cannot be changed;
+No changes in font (or any other in-line changes e.g. ) are supported within the text
+
+Example: ...
+
+---------
+Bug fixes
+---------
+1) HTML footer containing table was triggering page break.
+Added $this->InHTMLFooter as flag to prevent page triggering in footers containing table
+Set in fn.writeHTMLFooters() -> in fn.tableWrite() stops the pageBreak being reset
+
+2) Crashing when libcurl not installed.
+Edited OpenTag() curl_init - added if (function_exists) to exclude crash when libcurl not installed
+
+3) Single cell with borders not showing the borders.
+e.g. etc
+
+Memory Optimization added (script from FPDF site) - edited fn. _putpages() and fn. _endpage()
+
+fn. SetFont() edited to return val quicker if font already set (increase efficiency)
+
+new vars chrs and ords are used to store chr() and ord() - quicker than using functions
+
+fn.setMBencoding() - only call mb_internal_encoding if need to change
+
+Bugs
+----
+fn. SetDefaultFontSize() - edited to allow to override that set in defaultCSS
+
+fn. Output() - Added temporary(?) disablement of encryption in CJK as it doesn't work!
+
+fn. OpenTag() [LI] $this->blockjustfinished=false to prevents newline after first bullet of list within table
+
+Uses of mb_ereg_replace removed, and mb_split changed - requires regex_encoding (regex_encoding only used as UTF-8)
+
+fn. WriteHTML: attributes are trimmed with trim() to allow correct handling of e.g. class="bpmBook "
+
+fn. printbuffer() and fn. openTag() to ensure
+ outputs top margins/padding for both 1st and 2nd div
+ and ...
+
+fn. SetFont() added line - bug fixing in CJK fonts
+
+CSS functionality
+-----------------
+Added special CSS 'thead-underline' (similar to topntail)
+
+var $thead_font_weight; added (openTag) to enable setting of font-weight for | cells
+
+Fixed table border inheritance: Table border inherits border="1" to cells, but not table style="border..."
+
+"page-break-inside: avoid" added (var keep_block_together) to allow a DIV or P to be kept on one page
+ - not compatible with table autosize or table rotate
+ - only works over maximum of 2 pages
+
+Enhancements
+------------
+Orphans in line justification: R. Bracket ) added to defined list of orphans
+
+allow_url_open
+--------------
+Following a change in the PHP ini config set on my website by my ISP, changes made to allow mPDF to work with allow_url_open=OFF.
+ - file_get_contents() changed to use libcurl (for CSS files)
+ - openTag('IMG') @fopen() and 3 functions _parsegif, _parseJPG, _parsePNG, edited to copy remote image files to local file to include images
+
+FlowChart
+---------
+Changes to enable mPDF work with a custom script producing Flowcharts:
+ - WriteHTML() second parameter=3 will allow HTML to be parsed but not output
+ - fn. Arrow() added
+ - TableWordWrap() added parameter to force array return
diff --git a/mpdf/CREDITS.txt b/mpdf/CREDITS.txt
new file mode 100644
index 0000000..3fa5584
--- /dev/null
+++ b/mpdf/CREDITS.txt
@@ -0,0 +1,92 @@
+
+
+/*******************************************************************************
+* Software: FPDF *
+* Version: 1.53 *
+* Date: 2004-12-31 *
+* Author: Olivier PLATHEY *
+* License: Freeware *
+* *
+* You may use and modify this software as you wish. *
+*******************************************************************************/
+
+/*******************************************************************************
+* HTML2FPDF is a php script to read a HTML text and generate a PDF file. *
+* Copyright (C) 2004-2005 Renato Coelho *
+* *
+* html2fpdf.php, htmltoolkit.php *
+*******************************************************************************/
+
+CREDITS From HTML2FPDF:
+
+-Olivier Plathey for the fpdf.php class [http://www.fpdf.org]
+-Damon Kohler for the Flowing Block script [mailto:damonkohler@yahoo.com]
+-Clément Lavoillotte for HTML-oriented FPDF idea
+-Yamasoft for the gif.php class [http://www.yamasoft.com/]
+-Jérôme Fenal for the _parsegif() function
+-"VIETCOM" for the PDFTable code [http://www.freepgs.com/vietcom/tool/pdftable/] [mailto:vncommando@yahoo.com]
+-Yukihiro O. for the SetDash() function [mailto:yukihiro_o@infoseek.jp]
+-Ron Korving for the WordWrap() function
+-Michel Poulain for the DisplayPreferences() function
+-Patrick Benny for the MultiCellBlt() function idea [no longer in use]
+-Seb for the _SetTextRendering() and SetTextOutline() functions [mailto:captainseb@wanadoo.fr]
+-MorphSoft for the colornames list idea
+-W3SCHOOLS for HTML-related reference info [http://www.w3schools.com/]
+
+
+
+/****************************************************************************
+* Software: FPDF_Protection *
+* Version: 1.02 *
+* Date: 2005/05/08 *
+* Author: Klemen VODOPIVEC *
+* License: Freeware *
+* *
+* You may use and modify this software as you wish as stated in original *
+* FPDF package. *
+****************************************************************************/
+
+/****************************************************************************
+// FPDI - Version 1.2
+//
+// Copyright 2004-2007 Setasign - Jan Slabon
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+****************************************************************************/
+
+/****************************************************************************
+ * @copyright Khaled Al-Shamaa 2008
+ * @link http://www.ar-php.org
+ * @author Khaled Al-Shamaa
+ * @desc Set of PHP5 / UTF-8 Classes developed to enhance Arabic web
+ * applications by providing set of tools includes stem-based searching,
+ * translitiration, soundex, Hijri calendar, charset detection and
+ * converter, spell numbers, keyboard language, Muslim prayer time,
+ * auto-summarization, and more...
+ * @package Arabic
+ *
+ * @version 1.8 released in Feb 15, 2009
+ *
+ * @license LGPL
+****************************************************************************/
+
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation;
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+[http://www.opensource.org/licenses/lgpl-license.php]
+
diff --git a/mpdf/LICENSE.txt b/mpdf/LICENSE.txt
new file mode 100644
index 0000000..5b6e7c6
--- /dev/null
+++ b/mpdf/LICENSE.txt
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 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.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, 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 or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+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 give any other recipients of the Program a copy of this License
+along with the Program.
+
+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 Program or any portion
+of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+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 Program, 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 Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) 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; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, 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 executable. However, as a
+special exception, the source code 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.
+
+If distribution of executable or 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 counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program 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.
+
+ 5. 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 Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program 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 to
+this License.
+
+ 7. 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 Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program 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 Program.
+
+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.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program 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.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the 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 Program
+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 Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, 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
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ , 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/mpdf/README.txt b/mpdf/README.txt
new file mode 100644
index 0000000..d66926e
--- /dev/null
+++ b/mpdf/README.txt
@@ -0,0 +1,130 @@
+Installation
+============
+ * Download the .zip file and unzip it
+ * Create a folder e.g. /mpdf on your server
+ * Upload all of the files to the server, maintaining the folders as they are
+ * Ensure that you have write permissions set (CHMOD 6xx or 7xx) for the following folders:
+ /ttfontdata/ - used to cache font data; improves performance a lot
+ /tmp/ - used for some images and ProgressBar
+ /graph_cache/ - if you are using JpGraph in conjunction with mPDF
+
+To test the installation, point your browser to the basic example file : [path_to_mpdf_folder]/mpdf/examples/example01_basic.php
+
+If you wish to define a different folder for temporary files rather than /tmp/ see the note on 'Folder for temporary files' in
+ the section on Installation & Setup in the manual (http://mpdf1.com/manual/).
+
+If you have problems, please read the section on troubleshooting in the manual.
+
+
+Fonts
+=====
+Let us refer to font names in 2 ways:
+"CSS font-family name" - mPDF is designed primarily to read HTML and CSS. This is the name used in CSS e.g.
+
+
+"mPDF font-family name" - the name used internally to process fonts. This could be anything you like,
+ but by default mPDF will convert CSS font-family names by removing any spaces and changing
+ to lowercase. Reading the name above, mPDF will look for a "mPDF font-family name" of
+ 'trebuchetms'.
+
+The configurable values referred to below are set in the config_fonts.php file
+
+When parsing HTML/CSS, mPDF will read the CSS font-family name (e.g. 'Trebuchet MS') and convert
+by removing any spaces and changing to lowercase, to look for a mPDF font-family name (trebuchetms).
+
+Next it will look for a translation (if set) in config_font.php e.g.:
+$this->fonttrans = array(
+ 'trebuchetms' => 'trebuchet'
+)
+
+Now the mPDF font-family name to be used is 'trebuchet'
+
+If you wish to make this font available, you need to specify the Truetype .ttf font files for each variant.
+These should be defined in config_font.php in the array:
+$this->fontdata = array(
+ "trebuchet" => array(
+ 'R' => "trebuc.ttf",
+ 'B' => "trebucbd.ttf",
+ 'I' => "trebucit.ttf",
+ 'BI' => "trebucbi.ttf",
+ )
+)
+
+This is the array which determines whether a font is available to mPDF. Each font-family must have a
+Regular ['R'] file defined - the others (bold, italic, bold-italic) are optional.
+
+mPDF will try to load the font-file. If you have defined _MPDF_SYSTEM_TTFONTS at the top of the
+config_fonts.php file, it will first look for the font-file there. This is useful if you are running
+mPDF on a computer which already has a folder with TTF fonts in (e.g. on Windows)
+
+If the font-file is not there, or _MPDF_SYSTEM_TTFONTS is not defined, mPDF will look in the folder
+/[your_path_to_mpdf]/ttfonts/
+
+Note that the font-file names are case-sensitive and can contain capitals.
+
+If the folder /ttfontdata/ is writeable (CHMOD 644 or 755), mPDF will save files there which it can
+re-use next time it accesses a particular font. This will significantly improve processing time
+and is strongly recommended.
+
+mPDF should be able to read most TrueType Unicode font files with a .ttf extension
+Truetype fonts with .otf extension that are OpenType also work OK.
+TrueType collections (.ttc) will also work if they contain TrueType Unicode fonts.
+
+
+Character substitution
+----------------------
+Most people will have access to a Pan-Unicode font with most Unicode characters in it such as
+Arial Unicode MS. Set $this->backupSubsFont = array('arialunicodems'); at the top of the config_fonts.php file
+to use this font when substituting any characters not found in the specific font being used.
+
+Example:
+You can set $mpdf->useSubstitutions = true; at runtime
+or $this->useSubstitutions = true; in the config.php file
+
+ This text contains a Thai character ม which does not exist
+in the Comic Sans MS font file
+
+When useSubstitutions is true, mPDF will try to find substitutions for any missing characters:
+1) firstly looks if the character is available in the inbuilt Symbols or ZapfDingbats fonts;
+2) [If defined] looks in each of the the font(s) set by $this->backupSubsFont array
+
+NB There is an increase in processing time when using substitutions, and even more so if
+a backupSubsFont is defined.
+
+Controlling mPDF mode
+=====================
+The first parameter of new mPDF('') works as follows:
+new mPDF('c') - forces mPDF to only use the built-in [c]ore Adobe fonts (Helvetica, Times etc)
+
+new mPDF('') - default - font subsetting behaviour is determined by the configurable variables
+ $this->maxTTFFilesize and $this->percentSubset (see below)
+ Default values are set so that: 1) very large font files are always subset
+ 2) Fonts are embedded as subsets if < 30% of the characters are used
+
+new mPDF('..+aCJK') new mPDF('+aCJK')
+new mPDF('..-aCJK') new mPDF('-aCJK')
+ - used optionally together with a language or language/country code, +aCJK will force mPDF
+ to use the Adobe non-embedded CJK fonts when a passage is marked with e.g. "lang: ja"
+ This can be used at runtime to override the value set for $mpdf->useAdobeCJK in config.php
+ Use in conjunction with settings in config_cp.php
+
+For backwards compatibility, new mPDF('-s') and new mPDF('s') will force subsetting by
+ setting $this->percentSubset=100
+ new mPDF('utf-8-s') and new mPDF('ar-s') are also recognised
+
+
+
+
+Configuration variables changed
+===============================
+Configuration variables are documented in the on-line manual (http://mpdf1.com/manual/).
+
+
+Font folders
+============
+If you wish to define your own font file folders (perhaps to share),
+you can define the 2 constants in your script before including the mpdf.php script e.g.:
+
+define('_MPDF_TTFONTPATH','your_path/ttfonts/');
+define('_MPDF_TTFONTDATAPATH','your_path/ttfontdata/'); // should be writeable
+
diff --git a/mpdf/classes/barcode.php b/mpdf/classes/barcode.php
new file mode 100644
index 0000000..9a28a86
--- /dev/null
+++ b/mpdf/classes/barcode.php
@@ -0,0 +1,1972 @@
+.
+//
+// See LICENSE.TXT file for more information.
+// ----------------------------------------------------------------------------
+//
+// Description : PHP class to creates array representations for
+// common 1D barcodes to be used with TCPDF.
+//
+// Author: Nicola Asuni
+//
+// (c) Copyright:
+// Nicola Asuni
+// Tecnick.com S.r.l.
+// Via della Pace, 11
+// 09044 Quartucciu (CA)
+// ITALY
+// www.tecnick.com
+// info@tecnick.com
+//============================================================+
+
+class PDFBarcode {
+
+ protected $barcode_array;
+ protected $gapwidth;
+ protected $print_ratio;
+ protected $daft;
+
+ public function __construct() {
+
+ }
+
+ public function getBarcodeArray($code, $type, $pr='') {
+ $this->setBarcode($code, $type, $pr);
+ return $this->barcode_array;
+ }
+ public function getChecksum($code, $type) {
+ $this->setBarcode($code, $type);
+ if (!$this->barcode_array) { return ''; }
+ else { return $this->barcode_array['checkdigit']; }
+ }
+
+ public function setBarcode($code, $type, $pr='') {
+ $this->print_ratio = 1;
+ switch (strtoupper($type)) {
+ case 'ISBN':
+ case 'ISSN':
+ case 'EAN13': { // EAN 13
+ $arrcode = $this->barcode_eanupc($code, 13);
+ $arrcode['lightmL'] = 11; // LEFT light margin = x X-dim (http://www.gs1uk.org)
+ $arrcode['lightmR'] = 7; // RIGHT light margin = x X-dim (http://www.gs1uk.org)
+ $arrcode['nom-X'] = 0.33; // Nominal value for X-dim in mm (http://www.gs1uk.org)
+ $arrcode['nom-H'] = 25.93; // Nominal bar height in mm incl. numerals (http://www.gs1uk.org)
+ break;
+ }
+ case 'UPCA': { // UPC-A
+ $arrcode = $this->barcode_eanupc($code, 12);
+ $arrcode['lightmL'] = 9; // LEFT light margin = x X-dim (http://www.gs1uk.org)
+ $arrcode['lightmR'] = 9; // RIGHT light margin = x X-dim (http://www.gs1uk.org)
+ $arrcode['nom-X'] = 0.33; // Nominal value for X-dim in mm (http://www.gs1uk.org)
+ $arrcode['nom-H'] = 25.91; // Nominal bar height in mm incl. numerals (http://www.gs1uk.org)
+ break;
+ }
+ case 'UPCE': { // UPC-E
+ $arrcode = $this->barcode_eanupc($code, 6);
+ $arrcode['lightmL'] = 9; // LEFT light margin = x X-dim (http://www.gs1uk.org)
+ $arrcode['lightmR'] = 7; // RIGHT light margin = x X-dim (http://www.gs1uk.org)
+ $arrcode['nom-X'] = 0.33; // Nominal value for X-dim in mm (http://www.gs1uk.org)
+ $arrcode['nom-H'] = 25.93; // Nominal bar height in mm incl. numerals (http://www.gs1uk.org)
+ break;
+ }
+ case 'EAN8': { // EAN 8
+ $arrcode = $this->barcode_eanupc($code, 8);
+ $arrcode['lightmL'] = 7; // LEFT light margin = x X-dim (http://www.gs1uk.org)
+ $arrcode['lightmR'] = 7; // RIGHT light margin = x X-dim (http://www.gs1uk.org)
+ $arrcode['nom-X'] = 0.33; // Nominal value for X-dim in mm (http://www.gs1uk.org)
+ $arrcode['nom-H'] = 21.64; // Nominal bar height in mm incl. numerals (http://www.gs1uk.org)
+ break;
+ }
+ case 'EAN2': { // 2-Digits UPC-Based Extention
+ $arrcode = $this->barcode_eanext($code, 2);
+ $arrcode['lightmL'] = 7; // LEFT light margin = x X-dim (estimated)
+ $arrcode['lightmR'] = 7; // RIGHT light margin = x X-dim (estimated)
+ $arrcode['sepM'] = 9; // SEPARATION margin = x X-dim (http://web.archive.org/web/19990501035133/http://www.uc-council.org/d36-d.htm)
+ $arrcode['nom-X'] = 0.33; // Nominal value for X-dim in mm (http://www.gs1uk.org)
+ $arrcode['nom-H'] = 20; // Nominal bar height in mm incl. numerals (estimated) not used when combined
+ break;
+ }
+ case 'EAN5': { // 5-Digits UPC-Based Extention
+ $arrcode = $this->barcode_eanext($code, 5);
+ $arrcode['lightmL'] = 7; // LEFT light margin = x X-dim (estimated)
+ $arrcode['lightmR'] = 7; // RIGHT light margin = x X-dim (estimated)
+ $arrcode['sepM'] = 9; // SEPARATION margin = x X-dim (http://web.archive.org/web/19990501035133/http://www.uc-council.org/d36-d.htm)
+ $arrcode['nom-X'] = 0.33; // Nominal value for X-dim in mm (http://www.gs1uk.org)
+ $arrcode['nom-H'] = 20; // Nominal bar height in mm incl. numerals (estimated) not used when combined
+ break;
+ }
+
+ case 'IMB': { // IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200
+ $xdim = 0.508; // Nominal value for X-dim (bar width) in mm (spec.)
+ $bpi = 22; // Bars per inch
+ // Ratio of Nominal value for width of spaces in mm / Nominal value for X-dim (bar width) in mm based on bars per inch
+ $this->gapwidth = ((25.4/$bpi) - $xdim)/$xdim;
+ $this->daft = array('D'=>2, 'A'=>2, 'F'=>3, 'T'=>1); // Descender; Ascender; Full; Tracker bar heights
+ $arrcode = $this->barcode_imb($code);
+ $arrcode['nom-X'] = $xdim ;
+ $arrcode['nom-H'] = 3.68; // Nominal value for Height of Full bar in mm (spec.)
+ // USPS-B-3200 Revision C = 4.623
+ // USPS-B-3200 Revision E = 3.68
+ $arrcode['quietL'] = 3.175; // LEFT Quiet margin = mm (spec.)
+ $arrcode['quietR'] = 3.175; // RIGHT Quiet margin = mm (spec.)
+ $arrcode['quietTB'] = 0.711; // TOP/BOTTOM Quiet margin = mm (spec.)
+ break;
+ }
+ case 'RM4SCC': { // RM4SCC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code)
+ $xdim = 0.508; // Nominal value for X-dim (bar width) in mm (spec.)
+ $bpi = 22; // Bars per inch
+ // Ratio of Nominal value for width of spaces in mm / Nominal value for X-dim (bar width) in mm based on bars per inch
+ $this->gapwidth = ((25.4/$bpi) - $xdim)/$xdim;
+ $this->daft = array('D'=>5, 'A'=>5, 'F'=>8, 'T'=>2); // Descender; Ascender; Full; Tracker bar heights
+ $arrcode = $this->barcode_rm4scc($code, false);
+ $arrcode['nom-X'] = $xdim ;
+ $arrcode['nom-H'] = 5.0; // Nominal value for Height of Full bar in mm (spec.)
+ $arrcode['quietL'] = 2; // LEFT Quiet margin = mm (spec.)
+ $arrcode['quietR'] = 2; // RIGHT Quiet margin = mm (spec.)
+ $arrcode['quietTB'] = 2; // TOP/BOTTOM Quiet margin = mm (spec?)
+ break;
+ }
+ case 'KIX': { // KIX (Klant index - Customer index)
+ $xdim = 0.508; // Nominal value for X-dim (bar width) in mm (spec.)
+ $bpi = 22; // Bars per inch
+ // Ratio of Nominal value for width of spaces in mm / Nominal value for X-dim (bar width) in mm based on bars per inch
+ $this->gapwidth = ((25.4/$bpi) - $xdim)/$xdim;
+ $this->daft = array('D'=>5, 'A'=>5, 'F'=>8, 'T'=>2); // Descender; Ascender; Full; Tracker bar heights
+ $arrcode = $this->barcode_rm4scc($code, true);
+ $arrcode['nom-X'] = $xdim ;
+ $arrcode['nom-H'] = 5.0; // Nominal value for Height of Full bar in mm (? spec.)
+ $arrcode['quietL'] = 2; // LEFT Quiet margin = mm (spec.)
+ $arrcode['quietR'] = 2; // RIGHT Quiet margin = mm (spec.)
+ $arrcode['quietTB'] = 2; // TOP/BOTTOM Quiet margin = mm (spec.)
+ break;
+ }
+ case 'POSTNET': { // POSTNET
+ $xdim = 0.508; // Nominal value for X-dim (bar width) in mm (spec.)
+ $bpi = 22; // Bars per inch
+ // Ratio of Nominal value for width of spaces in mm / Nominal value for X-dim (bar width) in mm based on bars per inch
+ $this->gapwidth = ((25.4/$bpi) - $xdim)/$xdim;
+ $arrcode = $this->barcode_postnet($code, false);
+ $arrcode['nom-X'] = $xdim ;
+ $arrcode['nom-H'] = 3.175; // Nominal value for Height of Full bar in mm (spec.)
+ $arrcode['quietL'] = 3.175; // LEFT Quiet margin = mm (?spec.)
+ $arrcode['quietR'] = 3.175; // RIGHT Quiet margin = mm (?spec.)
+ $arrcode['quietTB'] = 1.016; // TOP/BOTTOM Quiet margin = mm (?spec.)
+ break;
+ }
+ case 'PLANET': { // PLANET
+ $xdim = 0.508; // Nominal value for X-dim (bar width) in mm (spec.)
+ $bpi = 22; // Bars per inch
+ // Ratio of Nominal value for width of spaces in mm / Nominal value for X-dim (bar width) in mm based on bars per inch
+ $this->gapwidth = ((25.4/$bpi) - $xdim)/$xdim;
+ $arrcode = $this->barcode_postnet($code, true);
+ $arrcode['nom-X'] = $xdim ;
+ $arrcode['nom-H'] = 3.175; // Nominal value for Height of Full bar in mm (spec.)
+ $arrcode['quietL'] = 3.175; // LEFT Quiet margin = mm (?spec.)
+ $arrcode['quietR'] = 3.175; // RIGHT Quiet margin = mm (?spec.)
+ $arrcode['quietTB'] = 1.016; // TOP/BOTTOM Quiet margin = mm (?spec.)
+ break;
+ }
+
+ case 'C93': { // CODE 93 - USS-93
+ $arrcode = $this->barcode_code93($code);
+ if ($arrcode == false) { break; }
+ $arrcode['nom-X'] = 0.381; // Nominal value for X-dim (bar width) in mm (2 X min. spec.)
+ $arrcode['nom-H'] = 10; // Nominal value for Height of Full bar in mm (non-spec.)
+ $arrcode['lightmL'] = 10; // LEFT light margin = x X-dim (spec.)
+ $arrcode['lightmR'] = 10; // RIGHT light margin = x X-dim (spec.)
+ $arrcode['lightTB'] = 0; // TOP/BOTTOM light margin = x X-dim (non-spec.)
+ break;
+ }
+ case 'CODE11': { // CODE 11
+ if ($pr > 0) { $this->print_ratio = $pr; }
+ else { $this->print_ratio = 3; } // spec: Pr= 1:2.24 - 1:3.5
+ $arrcode = $this->barcode_code11($code);
+ if ($arrcode == false) { break; }
+ $arrcode['nom-X'] = 0.381; // Nominal value for X-dim (bar width) in mm (2 X min. spec.)
+ $arrcode['nom-H'] = 10; // Nominal value for Height of Full bar in mm (non-spec.)
+ $arrcode['lightmL'] = 10; // LEFT light margin = x X-dim (spec.)
+ $arrcode['lightmR'] = 10; // RIGHT light margin = x X-dim (spec.)
+ $arrcode['lightTB'] = 0; // TOP/BOTTOM light margin = x X-dim (non-spec.)
+ break;
+ }
+ case 'MSI': // MSI (Variation of Plessey code)
+ case 'MSI+': { // MSI + CHECKSUM (modulo 11)
+ if (strtoupper($type)=='MSI') { $arrcode = $this->barcode_msi($code, false); }
+ if (strtoupper($type)=='MSI+') { $arrcode = $this->barcode_msi($code, true); }
+ if ($arrcode == false) { break; }
+ $arrcode['nom-X'] = 0.381; // Nominal value for X-dim (bar width) in mm (2 X min. spec.)
+ $arrcode['nom-H'] = 10; // Nominal value for Height of Full bar in mm (non-spec.)
+ $arrcode['lightmL'] = 12; // LEFT light margin = x X-dim (spec.)
+ $arrcode['lightmR'] = 12; // RIGHT light margin = x X-dim (spec.)
+ $arrcode['lightTB'] = 0; // TOP/BOTTOM light margin = x X-dim (non-spec.)
+ break;
+ }
+ case 'CODABAR': { // CODABAR
+ if ($pr > 0) { $this->print_ratio = $pr; }
+ else { $this->print_ratio = 2.5; } // spec: Pr= 1:2 - 1:3 (>2.2 if X<0.50)
+ if (strtoupper($type)=='CODABAR') { $arrcode = $this->barcode_codabar($code); }
+ if ($arrcode == false) { break; }
+ $arrcode['nom-X'] = 0.381; // Nominal value for X-dim (bar width) in mm (2 X min. spec.)
+ $arrcode['nom-H'] = 10; // Nominal value for Height of Full bar in mm (non-spec.)
+ $arrcode['lightmL'] = 10; // LEFT light margin = x X-dim (spec.)
+ $arrcode['lightmR'] = 10; // RIGHT light margin = x X-dim (spec.)
+ $arrcode['lightTB'] = 0; // TOP/BOTTOM light margin = x X-dim (non-spec.)
+ break;
+ }
+ case 'C128A': // CODE 128 A
+ case 'C128B': // CODE 128 B
+ case 'C128C': // CODE 128 C
+ case 'EAN128A': // EAN 128 A
+ case 'EAN128B': // EAN 128 B
+ case 'EAN128C': { // EAN 128 C
+ if (strtoupper($type)=='C128A') { $arrcode = $this->barcode_c128($code, 'A'); }
+ if (strtoupper($type)=='C128B') { $arrcode = $this->barcode_c128($code, 'B'); }
+ if (strtoupper($type)=='C128C') { $arrcode = $this->barcode_c128($code, 'C'); }
+ if (strtoupper($type)=='EAN128A') { $arrcode = $this->barcode_c128($code, 'A', true); }
+ if (strtoupper($type)=='EAN128B') { $arrcode = $this->barcode_c128($code, 'B', true); }
+ if (strtoupper($type)=='EAN128C') { $arrcode = $this->barcode_c128($code, 'C', true); }
+ if ($arrcode == false) { break; }
+ $arrcode['nom-X'] = 0.381; // Nominal value for X-dim (bar width) in mm (2 X min. spec.)
+ $arrcode['nom-H'] = 10; // Nominal value for Height of Full bar in mm (non-spec.)
+ $arrcode['lightmL'] = 10; // LEFT light margin = x X-dim (spec.)
+ $arrcode['lightmR'] = 10; // RIGHT light margin = x X-dim (spec.)
+ $arrcode['lightTB'] = 0; // TOP/BOTTOM light margin = x X-dim (non-spec.)
+ break;
+ }
+ case 'C39': // CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.
+ case 'C39+': // CODE 39 with checksum
+ case 'C39E': // CODE 39 EXTENDED
+ case 'C39E+': { // CODE 39 EXTENDED + CHECKSUM
+ if ($pr > 0) { $this->print_ratio = $pr; }
+ else { $this->print_ratio = 2.5; } // spec: Pr= 1:2 - 1:3 (>2.2 if X<0.50)
+ $code = str_replace(chr(194).chr(160), ' ', $code); // mPDF 5.3.95 (for utf-8 encoded)
+ $code = str_replace(chr(160), ' ', $code); // mPDF 5.3.95 (for win-1252)
+ if (strtoupper($type)=='C39') { $arrcode = $this->barcode_code39($code, false, false); }
+ if (strtoupper($type)=='C39+') { $arrcode = $this->barcode_code39($code, false, true); }
+ if (strtoupper($type)=='C39E') { $arrcode = $this->barcode_code39($code, true, false); }
+ if (strtoupper($type)=='C39E+') { $arrcode = $this->barcode_code39($code, true, true); }
+ if ($arrcode == false) { break; }
+ $arrcode['nom-X'] = 0.381; // Nominal value for X-dim (bar width) in mm (2 X min. spec.)
+ $arrcode['nom-H'] = 10; // Nominal value for Height of Full bar in mm (non-spec.)
+ $arrcode['lightmL'] = 10; // LEFT light margin = x X-dim (spec.)
+ $arrcode['lightmR'] = 10; // RIGHT light margin = x X-dim (spec.)
+ $arrcode['lightTB'] = 0; // TOP/BOTTOM light margin = x X-dim (non-spec.)
+ break;
+ }
+ case 'S25': // Standard 2 of 5
+ case 'S25+': { // Standard 2 of 5 + CHECKSUM
+ if ($pr > 0) { $this->print_ratio = $pr; }
+ else { $this->print_ratio = 3; } // spec: Pr=1:3/1:4.5
+ if (strtoupper($type)=='S25') { $arrcode = $this->barcode_s25($code, false); }
+ if (strtoupper($type)=='S25+') { $arrcode = $this->barcode_s25($code, true); }
+ if ($arrcode == false) { break; }
+ $arrcode['nom-X'] = 0.381; // Nominal value for X-dim (bar width) in mm (2 X min. spec.)
+ $arrcode['nom-H'] = 10; // Nominal value for Height of Full bar in mm (non-spec.)
+ $arrcode['lightmL'] = 10; // LEFT light margin = x X-dim (spec.)
+ $arrcode['lightmR'] = 10; // RIGHT light margin = x X-dim (spec.)
+ $arrcode['lightTB'] = 0; // TOP/BOTTOM light margin = x X-dim (non-spec.)
+ break;
+ }
+ case 'I25': // Interleaved 2 of 5
+ case 'I25+': { // Interleaved 2 of 5 + CHECKSUM
+ if ($pr > 0) { $this->print_ratio = $pr; }
+ else { $this->print_ratio = 2.5; } // spec: Pr= 1:2 - 1:3 (>2.2 if X<0.50)
+ if (strtoupper($type)=='I25') { $arrcode = $this->barcode_i25($code, false); }
+ if (strtoupper($type)=='I25+') { $arrcode = $this->barcode_i25($code, true); }
+ if ($arrcode == false) { break; }
+ $arrcode['nom-X'] = 0.381; // Nominal value for X-dim (bar width) in mm (2 X min. spec.)
+ $arrcode['nom-H'] = 10; // Nominal value for Height of Full bar in mm (non-spec.)
+ $arrcode['lightmL'] = 10; // LEFT light margin = x X-dim (spec.)
+ $arrcode['lightmR'] = 10; // RIGHT light margin = x X-dim (spec.)
+ $arrcode['lightTB'] = 0; // TOP/BOTTOM light margin = x X-dim (non-spec.)
+ break;
+ }
+ case 'I25B': // Interleaved 2 of 5 + Bearer bars
+ case 'I25B+': { // Interleaved 2 of 5 + CHECKSUM + Bearer bars
+ if ($pr > 0) { $this->print_ratio = $pr; }
+ else { $this->print_ratio = 2.5; } // spec: Pr= 1:2 - 1:3 (>2.2 if X<0.50)
+ if (strtoupper($type)=='I25B') { $arrcode = $this->barcode_i25($code, false); }
+ if (strtoupper($type)=='I25B+') { $arrcode = $this->barcode_i25($code, true); }
+ if ($arrcode == false) { break; }
+ $arrcode['nom-X'] = 0.381; // Nominal value for X-dim (bar width) in mm (2 X min. spec.)
+ $arrcode['nom-H'] = 10; // Nominal value for Height of Full bar in mm (non-spec.)
+ $arrcode['lightmL'] = 10; // LEFT light margin = x X-dim (spec.)
+ $arrcode['lightmR'] = 10; // RIGHT light margin = x X-dim (spec.)
+ $arrcode['lightTB'] = 2; // TOP/BOTTOM light margin = x X-dim (non-spec.) - used for bearer bars
+ break;
+ }
+ default: {
+ $this->barcode_array = false;
+ }
+ }
+ $this->barcode_array = $arrcode;
+ }
+
+ /**
+ * CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.
+ */
+ protected function barcode_code39($code, $extended=false, $checksum=false) {
+ $chr['0'] = '111221211';
+ $chr['1'] = '211211112';
+ $chr['2'] = '112211112';
+ $chr['3'] = '212211111';
+ $chr['4'] = '111221112';
+ $chr['5'] = '211221111';
+ $chr['6'] = '112221111';
+ $chr['7'] = '111211212';
+ $chr['8'] = '211211211';
+ $chr['9'] = '112211211';
+ $chr['A'] = '211112112';
+ $chr['B'] = '112112112';
+ $chr['C'] = '212112111';
+ $chr['D'] = '111122112';
+ $chr['E'] = '211122111';
+ $chr['F'] = '112122111';
+ $chr['G'] = '111112212';
+ $chr['H'] = '211112211';
+ $chr['I'] = '112112211';
+ $chr['J'] = '111122211';
+ $chr['K'] = '211111122';
+ $chr['L'] = '112111122';
+ $chr['M'] = '212111121';
+ $chr['N'] = '111121122';
+ $chr['O'] = '211121121';
+ $chr['P'] = '112121121';
+ $chr['Q'] = '111111222';
+ $chr['R'] = '211111221';
+ $chr['S'] = '112111221';
+ $chr['T'] = '111121221';
+ $chr['U'] = '221111112';
+ $chr['V'] = '122111112';
+ $chr['W'] = '222111111';
+ $chr['X'] = '121121112';
+ $chr['Y'] = '221121111';
+ $chr['Z'] = '122121111';
+ $chr['-'] = '121111212';
+ $chr['.'] = '221111211';
+ $chr[' '] = '122111211';
+ $chr['$'] = '121212111';
+ $chr['/'] = '121211121';
+ $chr['+'] = '121112121';
+ $chr['%'] = '111212121';
+ $chr['*'] = '121121211';
+
+ $code = strtoupper($code);
+ $checkdigit = '';
+ if ($extended) {
+ // extended mode
+ $code = $this->encode_code39_ext($code);
+ }
+ if ($code === false) {
+ return false;
+ }
+ if ($checksum) {
+ // checksum
+ $checkdigit = $this->checksum_code39($code);
+ $code .= $checkdigit ;
+ }
+ // add start and stop codes
+ $code = '*'.$code.'*';
+
+ $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
+ $k = 0;
+ $clen = strlen($code);
+ for ($i = 0; $i < $clen; ++$i) {
+ $char = $code[$i];
+ if(!isset($chr[$char])) {
+ // invalid character
+ return false;
+ }
+ for ($j = 0; $j < 9; ++$j) {
+ if (($j % 2) == 0) {
+ $t = true; // bar
+ } else {
+ $t = false; // space
+ }
+ $x = $chr[$char][$j];
+ if ($x == 2) { $w = $this->print_ratio; }
+ else { $w = 1; }
+
+ $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
+ $bararray['maxw'] += $w;
+ ++$k;
+ }
+ $bararray['bcode'][$k] = array('t' => false, 'w' => 1, 'h' => 1, 'p' => 0);
+ $bararray['maxw'] += 1;
+ ++$k;
+ }
+ $bararray['checkdigit'] = $checkdigit;
+ return $bararray;
+ }
+
+ /**
+ * Encode a string to be used for CODE 39 Extended mode.
+ */
+ protected function encode_code39_ext($code) {
+ $encode = array(
+ chr(0) => '%U', chr(1) => '$A', chr(2) => '$B', chr(3) => '$C',
+ chr(4) => '$D', chr(5) => '$E', chr(6) => '$F', chr(7) => '$G',
+ chr(8) => '$H', chr(9) => '$I', chr(10) => '$J', chr(11) => '£K',
+ chr(12) => '$L', chr(13) => '$M', chr(14) => '$N', chr(15) => '$O',
+ chr(16) => '$P', chr(17) => '$Q', chr(18) => '$R', chr(19) => '$S',
+ chr(20) => '$T', chr(21) => '$U', chr(22) => '$V', chr(23) => '$W',
+ chr(24) => '$X', chr(25) => '$Y', chr(26) => '$Z', chr(27) => '%A',
+ chr(28) => '%B', chr(29) => '%C', chr(30) => '%D', chr(31) => '%E',
+ chr(32) => ' ', chr(33) => '/A', chr(34) => '/B', chr(35) => '/C',
+ chr(36) => '/D', chr(37) => '/E', chr(38) => '/F', chr(39) => '/G',
+ chr(40) => '/H', chr(41) => '/I', chr(42) => '/J', chr(43) => '/K',
+ chr(44) => '/L', chr(45) => '-', chr(46) => '.', chr(47) => '/O',
+ chr(48) => '0', chr(49) => '1', chr(50) => '2', chr(51) => '3',
+ chr(52) => '4', chr(53) => '5', chr(54) => '6', chr(55) => '7',
+ chr(56) => '8', chr(57) => '9', chr(58) => '/Z', chr(59) => '%F',
+ chr(60) => '%G', chr(61) => '%H', chr(62) => '%I', chr(63) => '%J',
+ chr(64) => '%V', chr(65) => 'A', chr(66) => 'B', chr(67) => 'C',
+ chr(68) => 'D', chr(69) => 'E', chr(70) => 'F', chr(71) => 'G',
+ chr(72) => 'H', chr(73) => 'I', chr(74) => 'J', chr(75) => 'K',
+ chr(76) => 'L', chr(77) => 'M', chr(78) => 'N', chr(79) => 'O',
+ chr(80) => 'P', chr(81) => 'Q', chr(82) => 'R', chr(83) => 'S',
+ chr(84) => 'T', chr(85) => 'U', chr(86) => 'V', chr(87) => 'W',
+ chr(88) => 'X', chr(89) => 'Y', chr(90) => 'Z', chr(91) => '%K',
+ chr(92) => '%L', chr(93) => '%M', chr(94) => '%N', chr(95) => '%O',
+ chr(96) => '%W', chr(97) => '+A', chr(98) => '+B', chr(99) => '+C',
+ chr(100) => '+D', chr(101) => '+E', chr(102) => '+F', chr(103) => '+G',
+ chr(104) => '+H', chr(105) => '+I', chr(106) => '+J', chr(107) => '+K',
+ chr(108) => '+L', chr(109) => '+M', chr(110) => '+N', chr(111) => '+O',
+ chr(112) => '+P', chr(113) => '+Q', chr(114) => '+R', chr(115) => '+S',
+ chr(116) => '+T', chr(117) => '+U', chr(118) => '+V', chr(119) => '+W',
+ chr(120) => '+X', chr(121) => '+Y', chr(122) => '+Z', chr(123) => '%P',
+ chr(124) => '%Q', chr(125) => '%R', chr(126) => '%S', chr(127) => '%T');
+ $code_ext = '';
+ $clen = strlen($code);
+ for ($i = 0 ; $i < $clen; ++$i) {
+ if (ord($code[$i]) > 127) {
+ return false;
+ }
+ $code_ext .= $encode[$code[$i]];
+ }
+ return $code_ext;
+ }
+
+ /**
+ * Calculate CODE 39 checksum (modulo 43).
+ */
+ protected function checksum_code39($code) {
+ $chars = array(
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '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', '-', '.', ' ', '$', '/', '+', '%');
+ $sum = 0;
+ $clen = strlen($code);
+ for ($i = 0 ; $i < $clen; ++$i) {
+ $k = array_keys($chars, $code[$i]);
+ $sum += $k[0];
+ }
+ $j = ($sum % 43);
+ return $chars[$j];
+ }
+
+ /**
+ * CODE 93 - USS-93
+ * Compact code similar to Code 39
+ */
+ protected function barcode_code93($code) {
+ $chr[48] = '131112'; // 0
+ $chr[49] = '111213'; // 1
+ $chr[50] = '111312'; // 2
+ $chr[51] = '111411'; // 3
+ $chr[52] = '121113'; // 4
+ $chr[53] = '121212'; // 5
+ $chr[54] = '121311'; // 6
+ $chr[55] = '111114'; // 7
+ $chr[56] = '131211'; // 8
+ $chr[57] = '141111'; // 9
+ $chr[65] = '211113'; // A
+ $chr[66] = '211212'; // B
+ $chr[67] = '211311'; // C
+ $chr[68] = '221112'; // D
+ $chr[69] = '221211'; // E
+ $chr[70] = '231111'; // F
+ $chr[71] = '112113'; // G
+ $chr[72] = '112212'; // H
+ $chr[73] = '112311'; // I
+ $chr[74] = '122112'; // J
+ $chr[75] = '132111'; // K
+ $chr[76] = '111123'; // L
+ $chr[77] = '111222'; // M
+ $chr[78] = '111321'; // N
+ $chr[79] = '121122'; // O
+ $chr[80] = '131121'; // P
+ $chr[81] = '212112'; // Q
+ $chr[82] = '212211'; // R
+ $chr[83] = '211122'; // S
+ $chr[84] = '211221'; // T
+ $chr[85] = '221121'; // U
+ $chr[86] = '222111'; // V
+ $chr[87] = '112122'; // W
+ $chr[88] = '112221'; // X
+ $chr[89] = '122121'; // Y
+ $chr[90] = '123111'; // Z
+ $chr[45] = '121131'; // -
+ $chr[46] = '311112'; // .
+ $chr[32] = '311211'; //
+ $chr[36] = '321111'; // $
+ $chr[47] = '112131'; // /
+ $chr[43] = '113121'; // +
+ $chr[37] = '211131'; // %
+ $chr[128] = '121221'; // ($)
+ $chr[129] = '311121'; // (/)
+ $chr[130] = '122211'; // (+)
+ $chr[131] = '312111'; // (%)
+ $chr[42] = '111141'; // start-stop
+ $code = strtoupper($code);
+ $encode = array(
+ chr(0) => chr(131).'U', chr(1) => chr(128).'A', chr(2) => chr(128).'B', chr(3) => chr(128).'C',
+ chr(4) => chr(128).'D', chr(5) => chr(128).'E', chr(6) => chr(128).'F', chr(7) => chr(128).'G',
+ chr(8) => chr(128).'H', chr(9) => chr(128).'I', chr(10) => chr(128).'J', chr(11) => '£K',
+ chr(12) => chr(128).'L', chr(13) => chr(128).'M', chr(14) => chr(128).'N', chr(15) => chr(128).'O',
+ chr(16) => chr(128).'P', chr(17) => chr(128).'Q', chr(18) => chr(128).'R', chr(19) => chr(128).'S',
+ chr(20) => chr(128).'T', chr(21) => chr(128).'U', chr(22) => chr(128).'V', chr(23) => chr(128).'W',
+ chr(24) => chr(128).'X', chr(25) => chr(128).'Y', chr(26) => chr(128).'Z', chr(27) => chr(131).'A',
+ chr(28) => chr(131).'B', chr(29) => chr(131).'C', chr(30) => chr(131).'D', chr(31) => chr(131).'E',
+ chr(32) => ' ', chr(33) => chr(129).'A', chr(34) => chr(129).'B', chr(35) => chr(129).'C',
+ chr(36) => chr(129).'D', chr(37) => chr(129).'E', chr(38) => chr(129).'F', chr(39) => chr(129).'G',
+ chr(40) => chr(129).'H', chr(41) => chr(129).'I', chr(42) => chr(129).'J', chr(43) => chr(129).'K',
+ chr(44) => chr(129).'L', chr(45) => '-', chr(46) => '.', chr(47) => chr(129).'O',
+ chr(48) => '0', chr(49) => '1', chr(50) => '2', chr(51) => '3',
+ chr(52) => '4', chr(53) => '5', chr(54) => '6', chr(55) => '7',
+ chr(56) => '8', chr(57) => '9', chr(58) => chr(129).'Z', chr(59) => chr(131).'F',
+ chr(60) => chr(131).'G', chr(61) => chr(131).'H', chr(62) => chr(131).'I', chr(63) => chr(131).'J',
+ chr(64) => chr(131).'V', chr(65) => 'A', chr(66) => 'B', chr(67) => 'C',
+ chr(68) => 'D', chr(69) => 'E', chr(70) => 'F', chr(71) => 'G',
+ chr(72) => 'H', chr(73) => 'I', chr(74) => 'J', chr(75) => 'K',
+ chr(76) => 'L', chr(77) => 'M', chr(78) => 'N', chr(79) => 'O',
+ chr(80) => 'P', chr(81) => 'Q', chr(82) => 'R', chr(83) => 'S',
+ chr(84) => 'T', chr(85) => 'U', chr(86) => 'V', chr(87) => 'W',
+ chr(88) => 'X', chr(89) => 'Y', chr(90) => 'Z', chr(91) => chr(131).'K',
+ chr(92) => chr(131).'L', chr(93) => chr(131).'M', chr(94) => chr(131).'N', chr(95) => chr(131).'O',
+ chr(96) => chr(131).'W', chr(97) => chr(130).'A', chr(98) => chr(130).'B', chr(99) => chr(130).'C',
+ chr(100) => chr(130).'D', chr(101) => chr(130).'E', chr(102) => chr(130).'F', chr(103) => chr(130).'G',
+ chr(104) => chr(130).'H', chr(105) => chr(130).'I', chr(106) => chr(130).'J', chr(107) => chr(130).'K',
+ chr(108) => chr(130).'L', chr(109) => chr(130).'M', chr(110) => chr(130).'N', chr(111) => chr(130).'O',
+ chr(112) => chr(130).'P', chr(113) => chr(130).'Q', chr(114) => chr(130).'R', chr(115) => chr(130).'S',
+ chr(116) => chr(130).'T', chr(117) => chr(130).'U', chr(118) => chr(130).'V', chr(119) => chr(130).'W',
+ chr(120) => chr(130).'X', chr(121) => chr(130).'Y', chr(122) => chr(130).'Z', chr(123) => chr(131).'P',
+ chr(124) => chr(131).'Q', chr(125) => chr(131).'R', chr(126) => chr(131).'S', chr(127) => chr(131).'T');
+ $code_ext = '';
+ $clen = strlen($code);
+ for ($i = 0 ; $i < $clen; ++$i) {
+ if (ord($code{$i}) > 127) {
+ return false;
+ }
+ $code_ext .= $encode[$code{$i}];
+ }
+ // checksum
+ $code_ext .= $this->checksum_code93($code_ext);
+ // add start and stop codes
+ $code = '*'.$code_ext.'*';
+ $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
+ $k = 0;
+ $clen = strlen($code);
+ for ($i = 0; $i < $clen; ++$i) {
+ $char = ord($code{$i});
+ if(!isset($chr[$char])) {
+ // invalid character
+ return false;
+ }
+ for ($j = 0; $j < 6; ++$j) {
+ if (($j % 2) == 0) {
+ $t = true; // bar
+ } else {
+ $t = false; // space
+ }
+ $w = $chr[$char]{$j};
+ $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
+ $bararray['maxw'] += $w;
+ ++$k;
+ }
+ }
+ $bararray['bcode'][$k] = array('t' => true, 'w' => 1, 'h' => 1, 'p' => 0);
+ $bararray['maxw'] += 1;
+ ++$k;
+ return $bararray;
+ }
+
+ /**
+ * Calculate CODE 93 checksum (modulo 47).
+ */
+ protected function checksum_code93($code) {
+ $chars = array(
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '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', '-', '.', ' ', '$', '/', '+', '%',
+ '<', '=', '>', '?');
+ // translate special characters
+ $code = strtr($code, chr(128).chr(131).chr(129).chr(130), '<=>?');
+ $len = strlen($code);
+ // calculate check digit C
+ $p = 1;
+ $check = 0;
+ for ($i = ($len - 1); $i >= 0; --$i) {
+ $k = array_keys($chars, $code{$i});
+ $check += ($k[0] * $p);
+ ++$p;
+ if ($p > 20) {
+ $p = 1;
+ }
+ }
+ $check %= 47;
+ $c = $chars[$check];
+ $code .= $c;
+ // calculate check digit K
+ $p = 1;
+ $check = 0;
+ for ($i = $len; $i >= 0; --$i) {
+ $k = array_keys($chars, $code{$i});
+ $check += ($k[0] * $p);
+ ++$p;
+ if ($p > 15) {
+ $p = 1;
+ }
+ }
+ $check %= 47;
+ $k = $chars[$check];
+ $checksum = $c.$k;
+ // resto respecial characters
+ $checksum = strtr($checksum, '<=>?', chr(128).chr(131).chr(129).chr(130));
+ return $checksum;
+ }
+
+ /**
+ * Checksum for standard 2 of 5 barcodes.
+ */
+ protected function checksum_s25($code) {
+ $len = strlen($code);
+ $sum = 0;
+ for ($i = 0; $i < $len; $i+=2) {
+ $sum += $code[$i];
+ }
+ $sum *= 3;
+ for ($i = 1; $i < $len; $i+=2) {
+ $sum += ($code[$i]);
+ }
+ $r = $sum % 10;
+ if($r > 0) {
+ $r = (10 - $r);
+ }
+ return $r;
+ }
+
+ /**
+ * MSI.
+ * Variation of Plessey code, with similar applications
+ * Contains digits (0 to 9) and encodes the data only in the width of bars.
+ */
+ protected function barcode_msi($code, $checksum=false) {
+ $chr['0'] = '100100100100';
+ $chr['1'] = '100100100110';
+ $chr['2'] = '100100110100';
+ $chr['3'] = '100100110110';
+ $chr['4'] = '100110100100';
+ $chr['5'] = '100110100110';
+ $chr['6'] = '100110110100';
+ $chr['7'] = '100110110110';
+ $chr['8'] = '110100100100';
+ $chr['9'] = '110100100110';
+ $chr['A'] = '110100110100';
+ $chr['B'] = '110100110110';
+ $chr['C'] = '110110100100';
+ $chr['D'] = '110110100110';
+ $chr['E'] = '110110110100';
+ $chr['F'] = '110110110110';
+ $checkdigit = '';
+ if ($checksum) {
+ // add checksum
+ $clen = strlen($code);
+ $p = 2;
+ $check = 0;
+ for ($i = ($clen - 1); $i >= 0; --$i) {
+ $check += (hexdec($code[$i]) * $p);
+ ++$p;
+ if ($p > 7) {
+ $p = 2;
+ }
+ }
+ $check %= 11;
+ if ($check > 0) {
+ $check = 11 - $check;
+ }
+ $code .= $check;
+ $checkdigit = $check;
+ }
+ $seq = '110'; // left guard
+ $clen = strlen($code);
+ for ($i = 0; $i < $clen; ++$i) {
+ $digit = $code[$i];
+ if (!isset($chr[$digit])) {
+ // invalid character
+ return false;
+ }
+ $seq .= $chr[$digit];
+ }
+ $seq .= '1001'; // right guard
+ $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
+ $bararray['checkdigit'] = $checkdigit;
+ return $this->binseq_to_array($seq, $bararray);
+ }
+
+ /**
+ * Standard 2 of 5 barcodes.
+ * Used in airline ticket marking, photofinishing
+ * Contains digits (0 to 9) and encodes the data only in the width of bars.
+ */
+ protected function barcode_s25($code, $checksum=false) {
+ $chr['0'] = '10101110111010';
+ $chr['1'] = '11101010101110';
+ $chr['2'] = '10111010101110';
+ $chr['3'] = '11101110101010';
+ $chr['4'] = '10101110101110';
+ $chr['5'] = '11101011101010';
+ $chr['6'] = '10111011101010';
+ $chr['7'] = '10101011101110';
+ $chr['8'] = '10101110111010';
+ $chr['9'] = '10111010111010';
+ $checkdigit = '';
+ if ($checksum) {
+ // add checksum
+ $checkdigit = $this->checksum_s25($code);
+ $code .= $checkdigit ;
+ }
+ if((strlen($code) % 2) != 0) {
+ // add leading zero if code-length is odd
+ $code = '0'.$code;
+ }
+ $seq = '11011010';
+ $clen = strlen($code);
+ for ($i = 0; $i < $clen; ++$i) {
+ $digit = $code[$i];
+ if (!isset($chr[$digit])) {
+ // invalid character
+ return false;
+ }
+ $seq .= $chr[$digit];
+ }
+ $seq .= '1101011';
+ $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
+ $bararray['checkdigit'] = $checkdigit;
+ return $this->binseq_to_array($seq, $bararray);
+ }
+
+ /**
+ * Convert binary barcode sequence to barcode array
+ */
+ protected function binseq_to_array($seq, $bararray) {
+ $len = strlen($seq);
+ $w = 0;
+ $k = 0;
+ for ($i = 0; $i < $len; ++$i) {
+ $w += 1;
+ if (($i == ($len - 1)) OR (($i < ($len - 1)) AND ($seq[$i] != $seq[($i+1)]))) {
+ if ($seq[$i] == '1') {
+ $t = true; // bar
+ } else {
+ $t = false; // space
+ }
+ $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
+ $bararray['maxw'] += $w;
+ ++$k;
+ $w = 0;
+ }
+ }
+ return $bararray;
+ }
+
+ /**
+ * Interleaved 2 of 5 barcodes.
+ * Compact numeric code, widely used in industry, air cargo
+ * Contains digits (0 to 9) and encodes the data in the width of both bars and spaces.
+ */
+ protected function barcode_i25($code, $checksum=false) {
+ $chr['0'] = '11221';
+ $chr['1'] = '21112';
+ $chr['2'] = '12112';
+ $chr['3'] = '22111';
+ $chr['4'] = '11212';
+ $chr['5'] = '21211';
+ $chr['6'] = '12211';
+ $chr['7'] = '11122';
+ $chr['8'] = '21121';
+ $chr['9'] = '12121';
+ $chr['A'] = '11';
+ $chr['Z'] = '21';
+ $checkdigit = '';
+ if ($checksum) {
+ // add checksum
+ $checkdigit = $this->checksum_s25($code);
+ $code .= $checkdigit ;
+ }
+ if((strlen($code) % 2) != 0) {
+ // add leading zero if code-length is odd
+ $code = '0'.$code;
+ }
+ // add start and stop codes
+ $code = 'AA'.strtolower($code).'ZA';
+
+ $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
+ $k = 0;
+ $clen = strlen($code);
+ for ($i = 0; $i < $clen; $i = ($i + 2)) {
+ $char_bar = $code[$i];
+ $char_space = $code[$i+1];
+ if((!isset($chr[$char_bar])) OR (!isset($chr[$char_space]))) {
+ // invalid character
+ return false;
+ }
+ // create a bar-space sequence
+ $seq = '';
+ $chrlen = strlen($chr[$char_bar]);
+ for ($s = 0; $s < $chrlen; $s++){
+ $seq .= $chr[$char_bar][$s] . $chr[$char_space][$s];
+ }
+ $seqlen = strlen($seq);
+ for ($j = 0; $j < $seqlen; ++$j) {
+ if (($j % 2) == 0) {
+ $t = true; // bar
+ } else {
+ $t = false; // space
+ }
+ $x = $seq[$j];
+ if ($x == 2) { $w = $this->print_ratio; }
+ else { $w = 1; }
+
+ $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
+ $bararray['maxw'] += $w;
+ ++$k;
+ }
+ }
+ $bararray['checkdigit'] = $checkdigit;
+ return $bararray;
+ }
+
+ /**
+ * C128 barcodes.
+ * Very capable code, excellent density, high reliability; in very wide use world-wide
+ */
+ protected function barcode_c128($code, $type='B', $ean=false) {
+ $code = strcode2utf($code); // mPDF 5.7.1 Allows e.g.
+ $chr = array(
+ '212222', /* 00 */
+ '222122', /* 01 */
+ '222221', /* 02 */
+ '121223', /* 03 */
+ '121322', /* 04 */
+ '131222', /* 05 */
+ '122213', /* 06 */
+ '122312', /* 07 */
+ '132212', /* 08 */
+ '221213', /* 09 */
+ '221312', /* 10 */
+ '231212', /* 11 */
+ '112232', /* 12 */
+ '122132', /* 13 */
+ '122231', /* 14 */
+ '113222', /* 15 */
+ '123122', /* 16 */
+ '123221', /* 17 */
+ '223211', /* 18 */
+ '221132', /* 19 */
+ '221231', /* 20 */
+ '213212', /* 21 */
+ '223112', /* 22 */
+ '312131', /* 23 */
+ '311222', /* 24 */
+ '321122', /* 25 */
+ '321221', /* 26 */
+ '312212', /* 27 */
+ '322112', /* 28 */
+ '322211', /* 29 */
+ '212123', /* 30 */
+ '212321', /* 31 */
+ '232121', /* 32 */
+ '111323', /* 33 */
+ '131123', /* 34 */
+ '131321', /* 35 */
+ '112313', /* 36 */
+ '132113', /* 37 */
+ '132311', /* 38 */
+ '211313', /* 39 */
+ '231113', /* 40 */
+ '231311', /* 41 */
+ '112133', /* 42 */
+ '112331', /* 43 */
+ '132131', /* 44 */
+ '113123', /* 45 */
+ '113321', /* 46 */
+ '133121', /* 47 */
+ '313121', /* 48 */
+ '211331', /* 49 */
+ '231131', /* 50 */
+ '213113', /* 51 */
+ '213311', /* 52 */
+ '213131', /* 53 */
+ '311123', /* 54 */
+ '311321', /* 55 */
+ '331121', /* 56 */
+ '312113', /* 57 */
+ '312311', /* 58 */
+ '332111', /* 59 */
+ '314111', /* 60 */
+ '221411', /* 61 */
+ '431111', /* 62 */
+ '111224', /* 63 */
+ '111422', /* 64 */
+ '121124', /* 65 */
+ '121421', /* 66 */
+ '141122', /* 67 */
+ '141221', /* 68 */
+ '112214', /* 69 */
+ '112412', /* 70 */
+ '122114', /* 71 */
+ '122411', /* 72 */
+ '142112', /* 73 */
+ '142211', /* 74 */
+ '241211', /* 75 */
+ '221114', /* 76 */
+ '413111', /* 77 */
+ '241112', /* 78 */
+ '134111', /* 79 */
+ '111242', /* 80 */
+ '121142', /* 81 */
+ '121241', /* 82 */
+ '114212', /* 83 */
+ '124112', /* 84 */
+ '124211', /* 85 */
+ '411212', /* 86 */
+ '421112', /* 87 */
+ '421211', /* 88 */
+ '212141', /* 89 */
+ '214121', /* 90 */
+ '412121', /* 91 */
+ '111143', /* 92 */
+ '111341', /* 93 */
+ '131141', /* 94 */
+ '114113', /* 95 */
+ '114311', /* 96 */
+ '411113', /* 97 */
+ '411311', /* 98 */
+ '113141', /* 99 */
+ '114131', /* 100 */
+ '311141', /* 101 */
+ '411131', /* 102 */
+ '211412', /* 103 START A */
+ '211214', /* 104 START B */
+ '211232', /* 105 START C */
+ '233111', /* STOP */
+ '200000' /* END */
+ );
+ $keys = '';
+ switch(strtoupper($type)) {
+ case 'A': {
+ $startid = 103;
+ $keys = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_';
+ for ($i = 0; $i < 32; ++$i) {
+ $keys .= chr($i);
+ }
+ break;
+ }
+ case 'B': {
+ $startid = 104;
+ $keys = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'.chr(127);
+ break;
+ }
+ case 'C': {
+ $startid = 105;
+ $keys = '';
+ if ((strlen($code) % 2) != 0) {
+ // The length of barcode value must be even ($code). You must pad the number with zeros
+ return false;
+ }
+ for ($i = 0; $i <= 99; ++$i) {
+ $keys .= chr($i);
+ }
+ $new_code = '';
+ $hclen = (strlen($code) / 2);
+ for ($i = 0; $i < $hclen; ++$i) {
+ $new_code .= chr(intval($code{(2 * $i)}.$code{(2 * $i + 1)}));
+ }
+ $code = $new_code;
+ break;
+ }
+ default: {
+ return false;
+ }
+ }
+
+ // calculate check character
+ $sum = $startid;
+ if ($ean) { $code = chr(102) . $code; } // Add FNC 1 - which identifies it as EAN-128
+ $clen = strlen($code);
+ for ($i = 0; $i < $clen; ++$i) {
+ if ($ean && $i==0) { $sum += 102; }
+ else { $sum += (strpos($keys, $code[$i]) * ($i+1)); }
+ }
+ $check = ($sum % 103);
+ $checkdigit = $check ;
+ // add start, check and stop codes
+ $code = chr($startid).$code.chr($check).chr(106).chr(107);
+ $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
+ $k = 0;
+ $len = strlen($code);
+ for ($i = 0; $i < $len; ++$i) {
+ $ck = strpos($keys, $code[$i]);
+ if (($i == 0) || ($ean && $i==1) | ($i > ($len-4))) {
+ $char_num = ord($code[$i]);
+ $seq = $chr[$char_num];
+ } elseif(($ck >= 0) AND isset($chr[$ck])) {
+ $seq = $chr[$ck];
+ } else {
+ // invalid character
+ return false;
+ }
+ for ($j = 0; $j < 6; ++$j) {
+ if (($j % 2) == 0) {
+ $t = true; // bar
+ } else {
+ $t = false; // space
+ }
+ $w = $seq[$j];
+ $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
+ $bararray['maxw'] += $w;
+ ++$k;
+ }
+ }
+ $bararray['checkdigit'] = $checkdigit;
+ return $bararray;
+ }
+
+ /**
+ * EAN13 and UPC-A barcodes.
+ * EAN13: European Article Numbering international retail product code
+ * UPC-A: Universal product code seen on almost all retail products in the USA and Canada
+ * UPC-E: Short version of UPC symbol
+ */
+ protected function barcode_eanupc($code, $len=13) {
+ $upce = false;
+ $checkdigit = false;
+ if ($len == 6) {
+ $len = 12; // UPC-A
+ $upce = true; // UPC-E mode
+ }
+ $data_len = $len - 1;
+ //Padding
+ $code = str_pad($code, $data_len, '0', STR_PAD_LEFT);
+ $code_len = strlen($code);
+ // calculate check digit
+ $sum_a = 0;
+ for ($i = 1; $i < $data_len; $i+=2) {
+ $sum_a += $code[$i];
+ }
+ if ($len > 12) {
+ $sum_a *= 3;
+ }
+ $sum_b = 0;
+ for ($i = 0; $i < $data_len; $i+=2) {
+ $sum_b += ($code[$i]);
+ }
+ if ($len < 13) {
+ $sum_b *= 3;
+ }
+ $r = ($sum_a + $sum_b) % 10;
+ if($r > 0) {
+ $r = (10 - $r);
+ }
+ if ($code_len == $data_len) {
+ // add check digit
+ $code .= $r;
+ $checkdigit = $r;
+ } elseif ($r !== intval($code[$data_len])) {
+ // wrong checkdigit
+ return false;
+ }
+ if ($len == 12) {
+ // UPC-A
+ $code = '0'.$code;
+ ++$len;
+ }
+ if ($upce) {
+ // convert UPC-A to UPC-E
+ $tmp = substr($code, 4, 3);
+ $prod_code = intval(substr($code,7,5)); // product code
+ $invalid_upce = false;
+ if (($tmp == '000') OR ($tmp == '100') OR ($tmp == '200')) {
+ // manufacturer code ends in 000, 100, or 200
+ $upce_code = substr($code, 2, 2).substr($code, 9, 3).substr($code, 4, 1);
+ if ($prod_code > 999) { $invalid_upce = true; }
+ } else {
+ $tmp = substr($code, 5, 2);
+ if ($tmp == '00') {
+ // manufacturer code ends in 00
+ $upce_code = substr($code, 2, 3).substr($code, 10, 2).'3';
+ if ($prod_code > 99) { $invalid_upce = true; }
+ } else {
+ $tmp = substr($code, 6, 1);
+ if ($tmp == '0') {
+ // manufacturer code ends in 0
+ $upce_code = substr($code, 2, 4).substr($code, 11, 1).'4';
+ if ($prod_code > 9) { $invalid_upce = true; }
+ } else {
+ // manufacturer code does not end in zero
+ $upce_code = substr($code, 2, 5).substr($code, 11, 1);
+ if ($prod_code > 9) { $invalid_upce = true; }
+ }
+ }
+ }
+ if ($invalid_upce) { die("Error - UPC-A cannot produce a valid UPC-E barcode"); } // Error generating a UPCE code
+ }
+ //Convert digits to bars
+ $codes = array(
+ 'A'=>array( // left odd parity
+ '0'=>'0001101',
+ '1'=>'0011001',
+ '2'=>'0010011',
+ '3'=>'0111101',
+ '4'=>'0100011',
+ '5'=>'0110001',
+ '6'=>'0101111',
+ '7'=>'0111011',
+ '8'=>'0110111',
+ '9'=>'0001011'),
+ 'B'=>array( // left even parity
+ '0'=>'0100111',
+ '1'=>'0110011',
+ '2'=>'0011011',
+ '3'=>'0100001',
+ '4'=>'0011101',
+ '5'=>'0111001',
+ '6'=>'0000101',
+ '7'=>'0010001',
+ '8'=>'0001001',
+ '9'=>'0010111'),
+ 'C'=>array( // right
+ '0'=>'1110010',
+ '1'=>'1100110',
+ '2'=>'1101100',
+ '3'=>'1000010',
+ '4'=>'1011100',
+ '5'=>'1001110',
+ '6'=>'1010000',
+ '7'=>'1000100',
+ '8'=>'1001000',
+ '9'=>'1110100')
+ );
+ $parities = array(
+ '0'=>array('A','A','A','A','A','A'),
+ '1'=>array('A','A','B','A','B','B'),
+ '2'=>array('A','A','B','B','A','B'),
+ '3'=>array('A','A','B','B','B','A'),
+ '4'=>array('A','B','A','A','B','B'),
+ '5'=>array('A','B','B','A','A','B'),
+ '6'=>array('A','B','B','B','A','A'),
+ '7'=>array('A','B','A','B','A','B'),
+ '8'=>array('A','B','A','B','B','A'),
+ '9'=>array('A','B','B','A','B','A')
+ );
+ $upce_parities = array();
+ $upce_parities[0] = array(
+ '0'=>array('B','B','B','A','A','A'),
+ '1'=>array('B','B','A','B','A','A'),
+ '2'=>array('B','B','A','A','B','A'),
+ '3'=>array('B','B','A','A','A','B'),
+ '4'=>array('B','A','B','B','A','A'),
+ '5'=>array('B','A','A','B','B','A'),
+ '6'=>array('B','A','A','A','B','B'),
+ '7'=>array('B','A','B','A','B','A'),
+ '8'=>array('B','A','B','A','A','B'),
+ '9'=>array('B','A','A','B','A','B')
+ );
+ $upce_parities[1] = array(
+ '0'=>array('A','A','A','B','B','B'),
+ '1'=>array('A','A','B','A','B','B'),
+ '2'=>array('A','A','B','B','A','B'),
+ '3'=>array('A','A','B','B','B','A'),
+ '4'=>array('A','B','A','A','B','B'),
+ '5'=>array('A','B','B','A','A','B'),
+ '6'=>array('A','B','B','B','A','A'),
+ '7'=>array('A','B','A','B','A','B'),
+ '8'=>array('A','B','A','B','B','A'),
+ '9'=>array('A','B','B','A','B','A')
+ );
+ $k = 0;
+ $seq = '101'; // left guard bar
+ if ($upce) {
+ $bararray = array('code' => $upce_code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
+ $p = $upce_parities[$code{1}][$r];
+ for ($i = 0; $i < 6; ++$i) {
+ $seq .= $codes[$p[$i]][$upce_code[$i]];
+ }
+ $seq .= '010101'; // right guard bar
+ } else {
+ $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
+ $half_len = ceil($len / 2);
+ if ($len == 8) {
+ for ($i = 0; $i < $half_len; ++$i) {
+ $seq .= $codes['A'][$code[$i]];
+ }
+ } else {
+ $p = $parities[$code{0}];
+ for ($i = 1; $i < $half_len; ++$i) {
+ $seq .= $codes[$p[$i-1]][$code[$i]];
+ }
+ }
+ $seq .= '01010'; // center guard bar
+ for ($i = $half_len; $i < $len; ++$i) {
+ $seq .= $codes['C'][$code[$i]];
+ }
+ $seq .= '101'; // right guard bar
+ }
+ $clen = strlen($seq);
+ $w = 0;
+ for ($i = 0; $i < $clen; ++$i) {
+ $w += 1;
+ if (($i == ($clen - 1)) OR (($i < ($clen - 1)) AND ($seq[$i] != $seq[($i+1)]))) {
+ if ($seq[$i] == '1') {
+ $t = true; // bar
+ } else {
+ $t = false; // space
+ }
+ $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
+ $bararray['maxw'] += $w;
+ ++$k;
+ $w = 0;
+ }
+ }
+ $bararray['checkdigit'] = $checkdigit;
+ return $bararray;
+ }
+
+ /**
+ * UPC-Based Extentions
+ * 2-Digit Ext.: Used to indicate magazines and newspaper issue numbers
+ * 5-Digit Ext.: Used to mark suggested retail price of books
+ */
+ protected function barcode_eanext($code, $len=5) {
+ //Padding
+ $code = str_pad($code, $len, '0', STR_PAD_LEFT);
+ // calculate check digit
+ if ($len == 2) {
+ $r = $code % 4;
+ } elseif ($len == 5) {
+ $r = (3 * ($code{0} + $code{2} + $code{4})) + (9 * ($code{1} + $code{3}));
+ $r %= 10;
+ } else {
+ return false;
+ }
+ //Convert digits to bars
+ $codes = array(
+ 'A'=>array( // left odd parity
+ '0'=>'0001101',
+ '1'=>'0011001',
+ '2'=>'0010011',
+ '3'=>'0111101',
+ '4'=>'0100011',
+ '5'=>'0110001',
+ '6'=>'0101111',
+ '7'=>'0111011',
+ '8'=>'0110111',
+ '9'=>'0001011'),
+ 'B'=>array( // left even parity
+ '0'=>'0100111',
+ '1'=>'0110011',
+ '2'=>'0011011',
+ '3'=>'0100001',
+ '4'=>'0011101',
+ '5'=>'0111001',
+ '6'=>'0000101',
+ '7'=>'0010001',
+ '8'=>'0001001',
+ '9'=>'0010111')
+ );
+ $parities = array();
+ $parities[2] = array(
+ '0'=>array('A','A'),
+ '1'=>array('A','B'),
+ '2'=>array('B','A'),
+ '3'=>array('B','B')
+ );
+ $parities[5] = array(
+ '0'=>array('B','B','A','A','A'),
+ '1'=>array('B','A','B','A','A'),
+ '2'=>array('B','A','A','B','A'),
+ '3'=>array('B','A','A','A','B'),
+ '4'=>array('A','B','B','A','A'),
+ '5'=>array('A','A','B','B','A'),
+ '6'=>array('A','A','A','B','B'),
+ '7'=>array('A','B','A','B','A'),
+ '8'=>array('A','B','A','A','B'),
+ '9'=>array('A','A','B','A','B')
+ );
+ $p = $parities[$len][$r];
+ $seq = '1011'; // left guard bar
+ $seq .= $codes[$p[0]][$code{0}];
+ for ($i = 1; $i < $len; ++$i) {
+ $seq .= '01'; // separator
+ $seq .= $codes[$p[$i]][$code[$i]];
+ }
+ $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
+ return $this->binseq_to_array($seq, $bararray);
+ }
+
+ /**
+ * POSTNET and PLANET barcodes.
+ * Used by U.S. Postal Service for automated mail sorting
+ */
+ protected function barcode_postnet($code, $planet=false) {
+ // bar lenght
+ if ($planet) {
+ $barlen = Array(
+ 0 => Array(1,1,2,2,2),
+ 1 => Array(2,2,2,1,1),
+ 2 => Array(2,2,1,2,1),
+ 3 => Array(2,2,1,1,2),
+ 4 => Array(2,1,2,2,1),
+ 5 => Array(2,1,2,1,2),
+ 6 => Array(2,1,1,2,2),
+ 7 => Array(1,2,2,2,1),
+ 8 => Array(1,2,2,1,2),
+ 9 => Array(1,2,1,2,2)
+ );
+ } else {
+ $barlen = Array(
+ 0 => Array(2,2,1,1,1),
+ 1 => Array(1,1,1,2,2),
+ 2 => Array(1,1,2,1,2),
+ 3 => Array(1,1,2,2,1),
+ 4 => Array(1,2,1,1,2),
+ 5 => Array(1,2,1,2,1),
+ 6 => Array(1,2,2,1,1),
+ 7 => Array(2,1,1,1,2),
+ 8 => Array(2,1,1,2,1),
+ 9 => Array(2,1,2,1,1)
+ );
+ }
+ $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 5, 'bcode' => array());
+ $k = 0;
+ $code = str_replace('-', '', $code);
+ $code = str_replace(' ', '', $code);
+ $len = strlen($code);
+ // calculate checksum
+ $sum = 0;
+ for ($i = 0; $i < $len; ++$i) {
+ $sum += intval($code[$i]);
+ }
+ $chkd = ($sum % 10);
+ if($chkd > 0) {
+ $chkd = (10 - $chkd);
+ }
+ $code .= $chkd;
+ $checkdigit = $chkd;
+ $len = strlen($code);
+ // start bar
+ $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 5, 'p' => 0);
+ $bararray['bcode'][$k++] = array('t' => 0, 'w' => $this->gapwidth , 'h' => 5, 'p' => 0);
+ $bararray['maxw'] += (1 + $this->gapwidth );
+ for ($i = 0; $i < $len; ++$i) {
+ for ($j = 0; $j < 5; ++$j) {
+ $bh = $barlen[$code[$i]][$j];
+ if ($bh == 2) {
+ $h = 5;
+ $p = 0;
+ }
+ else {
+ $h = 2;
+ $p = 3;
+ }
+ $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p);
+ $bararray['bcode'][$k++] = array('t' => 0, 'w' => $this->gapwidth , 'h' => 2, 'p' => 0);
+ $bararray['maxw'] += (1 + $this->gapwidth );
+ }
+ }
+ // end bar
+ $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 5, 'p' => 0);
+ $bararray['maxw'] += 1;
+ $bararray['checkdigit'] = $checkdigit;
+ return $bararray;
+ }
+
+ /**
+ * RM4SCC - CBC - KIX
+ * RM4SCC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code) - KIX (Klant index - Customer index)
+ * RM4SCC is the name of the barcode symbology used by the Royal Mail for its Cleanmail service.
+ */
+ protected function barcode_rm4scc($code, $kix=false) {
+ $notkix = !$kix;
+ // bar mode
+ // 1 = pos 1, length 2
+ // 2 = pos 1, length 3
+ // 3 = pos 2, length 1
+ // 4 = pos 2, length 2
+ $barmode = array(
+ '0' => array(3,3,2,2),
+ '1' => array(3,4,1,2),
+ '2' => array(3,4,2,1),
+ '3' => array(4,3,1,2),
+ '4' => array(4,3,2,1),
+ '5' => array(4,4,1,1),
+ '6' => array(3,1,4,2),
+ '7' => array(3,2,3,2),
+ '8' => array(3,2,4,1),
+ '9' => array(4,1,3,2),
+ 'A' => array(4,1,4,1),
+ 'B' => array(4,2,3,1),
+ 'C' => array(3,1,2,4),
+ 'D' => array(3,2,1,4),
+ 'E' => array(3,2,2,3),
+ 'F' => array(4,1,1,4),
+ 'G' => array(4,1,2,3),
+ 'H' => array(4,2,1,3),
+ 'I' => array(1,3,4,2),
+ 'J' => array(1,4,3,2),
+ 'K' => array(1,4,4,1),
+ 'L' => array(2,3,3,2),
+ 'M' => array(2,3,4,1),
+ 'N' => array(2,4,3,1),
+ 'O' => array(1,3,2,4),
+ 'P' => array(1,4,1,4),
+ 'Q' => array(1,4,2,3),
+ 'R' => array(2,3,1,4),
+ 'S' => array(2,3,2,3),
+ 'T' => array(2,4,1,3),
+ 'U' => array(1,1,4,4),
+ 'V' => array(1,2,3,4),
+ 'W' => array(1,2,4,3),
+ 'X' => array(2,1,3,4),
+ 'Y' => array(2,1,4,3),
+ 'Z' => array(2,2,3,3)
+ );
+ $code = strtoupper($code);
+ $len = strlen($code);
+ $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => $this->daft['F'], 'bcode' => array());
+ if ($notkix) {
+ // table for checksum calculation (row,col)
+ $checktable = array(
+ '0' => array(1,1),
+ '1' => array(1,2),
+ '2' => array(1,3),
+ '3' => array(1,4),
+ '4' => array(1,5),
+ '5' => array(1,0),
+ '6' => array(2,1),
+ '7' => array(2,2),
+ '8' => array(2,3),
+ '9' => array(2,4),
+ 'A' => array(2,5),
+ 'B' => array(2,0),
+ 'C' => array(3,1),
+ 'D' => array(3,2),
+ 'E' => array(3,3),
+ 'F' => array(3,4),
+ 'G' => array(3,5),
+ 'H' => array(3,0),
+ 'I' => array(4,1),
+ 'J' => array(4,2),
+ 'K' => array(4,3),
+ 'L' => array(4,4),
+ 'M' => array(4,5),
+ 'N' => array(4,0),
+ 'O' => array(5,1),
+ 'P' => array(5,2),
+ 'Q' => array(5,3),
+ 'R' => array(5,4),
+ 'S' => array(5,5),
+ 'T' => array(5,0),
+ 'U' => array(0,1),
+ 'V' => array(0,2),
+ 'W' => array(0,3),
+ 'X' => array(0,4),
+ 'Y' => array(0,5),
+ 'Z' => array(0,0)
+ );
+ $row = 0;
+ $col = 0;
+ for ($i = 0; $i < $len; ++$i) {
+ $row += $checktable[$code[$i]][0];
+ $col += $checktable[$code[$i]][1];
+ }
+ $row %= 6;
+ $col %= 6;
+ $chk = array_keys($checktable, array($row,$col));
+ $code .= $chk[0];
+ $bararray['checkdigit'] = $chk[0];
+ ++$len;
+ }
+ $k = 0;
+ if ($notkix) {
+ // start bar
+ $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $this->daft['A'] , 'p' => 0);
+ $bararray['bcode'][$k++] = array('t' => 0, 'w' => $this->gapwidth , 'h' => $this->daft['A'] , 'p' => 0);
+ $bararray['maxw'] += (1 + $this->gapwidth) ;
+ }
+ for ($i = 0; $i < $len; ++$i) {
+ for ($j = 0; $j < 4; ++$j) {
+ switch ($barmode[$code[$i]][$j]) {
+ case 1: {
+ // ascender (A)
+ $p = 0;
+ $h = $this->daft['A'];
+ break;
+ }
+ case 2: {
+ // full bar (F)
+ $p = 0;
+ $h = $this->daft['F'];
+ break;
+ }
+ case 3: {
+ // tracker (T)
+ $p = ($this->daft['F'] - $this->daft['T'])/2;
+ $h = $this->daft['T'];
+ break;
+ }
+ case 4: {
+ // descender (D)
+ $p = $this->daft['F'] - $this->daft['D'];
+ $h = $this->daft['D'];
+ break;
+ }
+ }
+
+ $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p);
+ $bararray['bcode'][$k++] = array('t' => 0, 'w' => $this->gapwidth, 'h' => 2, 'p' => 0);
+ $bararray['maxw'] += (1 + $this->gapwidth) ;
+ }
+ }
+ if ($notkix) {
+ // stop bar
+ $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $this->daft['F'], 'p' => 0);
+ $bararray['maxw'] += 1;
+ }
+ return $bararray;
+ }
+
+ /**
+ * CODABAR barcodes.
+ * Older code often used in library systems, sometimes in blood banks
+ */
+ protected function barcode_codabar($code) {
+ $chr = array(
+ '0' => '11111221',
+ '1' => '11112211',
+ '2' => '11121121',
+ '3' => '22111111',
+ '4' => '11211211',
+ '5' => '21111211',
+ '6' => '12111121',
+ '7' => '12112111',
+ '8' => '12211111',
+ '9' => '21121111',
+ '-' => '11122111',
+ '$' => '11221111',
+ ':' => '21112121',
+ '/' => '21211121',
+ '.' => '21212111',
+ '+' => '11222221',
+ 'A' => '11221211',
+ 'B' => '12121121',
+ 'C' => '11121221',
+ 'D' => '11122211'
+ );
+ $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
+ $k = 0;
+ $w = 0;
+ $seq = '';
+ $code = strtoupper($code);
+ $len = strlen($code);
+ for ($i = 0; $i < $len; ++$i) {
+ if (!isset($chr[$code[$i]])) {
+ return false;
+ }
+ $seq = $chr[$code[$i]];
+ for ($j = 0; $j < 8; ++$j) {
+ if (($j % 2) == 0) {
+ $t = true; // bar
+ } else {
+ $t = false; // space
+ }
+ $x = $seq[$j];
+ if ($x == 2) { $w = $this->print_ratio; }
+ else { $w = 1; }
+ $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
+ $bararray['maxw'] += $w;
+ ++$k;
+ }
+ }
+ return $bararray;
+ }
+
+ /**
+ * CODE11 barcodes.
+ * Used primarily for labeling telecommunications equipment
+ */
+ protected function barcode_code11($code) {
+ $chr = array(
+ '0' => '111121',
+ '1' => '211121',
+ '2' => '121121',
+ '3' => '221111',
+ '4' => '112121',
+ '5' => '212111',
+ '6' => '122111',
+ '7' => '111221',
+ '8' => '211211',
+ '9' => '211111',
+ '-' => '112111',
+ 'S' => '112211'
+ );
+
+ $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
+ $k = 0;
+ $w = 0;
+ $seq = '';
+ $len = strlen($code);
+ // calculate check digit C
+ $p = 1;
+ $check = 0;
+ for ($i = ($len - 1); $i >= 0; --$i) {
+ $digit = $code[$i];
+ if ($digit == '-') {
+ $dval = 10;
+ } else {
+ $dval = intval($digit);
+ }
+ $check += ($dval * $p);
+ ++$p;
+ if ($p > 10) {
+ $p = 1;
+ }
+ }
+ $check %= 11;
+ if ($check == 10) {
+ $check = '-';
+ }
+ $code .= $check;
+ $checkdigit = $check;
+ if ($len > 10) {
+ // calculate check digit K
+ $p = 1;
+ $check = 0;
+ for ($i = $len; $i >= 0; --$i) {
+ $digit = $code[$i];
+ if ($digit == '-') {
+ $dval = 10;
+ } else {
+ $dval = intval($digit);
+ }
+ $check += ($dval * $p);
+ ++$p;
+ if ($p > 9) {
+ $p = 1;
+ }
+ }
+ $check %= 11;
+ $code .= $check;
+ $checkdigit .= $check;
+ ++$len;
+ }
+ $code = 'S'.$code.'S';
+ $len += 3;
+ for ($i = 0; $i < $len; ++$i) {
+ if (!isset($chr[$code[$i]])) {
+ return false;
+ }
+ $seq = $chr[$code[$i]];
+ for ($j = 0; $j < 6; ++$j) {
+ if (($j % 2) == 0) {
+ $t = true; // bar
+ } else {
+ $t = false; // space
+ }
+ $x = $seq[$j];
+ if ($x == 2) { $w = $this->print_ratio; }
+ else { $w = 1; }
+ $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
+ $bararray['maxw'] += $w;
+ ++$k;
+ }
+ }
+ $bararray['checkdigit'] = $checkdigit;
+ return $bararray;
+ }
+
+
+ /**
+ * IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200
+ * (requires PHP bcmath extension)
+ * Intelligent Mail barcode is a 65-bar code for use on mail in the United States.
+ * The fields are described as follows:- The Barcode Identifier shall be assigned by USPS to encode the presort identification that is currently printed in human readable form on the optional endorsement line (OEL) as well as for future USPS use. This shall be two digits, with the second digit in the range of 0-4. The allowable encoding ranges shall be 00-04, 10-14, 20-24, 30-34, 40-44, 50-54, 60-64, 70-74, 80-84, and 90-94.
- The Service Type Identifier shall be assigned by USPS for any combination of services requested on the mailpiece. The allowable encoding range shall be 000-999. Each 3-digit value shall correspond to a particular mail class with a particular combination of service(s). Each service program, such as OneCode Confirm and OneCode ACS, shall provide the list of Service Type Identifier values.
- The Mailer or Customer Identifier shall be assigned by USPS as a unique, 6 or 9 digit number that identifies a business entity. The allowable encoding range for the 6 digit Mailer ID shall be 000000- 899999, while the allowable encoding range for the 9 digit Mailer ID shall be 900000000-999999999.
- The Serial or Sequence Number shall be assigned by the mailer for uniquely identifying and tracking mailpieces. The allowable encoding range shall be 000000000-999999999 when used with a 6 digit Mailer ID and 000000-999999 when used with a 9 digit Mailer ID. e. The Delivery Point ZIP Code shall be assigned by the mailer for routing the mailpiece. This shall replace POSTNET for routing the mailpiece to its final delivery point. The length may be 0, 5, 9, or 11 digits. The allowable encoding ranges shall be no ZIP Code, 00000-99999, 000000000-999999999, and 00000000000-99999999999.
+ */
+ protected function barcode_imb($code) {
+ $asc_chr = array(4,0,2,6,3,5,1,9,8,7,1,2,0,6,4,8,2,9,5,3,0,1,3,7,4,6,8,9,2,0,5,1,9,4,3,8,6,7,1,2,4,3,9,5,7,8,3,0,2,1,4,0,9,1,7,0,2,4,6,3,7,1,9,5,8);
+ $dsc_chr = array(7,1,9,5,8,0,2,4,6,3,5,8,9,7,3,0,6,1,7,4,6,8,9,2,5,1,7,5,4,3,8,7,6,0,2,5,4,9,3,0,1,6,8,2,0,4,5,9,6,7,5,2,6,3,8,5,1,9,8,7,4,0,2,6,3);
+ $asc_pos = array(3,0,8,11,1,12,8,11,10,6,4,12,2,7,9,6,7,9,2,8,4,0,12,7,10,9,0,7,10,5,7,9,6,8,2,12,1,4,2,0,1,5,4,6,12,1,0,9,4,7,5,10,2,6,9,11,2,12,6,7,5,11,0,3,2);
+ $dsc_pos = array(2,10,12,5,9,1,5,4,3,9,11,5,10,1,6,3,4,1,10,0,2,11,8,6,1,12,3,8,6,4,4,11,0,6,1,9,11,5,3,7,3,10,7,11,8,2,10,3,5,8,0,3,12,11,8,4,5,1,3,0,7,12,9,8,10);
+ $code_arr = explode('-', $code);
+ $tracking_number = $code_arr[0];
+ if (isset($code_arr[1])) {
+ $routing_code = $code_arr[1];
+ } else {
+ $routing_code = '';
+ }
+ // Conversion of Routing Code
+ switch (strlen($routing_code)) {
+ case 0: {
+ $binary_code = 0;
+ break;
+ }
+ case 5: {
+ $binary_code = bcadd($routing_code, '1');
+ break;
+ }
+ case 9: {
+ $binary_code = bcadd($routing_code, '100001');
+ break;
+ }
+ case 11: {
+ $binary_code = bcadd($routing_code, '1000100001');
+ break;
+ }
+ default: {
+ return false;
+ break;
+ }
+ }
+ $binary_code = bcmul($binary_code, 10);
+ $binary_code = bcadd($binary_code, $tracking_number{0});
+ $binary_code = bcmul($binary_code, 5);
+ $binary_code = bcadd($binary_code, $tracking_number{1});
+ $binary_code .= substr($tracking_number, 2, 18);
+ // convert to hexadecimal
+ $binary_code = $this->dec_to_hex($binary_code);
+ // pad to get 13 bytes
+ $binary_code = str_pad($binary_code, 26, '0', STR_PAD_LEFT);
+ // convert string to array of bytes
+ $binary_code_arr = chunk_split($binary_code, 2, "\r");
+ $binary_code_arr = substr($binary_code_arr, 0, -1);
+ $binary_code_arr = explode("\r", $binary_code_arr);
+ // calculate frame check sequence
+ $fcs = $this->imb_crc11fcs($binary_code_arr);
+ // exclude first 2 bits from first byte
+ $first_byte = sprintf('%2s', dechex((hexdec($binary_code_arr[0]) << 2) >> 2));
+ $binary_code_102bit = $first_byte.substr($binary_code, 2);
+ // convert binary data to codewords
+ $codewords = array();
+ $data = $this->hex_to_dec($binary_code_102bit);
+ $codewords[0] = bcmod($data, 636) * 2;
+ $data = bcdiv($data, 636);
+ for ($i = 1; $i < 9; ++$i) {
+ $codewords[$i] = bcmod($data, 1365);
+ $data = bcdiv($data, 1365);
+ }
+ $codewords[9] = $data;
+ if (($fcs >> 10) == 1) {
+ $codewords[9] += 659;
+ }
+ // generate lookup tables
+ $table2of13 = $this->imb_tables(2, 78);
+ $table5of13 = $this->imb_tables(5, 1287);
+ // convert codewords to characters
+ $characters = array();
+ $bitmask = 512;
+ foreach($codewords as $k => $val) {
+ if ($val <= 1286) {
+ $chrcode = $table5of13[$val];
+ } else {
+ $chrcode = $table2of13[($val - 1287)];
+ }
+ if (($fcs & $bitmask) > 0) {
+ // bitwise invert
+ $chrcode = ((~$chrcode) & 8191);
+ }
+ $characters[] = $chrcode;
+ $bitmask /= 2;
+ }
+ $characters = array_reverse($characters);
+ // build bars
+ $k = 0;
+ $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => $this->daft['F'], 'bcode' => array());
+ for ($i = 0; $i < 65; ++$i) {
+ $asc = (($characters[$asc_chr[$i]] & pow(2, $asc_pos[$i])) > 0);
+ $dsc = (($characters[$dsc_chr[$i]] & pow(2, $dsc_pos[$i])) > 0);
+ if ($asc AND $dsc) {
+ // full bar (F)
+ $p = 0;
+ $h = $this->daft['F'];
+ } elseif ($asc) {
+ // ascender (A)
+ $p = 0;
+ $h = $this->daft['A'];
+ } elseif ($dsc) {
+ // descender (D)
+ $p = $this->daft['F'] - $this->daft['D'];
+ $h = $this->daft['D'];
+ } else {
+ // tracker (T)
+ $p = ($this->daft['F'] - $this->daft['T'])/2;
+ $h = $this->daft['T'];
+ }
+ $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p);
+ // Gap
+ $bararray['bcode'][$k++] = array('t' => 0, 'w' => $this->gapwidth , 'h' => 1, 'p' => 0);
+ $bararray['maxw'] += (1 + $this->gapwidth );
+ }
+ unset($bararray['bcode'][($k - 1)]);
+ $bararray['maxw'] -= $this->gapwidth ;
+ return $bararray;
+ }
+
+ /**
+ * Convert large integer number to hexadecimal representation.
+ * (requires PHP bcmath extension)
+ */
+ public function dec_to_hex($number) {
+ $i = 0;
+ $hex = array();
+ if($number == 0) {
+ return '00';
+ }
+ while($number > 0) {
+ if($number == 0) {
+ array_push($hex, '0');
+ } else {
+ array_push($hex, strtoupper(dechex(bcmod($number, '16'))));
+ $number = bcdiv($number, '16', 0);
+ }
+ }
+ $hex = array_reverse($hex);
+ return implode($hex);
+ }
+
+ /**
+ * Convert large hexadecimal number to decimal representation (string).
+ * (requires PHP bcmath extension)
+ */
+ public function hex_to_dec($hex) {
+ $dec = 0;
+ $bitval = 1;
+ $len = strlen($hex);
+ for($pos = ($len - 1); $pos >= 0; --$pos) {
+ $dec = bcadd($dec, bcmul(hexdec($hex[$pos]), $bitval));
+ $bitval = bcmul($bitval, 16);
+ }
+ return $dec;
+ }
+
+ /**
+ * Intelligent Mail Barcode calculation of Frame Check Sequence
+ */
+ protected function imb_crc11fcs($code_arr) {
+ $genpoly = 0x0F35; // generator polynomial
+ $fcs = 0x07FF; // Frame Check Sequence
+ // do most significant byte skipping the 2 most significant bits
+ $data = hexdec($code_arr[0]) << 5;
+ for ($bit = 2; $bit < 8; ++$bit) {
+ if (($fcs ^ $data) & 0x400) {
+ $fcs = ($fcs << 1) ^ $genpoly;
+ } else {
+ $fcs = ($fcs << 1);
+ }
+ $fcs &= 0x7FF;
+ $data <<= 1;
+ }
+ // do rest of bytes
+ for ($byte = 1; $byte < 13; ++$byte) {
+ $data = hexdec($code_arr[$byte]) << 3;
+ for ($bit = 0; $bit < 8; ++$bit) {
+ if (($fcs ^ $data) & 0x400) {
+ $fcs = ($fcs << 1) ^ $genpoly;
+ } else {
+ $fcs = ($fcs << 1);
+ }
+ $fcs &= 0x7FF;
+ $data <<= 1;
+ }
+ }
+ return $fcs;
+ }
+
+ /**
+ * Reverse unsigned short value
+ */
+ protected function imb_reverse_us($num) {
+ $rev = 0;
+ for ($i = 0; $i < 16; ++$i) {
+ $rev <<= 1;
+ $rev |= ($num & 1);
+ $num >>= 1;
+ }
+ return $rev;
+ }
+
+ /**
+ * generate Nof13 tables used for Intelligent Mail Barcode
+ */
+ protected function imb_tables($n, $size) {
+ $table = array();
+ $lli = 0; // LUT lower index
+ $lui = $size - 1; // LUT upper index
+ for ($count = 0; $count < 8192; ++$count) {
+ $bit_count = 0;
+ for ($bit_index = 0; $bit_index < 13; ++$bit_index) {
+ $bit_count += intval(($count & (1 << $bit_index)) != 0);
+ }
+ // if we don't have the right number of bits on, go on to the next value
+ if ($bit_count == $n) {
+ $reverse = ($this->imb_reverse_us($count) >> 3);
+ // if the reverse is less than count, we have already visited this pair before
+ if ($reverse >= $count) {
+ // If count is symmetric, place it at the first free slot from the end of the list.
+ // Otherwise, place it at the first free slot from the beginning of the list AND place $reverse ath the next free slot from the beginning of the list
+ if ($reverse == $count) {
+ $table[$lui] = $count;
+ --$lui;
+ } else {
+ $table[$lli] = $count;
+ ++$lli;
+ $table[$lli] = $reverse;
+ ++$lli;
+ }
+ }
+ }
+ }
+ return $table;
+ }
+
+} // end of class
+
+//============================================================+
+// END OF FILE
+//============================================================+
+?>
\ No newline at end of file
diff --git a/mpdf/classes/bmp.php b/mpdf/classes/bmp.php
new file mode 100644
index 0000000..896ced8
--- /dev/null
+++ b/mpdf/classes/bmp.php
@@ -0,0 +1,248 @@
+mpdf = $mpdf;
+}
+
+
+function _getBMPimage($data, $file) {
+ $info = array();
+ // Adapted from script by Valentin Schmidt
+ // http://staff.dasdeck.de/valentin/fpdf/fpdf_bmp/
+ $bfOffBits=$this->_fourbytes2int_le(substr($data,10,4));
+ $width=$this->_fourbytes2int_le(substr($data,18,4));
+ $height=$this->_fourbytes2int_le(substr($data,22,4));
+ $flip = ($height<0);
+ if ($flip) $height =-$height;
+ $biBitCount=$this->_twobytes2int_le(substr($data,28,2));
+ $biCompression=$this->_fourbytes2int_le(substr($data,30,4));
+ $info = array('w'=>$width, 'h'=>$height);
+ if ($biBitCount<16){
+ $info['cs'] = 'Indexed';
+ $info['bpc'] = $biBitCount;
+ $palStr = substr($data,54,($bfOffBits-54));
+ $pal = '';
+ $cnt = strlen($palStr)/4;
+ for ($i=0;$i<$cnt;$i++){
+ $n = 4*$i;
+ $pal .= $palStr[$n+2].$palStr[$n+1].$palStr[$n];
+ }
+ $info['pal'] = $pal;
+ }
+ else{
+ $info['cs'] = 'DeviceRGB';
+ $info['bpc'] = 8;
+ }
+
+ if ($this->mpdf->restrictColorSpace==1 || $this->mpdf->PDFX || $this->mpdf->restrictColorSpace==3) {
+ if (($this->mpdf->PDFA && !$this->mpdf->PDFAauto) || ($this->mpdf->PDFX && !$this->mpdf->PDFXauto)) { $this->mpdf->PDFAXwarnings[] = "Image cannot be converted to suitable colour space for PDFA or PDFX file - ".$file." - (Image replaced by 'no-image'.)"; }
+ return array('error' => "BMP Image cannot be converted to suitable colour space - ".$file." - (Image replaced by 'no-image'.)");
+ }
+
+ $biXPelsPerMeter=$this->_fourbytes2int_le(substr($data,38,4)); // horizontal pixels per meter, usually set to zero
+ //$biYPelsPerMeter=$this->_fourbytes2int_le(substr($data,42,4)); // vertical pixels per meter, usually set to zero
+ $biXPelsPerMeter=round($biXPelsPerMeter/1000 *25.4);
+ //$biYPelsPerMeter=round($biYPelsPerMeter/1000 *25.4);
+ $info['set-dpi'] = $biXPelsPerMeter;
+
+ switch ($biCompression){
+ case 0:
+ $str = substr($data,$bfOffBits);
+ break;
+ case 1: # BI_RLE8
+ $str = $this->rle8_decode(substr($data,$bfOffBits), $width);
+ break;
+ case 2: # BI_RLE4
+ $str = $this->rle4_decode(substr($data,$bfOffBits), $width);
+ break;
+ }
+ $bmpdata = '';
+ $padCnt = (4-ceil(($width/(8/$biBitCount)))%4)%4;
+ switch ($biBitCount){
+ case 1:
+ case 4:
+ case 8:
+ $w = floor($width/(8/$biBitCount)) + ($width%(8/$biBitCount)?1:0);
+ $w_row = $w + $padCnt;
+ if ($flip){
+ for ($y=0;$y<$height;$y++){
+ $y0 = $y*$w_row;
+ for ($x=0;$x<$w;$x++)
+ $bmpdata .= $str[$y0+$x];
+ }
+ }else{
+ for ($y=$height-1;$y>=0;$y--){
+ $y0 = $y*$w_row;
+ for ($x=0;$x<$w;$x++)
+ $bmpdata .= $str[$y0+$x];
+ }
+ }
+ break;
+
+ case 16:
+ $w_row = $width*2 + $padCnt;
+ if ($flip){
+ for ($y=0;$y<$height;$y++){
+ $y0 = $y*$w_row;
+ for ($x=0;$x<$width;$x++){
+ $n = (ord( $str[$y0 + 2*$x + 1])*256 + ord( $str[$y0 + 2*$x]));
+ $b = ($n & 31)<<3; $g = ($n & 992)>>2; $r = ($n & 31744)>>7128;
+ $bmpdata .= chr($r) . chr($g) . chr($b);
+ }
+ }
+ }else{
+ for ($y=$height-1;$y>=0;$y--){
+ $y0 = $y*$w_row;
+ for ($x=0;$x<$width;$x++){
+ $n = (ord( $str[$y0 + 2*$x + 1])*256 + ord( $str[$y0 + 2*$x]));
+ $b = ($n & 31)<<3; $g = ($n & 992)>>2; $r = ($n & 31744)>>7;
+ $bmpdata .= chr($r) . chr($g) . chr($b);
+ }
+ }
+ }
+ break;
+
+ case 24:
+ case 32:
+ $byteCnt = $biBitCount/8;
+ $w_row = $width*$byteCnt + $padCnt;
+
+ if ($flip){
+ for ($y=0;$y<$height;$y++){
+ $y0 = $y*$w_row;
+ for ($x=0;$x<$width;$x++){
+ $i = $y0 + $x*$byteCnt ; # + 1
+ $bmpdata .= $str[$i+2].$str[$i+1].$str[$i];
+ }
+ }
+ }else{
+ for ($y=$height-1;$y>=0;$y--){
+ $y0 = $y*$w_row;
+ for ($x=0;$x<$width;$x++){
+ $i = $y0 + $x*$byteCnt ; # + 1
+ $bmpdata .= $str[$i+2].$str[$i+1].$str[$i];
+ }
+ }
+ }
+ break;
+
+ default:
+ return array('error' => 'Error parsing BMP image - Unsupported image biBitCount');
+ }
+ if ($this->mpdf->compress) {
+ $bmpdata=gzcompress($bmpdata);
+ $info['f']='FlateDecode';
+ }
+ $info['data']=$bmpdata;
+ $info['type']='bmp';
+ return $info;
+}
+
+function _fourbytes2int_le($s) {
+ //Read a 4-byte integer from string
+ return (ord($s[3])<<24) + (ord($s[2])<<16) + (ord($s[1])<<8) + ord($s[0]);
+}
+
+function _twobytes2int_le($s) {
+ //Read a 2-byte integer from string
+ return (ord(substr($s, 1, 1))<<8) + ord(substr($s, 0, 1));
+}
+
+
+# Decoder for RLE8 compression in windows bitmaps
+# see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp
+function rle8_decode ($str, $width){
+ $lineWidth = $width + (3 - ($width-1) % 4);
+ $out = '';
+ $cnt = strlen($str);
+ for ($i=0;$i<$cnt;$i++){
+ $o = ord($str[$i]);
+ switch ($o){
+ case 0: # ESCAPE
+ $i++;
+ switch (ord($str[$i])){
+ case 0: # NEW LINE
+ $padCnt = $lineWidth - strlen($out)%$lineWidth;
+ if ($padCnt<$lineWidth) $out .= str_repeat(chr(0), $padCnt); # pad line
+ break;
+ case 1: # END OF FILE
+ $padCnt = $lineWidth - strlen($out)%$lineWidth;
+ if ($padCnt<$lineWidth) $out .= str_repeat(chr(0), $padCnt); # pad line
+ break 3;
+ case 2: # DELTA
+ $i += 2;
+ break;
+ default: # ABSOLUTE MODE
+ $num = ord($str[$i]);
+ for ($j=0;$j<$num;$j++)
+ $out .= $str[++$i];
+ if ($num % 2) $i++;
+ }
+ break;
+ default:
+ $out .= str_repeat($str[++$i], $o);
+ }
+ }
+ return $out;
+}
+
+# Decoder for RLE4 compression in windows bitmaps
+# see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp
+function rle4_decode ($str, $width){
+ $w = floor($width/2) + ($width % 2);
+ $lineWidth = $w + (3 - ( ($width-1) / 2) % 4);
+ $pixels = array();
+ $cnt = strlen($str);
+ for ($i=0;$i<$cnt;$i++){
+ $o = ord($str[$i]);
+ switch ($o){
+ case 0: # ESCAPE
+ $i++;
+ switch (ord($str[$i])){
+ case 0: # NEW LINE
+ while (count($pixels)%$lineWidth!=0)
+ $pixels[]=0;
+ break;
+ case 1: # END OF FILE
+ while (count($pixels)%$lineWidth!=0)
+ $pixels[]=0;
+ break 3;
+ case 2: # DELTA
+ $i += 2;
+ break;
+ default: # ABSOLUTE MODE
+ $num = ord($str[$i]);
+ for ($j=0;$j<$num;$j++){
+ if ($j%2==0){
+ $c = ord($str[++$i]);
+ $pixels[] = ($c & 240)>>4;
+ } else
+ $pixels[] = $c & 15;
+ }
+ if ($num % 2) $i++;
+ }
+ break;
+ default:
+ $c = ord($str[++$i]);
+ for ($j=0;$j<$o;$j++)
+ $pixels[] = ($j%2==0 ? ($c & 240)>>4 : $c & 15);
+ }
+ }
+
+ $out = '';
+ if (count($pixels)%2) $pixels[]=0;
+ $cnt = count($pixels)/2;
+ for ($i=0;$i<$cnt;$i++)
+ $out .= chr(16*$pixels[2*$i] + $pixels[2*$i+1]);
+ return $out;
+}
+
+
+
+}
+
+?>
\ No newline at end of file
diff --git a/mpdf/classes/cssmgr.php b/mpdf/classes/cssmgr.php
new file mode 100644
index 0000000..7a9e87a
--- /dev/null
+++ b/mpdf/classes/cssmgr.php
@@ -0,0 +1,1721 @@
+mpdf = $mpdf;
+ $this->tablecascadeCSS = array();
+ $this->CSS=array();
+ $this->cascadeCSS = array();
+ $this->tbCSSlvl = 0;
+}
+
+function ReadCSS($html) {
+ preg_match_all('/', $html);
+ preg_match_all('/(.*?)<\/style>/si',$html,$m);
+ if (count($m[1])) {
+ for($i=0;$i)/s',' ',$m[1][$i]);
+ $sub = '>'.preg_replace('|/\*.*?\*/|s',' ',$sub).'';
+ $html = str_replace('>'.$m[1][$i].'', $sub, $html);
+ }
+ }
+
+
+ $html = preg_replace('//i','',$html);
+ $html = preg_replace('/<\!\-\-.*?\-\->/s',' ',$html);
+
+ $match = 0; // no match for instance
+ $regexp = ''; // This helps debugging: showing what is the REAL string being processed
+ $CSSext = array();
+
+ //CSS inside external files
+ $regexp = '/]*rel=["\']stylesheet["\'][^>]*href=["\']([^>"\']*)["\'].*?>/si';
+ $x = preg_match_all($regexp,$html,$cxt);
+ if ($x) {
+ $match += $x;
+ $CSSext = $cxt[1];
+ }
+ $regexp = '/]*href=["\']([^>"\']*)["\'][^>]*?rel=["\']stylesheet["\'].*?>/si';
+ $x = preg_match_all($regexp,$html,$cxt);
+ if ($x) {
+ $match += $x;
+ $CSSext = array_merge($CSSext,$cxt[1]);
+ }
+
+ // look for @import stylesheets
+ //$regexp = '/@import url\([\'\"]{0,1}([^\)]*?\.css)[\'\"]{0,1}\)/si';
+ $regexp = '/@import url\([\'\"]{0,1}([^\)]*?\.css(\?\S+)?)[\'\"]{0,1}\)/si';
+ $x = preg_match_all($regexp,$html,$cxt);
+ if ($x) {
+ $match += $x;
+ $CSSext = array_merge($CSSext,$cxt[1]);
+ }
+
+ // look for @import without the url()
+ //$regexp = '/@import [\'\"]{0,1}([^;]*?\.css)[\'\"]{0,1}/si';
+ $regexp = '/@import [\'\"]{0,1}([^;]*?\.css(\?\S+)?)[\'\"]{0,1}/si';
+ $x = preg_match_all($regexp,$html,$cxt);
+ if ($x) {
+ $match += $x;
+ $CSSext = array_merge($CSSext,$cxt[1]);
+ }
+
+ $ind = 0;
+ $CSSstr = '';
+
+ if (!is_array($this->cascadeCSS)) $this->cascadeCSS = array();
+
+ while($match){
+ $path = $CSSext[$ind];
+
+ $path = htmlspecialchars_decode($path); // mPDF 6
+
+ $this->mpdf->GetFullPath($path);
+ $CSSextblock = $this->mpdf->_get_file($path);
+ if ($CSSextblock) {
+ // look for embedded @import stylesheets in other stylesheets
+ // and fix url paths (including background-images) relative to stylesheet
+ //$regexpem = '/@import url\([\'\"]{0,1}(.*?\.css)[\'\"]{0,1}\)/si';
+ $regexpem = '/@import url\([\'\"]{0,1}(.*?\.css(\?\S+)?)[\'\"]{0,1}\)/si';
+ $xem = preg_match_all($regexpem,$CSSextblock,$cxtem);
+ $cssBasePath = preg_replace('/\/[^\/]*$/','',$path) . '/';
+ if ($xem) {
+ foreach($cxtem[1] AS $cxtembedded) {
+ // path is relative to original stlyesheet!!
+ $this->mpdf->GetFullPath($cxtembedded, $cssBasePath );
+ $match++;
+ $CSSext[] = $cxtembedded;
+ }
+ }
+ $regexpem = '/(background[^;]*url\s*\(\s*[\'\"]{0,1})([^\)\'\"]*)([\'\"]{0,1}\s*\))/si';
+ $xem = preg_match_all($regexpem,$CSSextblock,$cxtem);
+ if ($xem) {
+ for ($i=0;$impdf->GetFullPath($embedded, $cssBasePath );
+ $CSSextblock = preg_replace('/'.preg_quote($cxtem[0][$i],'/').'/', ($cxtem[1][$i].$embedded.$cxtem[3][$i]), $CSSextblock);
+ }
+ }
+ }
+ $CSSstr .= ' '.$CSSextblock;
+ }
+ $match--;
+ $ind++;
+ } //end of match
+
+ $match = 0; // reset value, if needed
+ // CSS as
+
+
+mPDF
+Backgrounds & Borders
+
+
+ Page background
+
+The background colour can be set by CSS styles on the <body> tag. This will set the background for the whole page. In this document, the background has been set as a gradient (see below).
+
+
+ Background Gradients
+
+Background can be set as a linear or radial gradient between two colours. The background has been set on this <div> element to a linear gradient. CSS style used here is:
+background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+The four numbers are coordinates in the form (x1, y1, x2, y2) which defines the gradient vector. x and y are values from 0 to 1, where 1 represents the height or width of the box as it is printed.
+
+
+Background gradients can be set on all block elements e.g. P, DIV, H1-H6, as well as on BODY.
+
+
+The background has been set on this <div> element to a radial gradient. CSS style used here is:
+background-gradient: radial #00FFFF #FFFF00 0.5 0.5 0.5 0.5 0.65;
+The five numbers are coordinates in the form (x1, y1, x2, y2, r) where (x1, y1) is the starting point of the gradient with color1,
+(x2, y2) is the center of the circle with color2, and r is the radius of the circle.
+(x1, y1) should be inside the circle, otherwise some areas will not be defined.
+
+
+Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec mattis lacus ac purus feugiat semper. Donec aliquet nunc odio, vitae pellentesque diam. Pellentesque sed velit lacus. Duis quis dui quis sem consectetur sollicitudin. Cras dolor quam, dapibus et pretium sit amet, elementum vel arcu. Duis rhoncus facilisis erat nec mattis. In hac habitasse platea dictumst. Vivamus hendrerit sem in justo aliquet a pellentesque lorem scelerisque. Suspendisse a augue sed urna rhoncus elementum. Aliquam erat volutpat.
+
+
+ Background Images
+
+The CSS properties background-image, background-position, and background-repeat are supported as defined in CSS2, as well as the shorthand form "background".
+
+The background has been set on this <div> element to:
+background: transparent url(\'bg.jpg\') repeat fixed right top;
+Background gradients can be set on all block elements e.g. P, DIV, H1-H6, as well as on BODY.
+
+
+ Rounded Borders
+
+Rounded corners to borders can be added using border-radius as defined in the draft spec. of CSS3.
+
+The two length values of the border-*-radius properties define the radii of a quarter ellipse that defines the shape of the corner of the outer border edge.
+The first value is the horizontal radius.
+ border-top-left-radius: 55pt 25pt; 55pt is radius of curve from top end of left border starting to go round to the top.
+
+If the second length is omitted it is equal to the first (and the corner is thus a quarter circle). If either length is zero, the corner is square, not rounded.
+
+The border-radius shorthand sets all four border-*-radius properties. If values are given before and after a slash, then the values before the slash set the horizontal radius and the values after the slash set the vertical radius. If there is no slash, then the values set both radii equally. The four values for each radii are given in the order top-left, top-right, bottom-right, bottom-left. If bottom-left is omitted it is the same as top-right. If bottom-right is omitted it is the same as top-left. If top-right is omitted it is the same as top-left.
+
+
+border-radius: 4em;
+
+would be equivalent to
+
+border-top-left-radius: 4em;
+border-top-right-radius: 4em;
+border-bottom-right-radius: 4em;
+border-bottom-left-radius: 4em;
+
+and
+border-radius: 2em 1em 4em / 0.5em 3em;
+would be equivalent to
+border-top-left-radius: 2em 0.5em;
+border-top-right-radius: 1em 3em;
+border-bottom-right-radius: 4em 0.5em;
+border-bottom-left-radius: 1em 3em;
+
+
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+include("../mpdf.php");
+
+$mpdf=new mPDF();
+
+$mpdf->SetDisplayMode('fullpage');
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+
+exit;
+
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example04_images.php b/mpdf/examples/example04_images.php
new file mode 100644
index 0000000..4807dfc
--- /dev/null
+++ b/mpdf/examples/example04_images.php
@@ -0,0 +1,207 @@
+
+table { border-collapse: collapse; margin-top: 0; text-align: center; }
+td { padding: 0.5em; }
+h1 { margin-bottom: 0; }z
+
+mPDF Images
+
+
+
+| GIF |
+JPG |
+JPG (CMYK) |
+PNG |
+BMP |
+WMF |
+SVG |
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+Opacity 50% |
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+Alpha channel
+
+Transparency
+
+| PNG |
+ |
+ |
+ |
+ |
+
+| GIF |
+ |
+ |
+ |
+ |
+
+| WMF |
+ |
+ |
+ |
+ |
+
+| SVG |
+ |
+ |
+ |
+ |
+
+
+
+Images returned from tiger.php
+
+GIF 
+JPG 
+PNG 
+WMF 
+SVG 
+
+
+
+
+
+Image Alignment
+In-line images can be individually aligned (vertically). Most of the values for "vertical-align" are supported: top, bottom, middle, baseline, text-top, and text-bottom. The default value for vertical alignment is baseline, and the default padding 0, consistent with most browsers.
+
+
+
+
+These images 
+are 
+ top 
+aligned 
+
+
+
+
+These images 
+are 
+ text-top 
+aligned 
+
+
+
+
+These images 
+are 
+ bottom 
+aligned 
+
+
+
+
+These images 
+are 
+ text-bottom 
+aligned 
+
+
+
+
+These images 
+are 
+ baseline 
+aligned 
+
+
+
+
+These images 
+are 
+ middle 
+aligned 
+
+
+
+Mixed alignment
+
+baseline: 
+text-bottom: 
+middle: 
+bottom: 
+text-top: 
+top: 
+
+
+Image Border and padding
+Image padding is supported as well as border and margin.
+
+
+Rotated Images
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+';
+//==============================================================
+//==============================================================
+//==============================================================
+include("../mpdf.php");
+
+$mpdf=new mPDF('c');
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+exit;
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example05_tables.php b/mpdf/examples/example05_tables.php
new file mode 100644
index 0000000..997614a
--- /dev/null
+++ b/mpdf/examples/example05_tables.php
@@ -0,0 +1,1017 @@
+mPDF
+Tables
+CSS Styles
+The CSS properties for tables and cells is increased over that in html2fpdf. It includes recognition of THEAD, TFOOT and TH. See below for other facilities such as autosizing, and rotation.
+
+| Row 1 | This is data | This is data |
+
+| Row 2 |
+
+
+ This is data p
+This is data out of p
+This is bold data p
+This is bold data out of p
+This is normal data after br
+H3 in a table
+This is data div
+This is data out of div
+This is data div (bold)
+This is data out of div
+ |
+
+
+More data This is large text |
+Row 3 | This is long data | This is data |
+Row 4 <td> cell | This is data | This is data |
+| Row 5 | Also data | Also data |
+| Row 6 | Also data | Also data |
+| Row 7 | Also data | Also data |
+| Row 8 | Also data | Also data |
+
+
+This table has padding-left and -right set to 5mm i.e. padding within the cells. Also border colour and style, font family and size are set by CSS.
+
+| Row 1 | This is data | This is data |
+| Row 2 | This is data p | More data |
+Row 3 | This is long data | This is data |
+Row 4 <td> cell | This is data | This is data |
+| Row 5 | Also data | Also data |
+| Row 6 | Also data | Also data |
+| Row 7 | Also data | Also data |
+| Row 8 | Also data | Also data |
+
+
+This table has padding-top and -bottom set to 3mm i.e. padding within the cells. Also background-, border colour and style, font family and size are set by in-line CSS.
+
+| Row 1 | This is data | This is data |
+| Row 2 | This is data p | More data |
+Row 3 | This is long data | This is data |
+
+
+
+Table Styles
+The style sheet used for these examples shows some of the table styles I use on my website. The property \'topntail\' defined by a border-type definition e.g. "1px solid #880000" puts a border at the top and bottom of the table, and also below a header row (thead) if defined. Note also that <thead> will automatically turn on the header-repeat i.e. reproduce the header row at the top of each page.
+bpmTopic Class
+
+
+| Row 1 |
+This is data |
+This is data |
+
+
+| Row 2 |
+
+ This is data p
+ |
+
+ More data
+ |
+
+
+|
+ Row 3
+ |
+
+ This is long data
+ |
+This is data |
+
+
+|
+ Row 4 <td> cell
+ |
+This is data |
+
+ This is data
+ |
+
+
+| Row 5 |
+Also data |
+Also data |
+
+
+| Row 6 |
+Also data |
+Also data |
+
+
+| Row 7 |
+Also data |
+Also data |
+
+
+| Row 8 |
+Also data |
+Also data |
+
+
+
+
+
+bpmTopicC Class (centered) Odd and Even rows
+
+
+
+| Row header 1 |
+This is data |
+This is data |
+
+| Row header 2 |
+
+ This is data p
+ |
+
+ This is data
+ |
+
+|
+ Row header 3
+ |
+
+ This is long data
+ |
+This is data |
+
+|
+ Row header 4
+<th> cell acting as header
+ |
+This is data |
+
+ This is data
+ |
+
+| Row header 5 |
+Also data |
+Also data |
+
+| Row header 6 |
+Also data |
+Also data |
+
+| Row header 7 |
+Also data |
+Also data |
+
+| Row header 8 |
+Also data |
+Also data |
+
+
+
+
+
+bpmTopnTail Class
+
+
+| Row 1 |
+This is data |
+This is data |
+
+
+| Row 2 |
+
+ This is data p
+ |
+
+ This is data
+ |
+
+
+|
+ Row 3
+ |
+
+ This is long data
+ |
+This is data |
+
+
+|
+ Row 4 <td> cell
+ |
+This is data |
+
+ This is data
+ |
+
+
+| Row 5 |
+Also data |
+Also data |
+
+
+| Row 6 |
+Also data |
+Also data |
+
+
+| Row 7 |
+Also data |
+Also data |
+
+
+| Row 8 |
+Also data |
+Also data |
+
+
+
+bpmTopnTailC Class (centered) Odd and Even rows
+
+
+
+| Row header 1 |
+This is data |
+This is data |
+
+| Row header 2 |
+
+ This is data p
+ |
+
+ This is data
+ |
+
+|
+ Row header 3
+ |
+
+ This is long data
+ |
+This is data |
+
+|
+ Row header 4
+<th> cell acting as header
+ |
+This is data |
+
+ This is data
+ |
+
+| Row header 5 |
+Also data |
+Also data |
+
+| Row header 6 |
+Also data |
+Also data |
+
+| Row header 7 |
+Also data |
+Also data |
+
+| Row header 8 |
+Also data |
+Also data |
+
+
+
+
+
+TopnTail Class
+
+
+
+|
+ Row header 1 p
+ |
+This is data |
+This is data |
+
+| Row header 2 |
+Bottom right align |
+
+ This is data. Can use
+bold italic sub or sup text
+ |
+
+|
+ Bottom right align
+ |
+
+ This is data. This cell
+uses Cell Styles to set
+the borders.
+All borders are collapsible
+in mPDF.
+ |
+This is data |
+
+| Row header 4 |
+
+ This is data p
+ |
+More data |
+
+| Row header 5 |
+Also data merged and centered |
+
+
+
+
+
+Lists in a Table
+
+
+
+|
+ Row header 1 p
+ |
+This is data |
+This is data |
+
+| Row header 2 |
+
+
+- Item 1
+- Item 2
+
+- Subitem of ordered list
+- Subitem 2
+
+- Level 3 subitem
+- Level 3 subitem
+
+
+
+
+- Item 3
+- Another Item
+- Subitem
+
+- Level 3 subitem
+
+
+- Another Item
+
+ |
+
+Unordered list:
+
+- Item 1
+- Item 2
+
+- Subitem of unordered list
+- Subitem 2
+
+- Level 3 subitem
+- Level 3 subitem
+- Level 3 subitem
+
+
+
+
+- Item 3
+
+ |
+
+
+
+
+
+Automatic Column Width
+
+
+| Causes |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit.
+Ut a eros at ligula vehicula pretium; maecenas feugiat pede vel risus.
+Suspendisse potenti |
+
+
+| Mechanisms |
+Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. |
+
+
+
+
+ColSpan & Rowspan
+
+
+| Causes |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit.
+Ut a eros at ligula vehicula pretium; maecenas feugiat pede vel risus.
+Suspendisse potenti |
+
+
+Fusce eleifend neque sit amet erat.
+Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. |
+Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla.
+Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. |
+
+
+
+
+
+Table Header & Footer Rows
+A table using a header row should repeat the header row across pages:
+bpmTopicC Class
+
+
+
+
+
+
+
+
+| Row header 1 |
+This is data |
+This is data |
+
+| Row header 2 |
+This is data |
+
+ This is data
+ |
+
+|
+ Row header 3
+ |
+
+ This is data
+ |
+This is data |
+
+| Row header 4 |
+This is data |
+
+ This is data
+ |
+
+| Row header 5 |
+Also data |
+Also data |
+
+| Row header 6 |
+Also data |
+Also data |
+
+| Row header 7 |
+Also data |
+Also data |
+
+| Row header 8 |
+Also data |
+Also data |
+
+| Row header 9 |
+Also data |
+Also data |
+
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+
+
+
+Autosizing Tables
+Periodic Table of elements. Tables are set by default to reduce font size if complete words will not fit inside each cell, to a maximum of 1/1.4 * the set font-size. This value can be changed by setting $mpdf->shrink_tables_to_fit=1.8 or using html attribute <table autosize="1.8">.
+
+Periodic Table
+
+
+| 1A | 2A | 3B | 4B | 5B | 6B | 7B | 8B | 8B | 8B | 1B | 2B | 3A | 4A | 5A | 6A | 7A | 8A |
+
+ |
+
+
+| H |
+ |
+He |
+
+
+| Li |
+Be |
+ |
+B |
+C |
+N |
+O |
+F |
+Ne |
+
+
+| Na |
+Mg |
+ |
+Al |
+Si |
+P |
+S |
+Cl |
+Ar |
+
+
+| K |
+Ca |
+Sc |
+Ti |
+V |
+Cr |
+Mn |
+Fe |
+Co |
+Ni |
+Cu |
+Zn |
+Ga |
+Ge |
+As |
+Se |
+Br |
+Kr |
+
+
+| Rb |
+Sr |
+Y |
+Zr |
+Nb |
+Mo |
+Tc |
+Ru |
+Rh |
+Pd |
+Ag |
+Cd |
+In |
+Sn |
+Sb |
+Te |
+I |
+Xe |
+
+
+| Cs |
+Ba |
+La |
+Hf |
+Ta |
+W |
+Re |
+Os |
+Ir |
+Pt |
+Au |
+Hg |
+Tl |
+Pb |
+Bi |
+Po |
+At |
+Rn |
+
+
+| Fr |
+Ra |
+Ac |
+ |
+
+
+ |
+
+
+ |
+Ce |
+Pr |
+Nd |
+Pm |
+Sm |
+Eu |
+Gd |
+Tb |
+Dy |
+Ho |
+Er |
+Tm |
+Yb |
+Lu |
+ |
+
+
+ |
+Th |
+Pa |
+U |
+Np |
+Pu |
+Am |
+Cm |
+Bk |
+Cf |
+Es |
+Fm |
+Md |
+No |
+Lr |
+ |
+
+
+
+
+
+Rotating Tables
+This is set to rotate -90 degrees (counterclockwise).
+
+Periodic Table
+
+
+| 1A | 2A | 3B | 4B | 5B | 6B | 7B | 8B | 8B | 8B | 1B | 2B | 3A | 4A | 5A | 6A | 7A | 8A |
+
+ |
+ |
+
+
+| H |
+ |
+ |
+He |
+
+
+| Li |
+Be |
+ |
+B |
+C |
+N |
+O |
+F |
+Ne |
+
+
+| Na |
+Mg |
+ |
+Al |
+Si |
+P |
+S |
+Cl |
+Ar |
+
+
+| K |
+Ca |
+Sc |
+Ti |
+V |
+Cr |
+Mn |
+Fe |
+Co |
+Ni |
+Cu |
+Zn |
+Ga |
+Ge |
+As |
+Se |
+Br |
+Kr |
+
+
+| Rb |
+Sr |
+Y |
+Zr |
+Nb |
+Mo |
+Tc |
+Ru |
+Rh |
+Pd |
+Ag |
+Cd |
+In |
+Sn |
+Sb |
+Te |
+I |
+Xe |
+
+
+| Cs |
+Ba |
+La |
+Hf |
+Ta |
+W |
+Re |
+Os |
+Ir |
+Pt |
+Au |
+Hg |
+Tl |
+Pb |
+Bi |
+Po |
+At |
+Rn |
+
+
+| Fr |
+Ra |
+Ac |
+
+
+ |
+ |
+
+
+ |
+Ce |
+Pr |
+Nd |
+Pm |
+Sm |
+Eu |
+Gd |
+Tb |
+Dy |
+Ho |
+Er |
+Tm |
+Yb |
+Lu |
+ |
+
+
+ |
+Th |
+Pa |
+U |
+Np |
+Pu |
+Am |
+Cm |
+Bk |
+Cf |
+Es |
+Fm |
+Md |
+No |
+Lr |
+ |
+
+
+
+
+
+Rotated text in Table Cells
+
+Periodic Table
+
+
+
+Element type 1A Second line | Element type longer 2A |
+Element type 3B |
+Element type 4B |
+Element type 5B |
+Element type 6B |
+7B | 8B |
+Element type 8B R |
+8B |
+Element type 1B |
+2B |
+Element type 3A |
+Element type 4A |
+Element type 5A |
+Element type 6A |
+7A |
+Element type 8A |
+
+
+
+
+
+| H |
+ |
+ |
+He |
+
+
+| Li |
+Be |
+ |
+B |
+C |
+N |
+O |
+F |
+Ne |
+
+
+| Na |
+Mg |
+ |
+Al |
+Si |
+P |
+S |
+Cl |
+Ar |
+
+
+| K |
+Ca |
+Sc |
+Ti |
+Va |
+Cr |
+Mn |
+Fe |
+Co |
+Ni |
+Cu |
+Zn |
+Ga |
+Ge |
+As |
+Se |
+Br |
+Kr |
+
+
+| Rb |
+Sr |
+Y |
+Zr |
+Nb |
+Mo |
+Tc |
+Ru |
+Rh |
+Pd |
+Ag |
+Cd |
+In |
+Sn |
+Sb |
+Te |
+I |
+Xe |
+
+
+| Cs |
+Ba |
+La |
+Hf |
+Ta |
+W |
+Re |
+Os |
+Ir |
+Pt |
+Au |
+Hg |
+Tl |
+Pb |
+Bi |
+Po |
+At |
+Rn |
+
+
+| Fr |
+Ra |
+Ac |
+
+
+ |
+Ce |
+Pr |
+Nd |
+Pm |
+Sm |
+Eu |
+Gd |
+Tb |
+Dy |
+Ho |
+Er |
+Tm |
+Yb |
+Lu |
+ |
+
+
+ |
+Th |
+Pa |
+U |
+Np |
+Pu |
+Am |
+Cm |
+Bk |
+Cf |
+Es |
+Fm |
+Md |
+No |
+Lr |
+ |
+
+
+
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+include("../mpdf.php");
+
+$mpdf=new mPDF('c','A4','','',32,25,27,25,16,13);
+
+$mpdf->SetDisplayMode('fullpage');
+
+$mpdf->list_indent_first_level = 0; // 1 or 0 - whether to indent the first level of a list
+
+// LOAD a stylesheet
+$stylesheet = file_get_contents('mpdfstyletables.css');
+$mpdf->WriteHTML($stylesheet,1); // The parameter 1 tells that this is css/style only and no body/html/text
+
+$mpdf->WriteHTML($html,2);
+
+$mpdf->Output('mpdf.pdf','I');
+exit;
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example06_tables_nested.php b/mpdf/examples/example06_tables_nested.php
new file mode 100644
index 0000000..e50764a
--- /dev/null
+++ b/mpdf/examples/example06_tables_nested.php
@@ -0,0 +1,532 @@
+
+
+
+
+mPDF
+Tables - Nested
+
+
+
+Text before table
+
+
+
+
+
+
+| This is data |
+This is data |
+
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+
+| Row C |
+C2 |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. |
+C4 |
+
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+
+
+
+ |
+This is data |
+
+
+| This is data |
+This is data |
+
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+
+| Row C |
+C2 |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. |
+C4 |
+
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+
+
+
+ |
+This is data |
+
+
+
+| This is data |
+This is data |
+
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+
+| Row C |
+C2 |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. |
+C4 |
+
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+
+
+
+ |
+This is data |
+
+
+
+| This is data |
+This is data |
+
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+
+| Row C |
+C2 |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. |
+C4 |
+
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+
+
+
+ |
+This is data |
+
+
+
+
+| This is data |
+This is data |
+This is data |
+This is data |
+
+
+
+| This is data |
+ |
+This is data |
+This is data |
+
+
+
+| This is data |
+This is data |
+This is data |
+This is data |
+
+
+
+
+
+
+
+ Text before table
+
+
+
+
+| Row 1 |
+This is data |
+
+Text before table
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+
+| Row C |
+C2 |
+C3 |
+C4 |
+
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+
+Text after table
+
+
+ |
+This is data |
+
+
+
+| Row 2 |
+This is data |
+This is data |
+This is data |
+
+
+
+| Row 3 |
+
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+
+| Row B |
+B2 |
+ |
+B4 |
+
+
+
+| Row C |
+C2 |
+
+
+
+
+
+| F1 |
+F2 |
+
+
+| Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec et nulla. Sed quis orci. |
+G2 |
+
+
+
+ |
+C4 |
+
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+
+
+
+ |
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+
+| Row C |
+C2 |
+C3 |
+C4 |
+
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+
+ |
+This is data |
+
+
+
+| Row 4 |
+This is data |
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+
+| Row B |
+B2 |
+ |
+B4 |
+
+
+
+| Row C |
+C2 |
+
+
+
+
+
+| F1 |
+F2 |
+
+
+| Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec et nulla. Sed quis orci. |
+G2 |
+
+
+
+ |
+C4 |
+
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+
+
+ |
+This is data |
+
+
+
+
+
+
+
+
+
+
+
+
+Text before table
+
+
+
+
+| Row 1 |
+This is data |
+
+
+NO NESTING |
+This is data |
+
+
+
+| Row 2 |
+This is data |
+This is data |
+This is data |
+
+
+
+| Row 3 |
+This is data |
+This is data |
+This is data |
+
+
+
+| Row 4 |
+This is data |
+This is data |
+This is data |
+
+
+
+
+
+
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+include("../mpdf.php");
+
+$mpdf=new mPDF('c','A4','','',32,25,27,25,16,13);
+
+$mpdf->SetDisplayMode('fullpage');
+
+$mpdf->list_indent_first_level = 0; // 1 or 0 - whether to indent the first level of a list
+
+// LOAD a stylesheet
+$stylesheet = file_get_contents('mpdfstyletables.css');
+$mpdf->WriteHTML($stylesheet,1); // The parameter 1 tells that this is css/style only and no body/html/text
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+exit;
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example07_tables_borders.php b/mpdf/examples/example07_tables_borders.php
new file mode 100644
index 0000000..fce39e7
--- /dev/null
+++ b/mpdf/examples/example07_tables_borders.php
@@ -0,0 +1,498 @@
+
+
+
+
+
+mPDF
+Tables - Borders
+mPDF
+
+Border conflict resolution in tables with border-collapse set to "collapse". mPDF follows the rules set by CSS as well as possible, but as you can see, there is some difference in interpretation of the rules:
+
+
+
+
+ | mPDF |
+ Internet Explorer IE 9 |
+ Firefox v 32.0.3 |
+
+
+
+
+
+
+
+
+ | 1 |
+ 1 |
+ 1 |
+
+
+ | 1 |
+ 1 |
+ 1 |
+
+
+ | 1 |
+ 1 |
+
+
+ | 1 |
+ 1 |
+ 1 |
+
+
+
+
+
+ |
+
+  |
+  |
+
+
+
+
+
+
+
+
+
+ | 1 |
+ 1 |
+ 1 |
+
+
+ | 1 |
+ 1 |
+ 1 |
+
+
+ | 1 |
+ 1 |
+
+
+ | 1 |
+ 1 |
+ 1 |
+
+
+
+
+ |
+
+
+
+
+
+
+
+ | 1 |
+ 1 |
+ 1 |
+
+
+ | 1 |
+ 1 |
+ 1 |
+
+
+ | 1 |
+ 1 |
+
+
+ | 1 |
+ 1 |
+ 1 |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+ | mPDF |
+ Internet Explorer IE 9 |
+ Firefox v 32.0.3 |
+
+
+
+
+
+
+
+
+ | 1 |
+ 1 |
+ 1 |
+
+
+ | 1 |
+ 1 |
+ 1 |
+
+
+ | 1 |
+ 1 |
+
+
+ | 1 |
+ 1 |
+ 1 |
+
+
+
+
+
+ |
+
+  |
+  |
+
+
+
+
+
+
+
+
+
+ | 1 |
+ 1 |
+ 1 |
+
+
+ | 1 |
+ 1 |
+ 1 |
+
+
+ | 1 |
+ 1 |
+
+
+ | 1 |
+ 1 |
+ 1 |
+
+
+
+
+ |
+
+
+
+
+
+
+
+ | 1 |
+ 1 |
+ 1 |
+
+
+ | 1 |
+ 1 |
+ 1 |
+
+
+ | 1 |
+ 1 |
+
+
+ | 1 |
+ 1 |
+ 1 |
+
+
+
+
+ |
+
+
+
+
+
+mPDF
+
+
+
+| Data |
+double red |
+dashed yellow |
+dotted green |
+Data |
+
+
+| Data |
+hidden |
+Data |
+none |
+Data |
+
+
+| Data |
+ridge blue |
+none |
+none |
+Data |
+
+
+| Data |
+none |
+groove pink |
+none |
+Data |
+
+
+| none |
+inset gray |
+none |
+outset purple |
+none |
+
+
+
+Firefox 32
+
+
+
+
+
+IE 9
+
+
+
+
+mPDF
+
+
+
+| Data |
+double red |
+dashed yellow |
+dotted green |
+Data |
+
+
+| Data |
+hidden |
+Data |
+none |
+Data |
+
+
+| Data |
+ridge blue |
+none |
+none |
+Data |
+
+
+| Data |
+none |
+groove pink |
+none |
+Data |
+
+
+| none |
+inset gray |
+none |
+outset purple |
+none |
+
+
+
+Firefox 32
+
+
+
+
+IE 9
+
+
+
+
+
+
+
+| solid orange |
+
+none |
+
+double red |
+
+none |
+
+inset gray |
+
+none |
+
+outset purple |
+
+none |
+
+groove pink |
+
+none |
+
+ridge blue |
+
+
+
+
+
+
+| solid orange |
+none |
+double red |
+none |
+inset gray |
+none |
+outset purple |
+none |
+groove pink |
+none |
+ridge blue |
+
+
+
+
+
+
+| solid orange |
+none |
+double red |
+none |
+inset gray |
+none |
+outset purple |
+none |
+groove pink |
+none |
+ridge blue |
+
+
+
+
+
+
+| solid orange |
+none |
+double red |
+none |
+inset gray |
+none |
+outset purple |
+none |
+groove pink |
+none |
+ridge blue |
+
+
+
+
+
+
+| solid orange |
+none |
+double red |
+none |
+inset gray |
+none |
+outset purple |
+none |
+groove pink |
+none |
+ridge blue |
+
+
+
+
+
+
+| solid orange |
+none |
+double red |
+none |
+inset gray |
+none |
+outset purple |
+none |
+groove pink |
+none |
+ridge blue |
+
+
+
+
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+include("../mpdf.php");
+
+$mpdf=new mPDF('en-GB-x','A4','','',10,10,10,10,6,3);
+
+$mpdf->SetDisplayMode('fullpage');
+
+$mpdf->list_indent_first_level = 0; // 1 or 0 - whether to indent the first level of a list
+
+// LOAD a stylesheet
+$stylesheet = file_get_contents('mpdfstyletables.css');
+$mpdf->WriteHTML($stylesheet,1); // The parameter 1 tells that this is css/style only and no body/html/text
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+exit;
+//==============================================================
+//==============================================================
+//==============================================================
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example08_lists.php b/mpdf/examples/example08_lists.php
new file mode 100644
index 0000000..e251bc5
--- /dev/null
+++ b/mpdf/examples/example08_lists.php
@@ -0,0 +1,155 @@
+
+ol, ul { text-align: justify;
+}
+
+.lista { list-style-type: upper-roman; }
+.listb{ list-style-type: decimal; font-family: sans-serif; color: blue; font-weight: bold; font-style: italic; font-size: 19pt; }
+.listc{ list-style-type: upper-alpha; padding-left: 25mm; }
+.listd{ list-style-type: lower-alpha; color: teal; line-height: 2; }
+.liste{ list-style-type: disc; }
+.listarabic { direction: rtl; list-style-type: arabic-indic; font-family: dejavusanscondensed; padding-right: 40px;}
+
+
+
+mPDF
+Lists
+
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Big text indent 25mm: Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Big text indent 25mm: Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- No class specified. Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+
+
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+
+- للعراق ان الاولوية حاليا
+- للعراق ان الاولوية حاليا
+- للعراق ان الاولوية حاليا
+- للعراق ان الاولوية حاليا
+- للعراق ان الاولوية حاليا
+- للعراق ان الاولوية حاليا
+
+
+
+
+';
+//==============================================================
+//==============================================================
+
+//echo $html; exit;
+//==============================================================
+include("../mpdf.php");
+
+$mpdf=new mPDF();
+
+$mpdf->SetDisplayMode('fullpage');
+
+$mpdf->WriteHTML($html);
+
+$mpdf->list_number_suffix = ')';
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+
+exit;
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example09_forms.php b/mpdf/examples/example09_forms.php
new file mode 100644
index 0000000..5c9190f
--- /dev/null
+++ b/mpdf/examples/example09_forms.php
@@ -0,0 +1,192 @@
+
+
+Textarea
+
+
+
+Select
+ followed by text
+
+
+
+
+Input Radio
+ No Yes
+
+
+
+Input Radio
+ No Keep Choice
+
+
+
+Input Text
+
+
+
+Input Password
+
+
+
+
+ Checkboxes
+ Disabled
+ Selected
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+
+$mpdf=new mPDF('c');
+
+// LOAD a stylesheet
+$stylesheet = file_get_contents('mpdfstyletables.css');
+$mpdf->WriteHTML($stylesheet,1); // The parameter 1 tells that this is css/style only and no body/html/text
+
+$mpdf->SetColumns(2,'J');
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+exit;
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example10_floating_and_fixed_position_elements.php b/mpdf/examples/example10_floating_and_fixed_position_elements.php
new file mode 100644
index 0000000..8a485e3
--- /dev/null
+++ b/mpdf/examples/example10_floating_and_fixed_position_elements.php
@@ -0,0 +1,103 @@
+
+.gradient {
+ border:0.1mm solid #220044;
+ background-color: #f0f2ff;
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+}
+h4 {
+ font-family: sans;
+ font-weight: bold;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+div {
+ padding:1em;
+ margin-bottom: 1em;
+ text-align:justify;
+}
+.myfixed1 { position: absolute;
+ overflow: visible;
+ left: 0;
+ bottom: 0;
+ border: 1px solid #880000;
+ background-color: #FFEEDD;
+ background-gradient: linear #dec7cd #fff0f2 0 1 0 0.5;
+ padding: 1.5em;
+ font-family:sans;
+ margin: 0;
+}
+.myfixed2 { position: fixed;
+ overflow: auto;
+ right: 0;
+ bottom: 0mm;
+ width: 65mm;
+ border: 1px solid #880000;
+ background-color: #FFEEDD;
+ background-gradient: linear #dec7cd #fff0f2 0 1 0 0.5;
+ padding: 0.5em;
+ font-family:sans;
+ margin: 0;
+ rotate: 90;
+}
+
+
+
+mPDF
+Floating & Fixed Position elements
+
+CSS "Float"
+
+Block elements can be positioned alongside each other using the CSS property float: left or right. The clear property can also be used, set as left|right|both. Float is only supported on block elements (i.e. not SPAN etc.) and is not fully compliant with the CSS specification.
+Float only works properly if a width is set for the float, otherwise the width is set to the maximum available (full width, or less if floats already set).
+
+Margin-right can still be set for a float:right and vice-versa.
+
+A block element next to a float has the padding adjusted so that content fits in the remaining width. Text next to a float should wrap correctly, but backgrounds and borders will overlap and/or lie under the floats in a mess.
+
+NB The width that is set defines the width of the content-box. So if you have two floats with width=50% and either of them has padding, margin or border, they will not fit together on the page.
+
+
+
+  This is text in a <div> element that is set to float:right and width:28%. It also has an image with float:right inside. With this exception, you cannot nest elements with the float property set inside one another.
+
+
+This is text in a <div> element that is set to float:left and width:54%.
+
+
+
+This is text that follows a <div> element that is set to clear:both.
+
+CSS "Position"
+At the bottom of the page are two DIV elements with position:fixed and position:absolute set
+
+1 Praesent pharetra nulla in turpis. Sed ipsum nulla, sodales nec, vulputate in, scelerisque vitae, magna. Praesent pharetra nulla in turpis. Sed ipsum nulla, sodales nec, vulputate in, scelerisque vitae, magna. Sed egestas justo nec ipsum. Nulla facilisi. Praesent sit amet pede quis metus aliquet vulputate. Donec luctus. Cras euismod tellus vel leo. Sed egestas justo nec ipsum. Nulla facilisi. Praesent sit amet pede quis metus aliquet vulputate. Donec luctus. Cras euismod tellus vel leo.
+
+2 Praesent pharetra nulla in turpis. Sed ipsum nulla, sodales nec, vulputate in, scelerisque vitae, magna. Sed egestas justo nec ipsum. Nulla facilisi. Praesent sit amet pede quis metus aliquet vulputate. Donec luctus. Cras euismod tellus vel leo.
+
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+include("../mpdf.php");
+
+$mpdf=new mPDF();
+
+$mpdf->SetDisplayMode('fullpage');
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+
+exit;
+
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example11_overflow_auto.php b/mpdf/examples/example11_overflow_auto.php
new file mode 100644
index 0000000..6fd990f
--- /dev/null
+++ b/mpdf/examples/example11_overflow_auto.php
@@ -0,0 +1,81 @@
+
+mPDF
+Fixed-position block element with Autofit
+Using the CSS properties position and overflow:auto it is possible to fit text to a single page:
+
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+
+ DIV: Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim.
+ DIV: Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim.
+
+Blockquote: Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus.
+
+Address: Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus.
+
+
+
+
+
+Styles - tt(teletype) italic bold big small emphasis strong new lines
+ code sample keyboard variable citation abbr. ACRONYM sup sub strike strike-s underline delete insert To be or not to be font changing face, size and color
+
+
+Paragraph using the in-line style to determine the font-size (15pt) and colour
+
+Testing BIG, SMALL, UNDERLINE, STRIKETHROUGH, FONT color, ACRONYM, SUPERSCRIPT and SUBSCRIPT
+This is strikethrough in block and small strikethrough in small span and big strikethrough in big span and then underline and strikethrough and sup but out of span again but blue font and ACRONYM text
+
+This is a green reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 then Strikethrough reference32-47 and strikethrough reference32-47
+
+Repeated in BIG: This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 but out of span again but blue font and ACRONYM text
+
+Repeated in small: This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 but out of span again but blue font and ACRONYM text
+
+The above repeated, but starting with a paragraph with font-size specified (7pt)
+
+This is strikethrough in block and small strikethrough in small span and then underline but out of span again but blue font and ACRONYM text
+
+This is strikethrough in block and big strikethrough in big span and then underline but out of span again but blue font and ACRONYM text
+
+This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 then Strikethrough reference32-47 and strikethrough reference32-47
+
+This tests underline and strikethrough when they are used together as they both use text-decoration
+
+Repeated in small: This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 but out of span again but blue font and ACRONYM text
+
+Repeated in BIG but with font-size set to 7pt by in-line css: This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 but out of span again but blue font and ACRONYM text
+
+Sed bibendum. Nunc eleifend ornare velit. Sed consectetuer urna in erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Mauris sodales semper metus. Maecenas justo libero, pretium at, malesuada eu, mollis et, arcu. Ut suscipit pede in nulla. Praesent elementum, dolor ac fringilla posuere, elit libero rutrum massa, vel tincidunt dui tellus a ante. Sed aliquet euismod dolor. Vestibulum sed dui. Duis lobortis hendrerit quam. Donec tempus orci ut libero. Pellentesque suscipit malesuada nisi.
+
+Praesent pharetra nulla in turpis. Sed ipsum nulla, sodales nec, vulputate in, scelerisque vitae, magna. Sed egestas justo nec ipsum. Nulla facilisi. Praesent sit amet pede quis metus aliquet vulputate. Donec luctus. Cras euismod tellus vel leo. Cras tellus. Fusce aliquet. Curabitur tincidunt viverra ligula. Fusce eget erat. Donec pede. Vestibulum id felis. Phasellus tincidunt ligula non pede. Morbi turpis. In vitae dui non erat placerat malesuada. Mauris adipiscing congue ante. Proin at erat. Aliquam mattis.
+
+
+';
+
+
+
+
+//==============================================================
+//==============================================================
+//==============================================================
+include("../mpdf.php");
+
+$mpdf=new mPDF('c');
+
+$mpdf->SetDisplayMode('fullpage');
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+
+exit;
+
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example12_paging_html.php b/mpdf/examples/example12_paging_html.php
new file mode 100644
index 0000000..44c5374
--- /dev/null
+++ b/mpdf/examples/example12_paging_html.php
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+| Left header p {PAGENO} |
+ |
+Right header |
+
+
+
+
+
+| Outer header |
+ |
+Inner header p {PAGENO} |
+
+
+
+
+
+
+
+
+
+
+
+Introduction
+Introduction
+Integer feugiat venenatis metus. Integer lacinia ultrices ipsum. Proin et arcu. Quisque varius libero. Nullam id arcu. Aenean justo quam, accumsan nec, luctus id, pellentesque molestie, mi. Aliquam sollicitudin feugiat eros. Nunc nisi turpis, consequat id, aliquet et, semper a, augue. Integer nisl ipsum, blandit et, lobortis a, egestas nec, odio. Nulla dolor ligula, nonummy ac, vulputate a, sollicitudin id, orci. Aenean turpis lorem, consequat quis, varius in, posuere vel, eros. Nulla facilisi.
+
+
+
+Section 2
+Section 2
+Integer feugiat venenatis metus. Integer lacinia ultrices ipsum. Proin et arcu. Quisque varius libero. Nullam id arcu. Aenean justo quam, accumsan nec, luctus id, pellentesque molestie, mi. Aliquam sollicitudin feugiat eros. Nunc nisi turpis, consequat id, aliquet et, semper a, augue. Integer nisl ipsum, blandit et, lobortis a, egestas nec, odio. Nulla dolor ligula, nonummy ac, vulputate a, sollicitudin id, orci. Donec laoreet nisl id magna. Curabitur mollis, quam eget fermentum malesuada, risus tortor ullamcorper dolor, nec placerat nisi urna non pede. Aliquam pretium, leo in interdum interdum, ipsum neque accumsan lectus, ac fringilla dui ipsum sed justo. In tincidunt risus convallis odio egestas luctus. Integer volutpat. Donec ultricies, leo in congue iaculis, dolor neque imperdiet nibh, vitae feugiat mi enim nec sapien. Aenean turpis lorem, consequat quis, varius in, posuere vel, eros. Nulla facilisi.
+
+
+
+Section 3
+Section 3
+Integer feugiat venenatis metus. Integer lacinia ultrices ipsum. Proin et arcu. Quisque varius libero. Nullam id arcu. Aenean justo quam, accumsan nec, luctus id, pellentesque molestie, mi. Aliquam sollicitudin feugiat eros. Nunc nisi turpis, consequat id, aliquet et, semper a, augue. Integer nisl ipsum, blandit et, lobortis a, egestas nec, odio. Nulla dolor ligula, nonummy ac, vulputate a, sollicitudin id, orci. Donec laoreet nisl id magna. Curabitur mollis, quam eget fermentum malesuada, risus tortor ullamcorper dolor, nec placerat nisi urna non pede. Aliquam pretium, leo in interdum interdum, ipsum neque accumsan lectus, ac fringilla dui ipsum sed justo. In tincidunt risus convallis odio egestas luctus. Integer volutpat. Donec ultricies, leo in congue iaculis, dolor neque imperdiet nibh, vitae feugiat mi enim nec sapien. Aenean turpis lorem, consequat quis, varius in, posuere vel, eros. Nulla facilisi.
+
+
+
+Section 4
+Section 4
+Integer feugiat venenatis metus. Integer lacinia ultrices ipsum. Proin et arcu. Quisque varius libero. Nullam id arcu. Aenean justo quam, accumsan nec, luctus id, pellentesque molestie, mi. Aliquam sollicitudin feugiat eros. Nunc nisi turpis, consequat id, aliquet et, semper a, augue. Integer nisl ipsum, blandit et, lobortis a, egestas nec, odio. Nulla dolor ligula, nonummy ac, vulputate a, sollicitudin id, orci. Donec laoreet nisl id magna. Curabitur mollis, quam eget fermentum malesuada, risus tortor ullamcorper dolor, nec placerat nisi urna non pede. Aliquam pretium, leo in interdum interdum, ipsum neque accumsan lectus, ac fringilla dui ipsum sed justo. In tincidunt risus convallis odio egestas luctus. Integer volutpat. Donec ultricies, leo in congue iaculis, dolor neque imperdiet nibh, vitae feugiat mi enim nec sapien. Aenean turpis lorem, consequat quis, varius in, posuere vel, eros. Nulla facilisi.
+
+
+
+
+
+Section 5
+Section 5
+Integer feugiat venenatis metus. Integer lacinia ultrices ipsum. Proin et arcu. Quisque varius libero. Nullam id arcu. Aenean justo quam, accumsan nec, luctus id, pellentesque molestie, mi. Aliquam sollicitudin feugiat eros. Nunc nisi turpis, consequat id, aliquet et, semper a, augue. Integer nisl ipsum, blandit et, lobortis a, egestas nec, odio. Nulla dolor ligula, nonummy ac, vulputate a, sollicitudin id, orci. Donec laoreet nisl id magna. Curabitur mollis, quam eget fermentum malesuada, risus tortor ullamcorper dolor, nec placerat nisi urna non pede. Aliquam pretium, leo in interdum interdum, ipsum neque accumsan lectus, ac fringilla dui ipsum sed justo. In tincidunt risus convallis odio egestas luctus. Integer volutpat. Donec ultricies, leo in congue iaculis, dolor neque imperdiet nibh, vitae feugiat mi enim nec sapien. Aenean turpis lorem, consequat quis, varius in, posuere vel, eros. Nulla facilisi.
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+include("../mpdf.php");
+$mpdf=new mPDF('c');
+
+$mpdf->mirrorMargins = true;
+
+$mpdf->SetDisplayMode('fullpage','two');
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+exit;
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example13_paging_css.php b/mpdf/examples/example13_paging_css.php
new file mode 100644
index 0000000..256a8a0
--- /dev/null
+++ b/mpdf/examples/example13_paging_css.php
@@ -0,0 +1,94 @@
+
+{PAGENO}
+
+
+{PAGENO}
+
+
+{PAGENO}
+
+
+{PAGENO}
+
+
+
+
+
+
+
+
+mPDF 1
+Paged Media using CSS
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin vel sem at odio varius pretium. Maecenas sed orci. Maecenas varius. Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin vel sem at odio varius pretium. Maecenas sed orci. Maecenas varius. Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+
+
+mPDF 2
+Paged Media using CSS
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin vel sem at odio varius pretium. Maecenas sed orci. Maecenas varius. Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin vel sem at odio varius pretium. Maecenas sed orci. Maecenas varius. Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin vel sem at odio varius pretium. Maecenas sed orci. Maecenas varius. Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+
+
+mPDF 3
+Paged Media using CSS
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin vel sem at odio varius pretium. Maecenas sed orci. Maecenas varius. Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin vel sem at odio varius pretium. Maecenas sed orci. Maecenas varius. Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin vel sem at odio varius pretium. Maecenas sed orci. Maecenas varius. Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+
+
+mPDF 4
+Paged Media using CSS
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin vel sem at odio varius pretium. Maecenas sed orci. Maecenas varius. Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin vel sem at odio varius pretium. Maecenas sed orci. Maecenas varius. Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+
+
+mPDF 5
+Paged Media using CSS
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin vel sem at odio varius pretium. Maecenas sed orci. Maecenas varius. Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin vel sem at odio varius pretium. Maecenas sed orci. Maecenas varius. Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin vel sem at odio varius pretium. Maecenas sed orci. Maecenas varius. Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+
+
+mPDF 6
+Paged Media using CSS
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin vel sem at odio varius pretium. Maecenas sed orci. Maecenas varius. Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin vel sem at odio varius pretium. Maecenas sed orci. Maecenas varius. Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin vel sem at odio varius pretium. Maecenas sed orci. Maecenas varius. Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+
+
+mPDF 7
+Paged Media using CSS
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin vel sem at odio varius pretium. Maecenas sed orci. Maecenas varius. Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin vel sem at odio varius pretium. Maecenas sed orci. Maecenas varius. Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+
+';
+//==============================================================
+//==============================================================
+//==============================================================
+include("../mpdf.php");
+
+$mpdf=new mPDF('c','A4','','',5,5,5,5,0,0);
+
+$mpdf->mirrorMargins = 1; // Use different Odd/Even headers and footers and mirror margins (1 or 0)
+
+$mpdf->SetDisplayMode('fullpage','two');
+
+// LOAD a stylesheet
+$stylesheet = file_get_contents('mpdfstylePaged.css');
+$mpdf->WriteHTML($stylesheet,1); // The parameter 1 tells that this is css/style only and no body/html/text
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+exit;
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example14_page_numbers_ToC_Index_Bookmarks.php b/mpdf/examples/example14_page_numbers_ToC_Index_Bookmarks.php
new file mode 100644
index 0000000..16e34f1
--- /dev/null
+++ b/mpdf/examples/example14_page_numbers_ToC_Index_Bookmarks.php
@@ -0,0 +1,155 @@
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin vel sem at odio varius pretium. Maecenas sed orci. Maecenas varius. Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui. ";
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+$html = '
+
+
+
+
+
+
+
+mPDF
+Table of Contents & Bookmarks
+
+
+
+
+';
+
+//==============================================================
+include("../mpdf.php");
+
+$mpdf=new mPDF('c','A4','','',32,25,27,25,16,13);
+
+$mpdf->mirrorMargins = 1;
+
+$mpdf->defaultPageNumStyle = 'i';
+
+$mpdf->SetDisplayMode('fullpage','two');
+
+// LOAD a stylesheet
+$stylesheet = file_get_contents('mpdfstyleA4.css');
+$mpdf->WriteHTML($stylesheet,1); // The parameter 1 tells that this is css/style only and no body/html/text
+
+$mpdf->WriteHTML($html);
+
+
+// Alternative ways to mark ToC entries and Bookmarks
+// This will automatically generate entries from the tag
+$mpdf->h2toc = array('H4'=>0);
+$mpdf->h2bookmarks = array('H4'=>0);
+
+//==============================================================
+// CONTENT
+for ($j = 1; $j<7; $j++) {
+ if ($j==2) $mpdf->WriteHTML('',2);
+ if ($j==3) $mpdf->WriteHTML('',2);
+ if ($j==4) $mpdf->WriteHTML('',2);
+ if ($j==5) $mpdf->WriteHTML('',2);
+ if ($j==6) $mpdf->WriteHTML('ODD ',2);
+ for ($x = 1; $x<7; $x++) {
+
+
+ $mpdf->WriteHTML('Section '.$j.'.'.$x.'',2);
+
+ $html = '';
+ // Split $lorem into words
+ $words = preg_split('/([\s,\.]+)/',$lorem,-1,PREG_SPLIT_DELIM_CAPTURE);
+ foreach($words as $i => $e) {
+ if($i%2==0) {
+ $y = rand(1,10); // every tenth word
+ // If it is just a word use it as an index entry
+ if (preg_match('/^[a-zA-Z]{4,99}$/',$e) && ($y > 8)) {
+ $content = trim($e);
+ $html .= '';
+ $html .= ''.$e . '';
+ }
+ else { $html .= $e; }
+ }
+ else { $html .= $e; }
+ }
+ $mpdf->WriteHTML($html);
+ }
+}
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// INDEX
+$html = '
+
+Index
+
+
+';
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+exit;
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example16_headers_method_2.php b/mpdf/examples/example16_headers_method_2.php
new file mode 100644
index 0000000..8ca966d
--- /dev/null
+++ b/mpdf/examples/example16_headers_method_2.php
@@ -0,0 +1,49 @@
+mirrorMargins = 1; // Use different Odd/Even headers and footers and mirror margins
+
+$header = '
+
+| Left header p {PAGENO} |
+ |
+Right header |
+
+';
+$headerE = '
+
+| Outer header |
+ |
+Inner header p {PAGENO} |
+
+';
+
+$footer = '';
+$footerE = '';
+
+
+$mpdf->SetHTMLHeader($header);
+$mpdf->SetHTMLHeader($headerE,'E');
+$mpdf->SetHTMLFooter($footer);
+$mpdf->SetHTMLFooter($footerE,'E');
+
+
+$html = '
+mPDF
+Headers & Footers Method 2
+Odd / Right page
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+
+Even / Left page
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+';
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+exit;
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example18_headers_method_4.php b/mpdf/examples/example18_headers_method_4.php
new file mode 100644
index 0000000..16e8bca
--- /dev/null
+++ b/mpdf/examples/example18_headers_method_4.php
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+mPDF
+Headers & Footers Method 4
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+
+
+Headers & Footers Method 4
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+
+
+
+
+Headers & Footers Method 4
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+
+include("../mpdf.php");
+
+$mpdf=new mPDF('c','A4','','',32,25,47,47,10,10);
+
+$mpdf->mirrorMargins = 1; // Use different Odd/Even headers and footers and mirror margins
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+exit;
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example19_page_sizes.php b/mpdf/examples/example19_page_sizes.php
new file mode 100644
index 0000000..6c3ca94
--- /dev/null
+++ b/mpdf/examples/example19_page_sizes.php
@@ -0,0 +1,59 @@
+
+ {PAGENO}
+
+
+ {PAGENO}
+
+
+
+';
+
+//==============================================================
+$html = '
+mPDF Page Sizes
+Changing page (sheet) sizes within the document
+';
+//==============================================================
+//==============================================================
+include("../mpdf.php");
+
+$mpdf=new mPDF('c','A4');
+
+$mpdf->WriteHTML($hhtml);
+
+$mpdf->WriteHTML($html);
+$mpdf->WriteHTML('This should print on an A4 (portrait) sheet ');
+
+$mpdf->WriteHTML('');
+$mpdf->WriteHTML($html);
+$mpdf->WriteHTML('This page appears just after the ToC and should print on an A4 (landscape) sheet ');
+
+$mpdf->WriteHTML('');
+$mpdf->WriteHTML($html);
+$mpdf->WriteHTML('This should print on an A5 (landscape) sheet ');
+
+$mpdf->WriteHTML('');
+$mpdf->WriteHTML($html);
+$mpdf->WriteHTML('This should print on an Letter sheet ');
+
+$mpdf->WriteHTML('');
+$mpdf->WriteHTML($html);
+$mpdf->WriteHTML('This should print on a sheet 150mm x 150mm ');
+
+$mpdf->WriteHTML('');
+$mpdf->WriteHTML($html);
+$mpdf->WriteHTML('This should print on a sheet 11.69in x 8.27in = A4 landscape ');
+
+
+$mpdf->Output();
+exit;
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example20_justify.php b/mpdf/examples/example20_justify.php
new file mode 100644
index 0000000..39c9e7f
--- /dev/null
+++ b/mpdf/examples/example20_justify.php
@@ -0,0 +1,130 @@
+mPDF
+Justification
+
+Tables
+Text can be justified in table cells using in-line or stylesheet CSS. (Note that <p> tags are removed within cells along with any style definition or attributes.)
+
+
+
+| Row header 1 |
+This is data |
+This is data |
+
+| Row header 2 |
+
+ This is data p
+ |
+
+ This is data
+ |
+
+|
+ Row header 3
+ |
+
+ This is long data
+ |
+This is data |
+
+|
+ Row header 4
+<th> cell acting as header
+ |
+Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. |
+
+ This is data
+ |
+
+| Row header 5 |
+Also data |
+Also data |
+
+| Row header 6 |
+Also data |
+Also data |
+
+| Row header 7 |
+Also data |
+Also data |
+
+| Row header 8 |
+Also data |
+Also data |
+
+
+
+
+Testing Justification with Long Words
+http://www-950.ibm.com/software/globalization/icu/demo/converters?s=ALL&snd=4356&dnd=4356
+Should not split
+Maecenas feugiat pede vel risus. Nulla et lectus eleifend verylongwordthatwontsplit neque sit amet erat
+Maecenas feugiat pede vel risus. Nulla et lectus eleifend et verylongwordthatwontsplit neque sit amet erat
+
+Non-breaking Space The next example has a non-breaking space between eleifend and the very long word. Maecenas feugiat pede vel risus. Nulla et lectus eleifend verylongwordthatwontsplitanywhere neque sit amet erat Nbsp will only work in fonts that have a glyph to represent the character i.e. not in the CJK languages nor some Unicode fonts.
+
+
+
+Testing Justification with mixed Styles
+This is strikethrough in block and small strikethrough in small span and big strikethrough in big span and then underline but out of span again but blue font and ACRONYM text
+This is a green reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 then Strikethrough reference32-47 and strikethrough reference32-47 and then more text.
+
+Repeated in BIG: This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 but out of span again but blue font and ACRONYM text
+
+Repeated in small: This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 but out of span again but blue font and ACRONYM text
+
+
+This is strikethrough in block and big strikethrough in big span and then underline but out of span again but blue font and ACRONYM text
+This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 then Strikethrough reference32-47 and strikethrough reference32-47 then more text.
+
+
+
+Repeated in BIG: This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 but out of span again but blue font and ACRONYM text
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+include("../mpdf.php");
+
+$mpdf=new mPDF('c','A4','','',32,25,27,25,16,13);
+
+$mpdf->SetDisplayMode('fullpage');
+
+// LOAD a stylesheet
+$stylesheet = file_get_contents('mpdfstyletables.css');
+$mpdf->WriteHTML($stylesheet,1); // The parameter 1 tells that this is css/style only and no body/html/text
+
+$mpdf->WriteHTML($html);
+
+// SPACING
+$mpdf->WriteHTML("SpacingmPDF uses both letter- and word-spacing for text justification. The default is a mixture of both, set by the configurable values jSWord and jSmaxChar. (Only word spacing is used when cursive languages such as Arabic or Indic are detected.) ");
+
+$mpdf->jSWord = 0; // Proportion (/1) of space (when justifying margins) to allocate to Word vs. Character
+$mpdf->jSmaxChar = 0; // Maximum spacing to allocate to character spacing. (0 = no maximum)
+$mpdf->WriteHTML("Character spacingMaecenas feugiat pede vel risus. Nulla et lectus eleifend verylongwordthatwontsplitanywhere neque sit amet erat ");
+
+// Back to default settings
+$mpdf->jSWord = 0.4;
+$mpdf->jSmaxChar = 2;
+$mpdf->WriteHTML("Word spacingMaecenas feugiat pede vel risus. Nulla et lectus eleifend verylongwordthatwontsplitanywhere neque sit amet erat ");
+
+$mpdf->WriteHTML("Mixed Character and Word spacingMaecenas feugiat pede vel risus. Nulla et lectus eleifend verylongwordthatwontsplitanywhere neque sit amet erat ");
+
+
+
+
+$mpdf->Output();
+exit;
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example21_hyphenation.php b/mpdf/examples/example21_hyphenation.php
new file mode 100644
index 0000000..ac51dfe
--- /dev/null
+++ b/mpdf/examples/example21_hyphenation.php
@@ -0,0 +1,39 @@
+Little Women
+Chapter One
+Playing Pilgrims
+
+ Christmas won\'t be Christmas without any presents, grumbled Jo, lying on the rug. It\'s so dreadful to be poor! sighed Meg, looking down at her old dress. I don\'t think it\'s fair for some girls to have plenty of pretty things, and other girls nothing at all, added little Amy, with an injured sniff. We\'ve got Father and Mother, and each other, said Beth contentedly from her corner. The four young faces on which the firelight shone brightened at the cheerful words, but darkened again as Jo said sadly, We haven\'t got Father, and shall not have him for a long time. She didn\'t say perhaps never, but each silently added it, thinking of Father far away, where the fighting was. Nobody spoke for a minute; then Meg said in an altered tone, You know the reason Mother proposed not having any presents this Christmas was because it is going to be a hard winter for everyone; and she thinks we ought not to spend money for pleasure, when our men are suffering so in the army. We can\'t do much, but we can make our little sacrifices, and ought to do it gladly. But I am afraid I don\'t And Meg shook her head, as she thought regretfully of all the pretty things she wanted. But I don\'t think the little we should spend would do any good. We\'ve each got a dollar, and the army wouldn\'t be much helped by our giving that. I agree not to expect anything from Mother or you, but I do want to buy UNDINE AND SINTRAM for myself. I\'ve wanted it so long, said Jo, who was a bookworm. I planned to spend mine in new music, said Beth, with a little sigh, which no one heard but the hearth brush and kettle holder. I shall get a nice box of Faber\'s drawing pencils. I really need them, said Amy decidedly. Mother didn\'t say anything about our money, and she won\'t wish us to give up everything. Let\'s each buy what we want, and have a little fun. I\'m sure we work hard enough to earn it, cried Jo, examining the heels of her shoes in a gentlemanly manner. I know I do—teaching those tiresome children nearly all day, when I\'m longing to enjoy myself at home, began Meg, in the complaining tone again. You don\'t have half such a hard time as I do, said Jo. How would you like to be shut up for hours with a nervous, fussy old lady, who keeps you trotting, is never satisfied, and worries you till you you\'re ready to fly out the window or cry? It\'s naughty to fret, but I do think washing dishes and keeping things tidy is the worst work in the world. It makes me cross, and my hands get so stiff, I can\'t practice well at all. And Beth looked at her rough hands with a sigh that any one could hear that time. I don\'t believe any of you suffer as I do, cried Amy, for you don\'t have to go to school with impertinent girls, who plague you if you don\'t know your lessons, and laugh at your dresses, and label your father if he isn\'t rich, and insult you when your nose isn\'t nice. If you mean libel, I\'d say so, and not talk about labels, as if Papa was a pickle bottle, advised Jo, laughing. I know what I mean, and you needn\'t be satirical about it. It\'s proper to use good words, and improve your vocabulary, returned Amy, with dignity. Don\'t peck at one another, children. Don\'t you wish we had the money Papa lost when we were little, Jo? Dear me! How happy and good we\'d be, if we had no worries! said Meg, who could remember better times. You said the other day you thought we were a deal happier than the King children, for they were fighting and fretting all the time, in spite of their money. So I did, Beth. Well, I think we are. For though we do have to work, we make fun of ourselves, and are a pretty jolly set, as Jo would say. Jo does use such slang words! observed Amy, with a reproving look at the long figure stretched on the rug. Jo immediately sat up, put her hands in her pockets, and began to whistle. Don\'t, Jo. It\'s so boyish! That\'s why I do it. I detest rude, unladylike girls! I hate affected, niminy-piminy chits! Birds in their little nests agree, sang Beth, the peacemaker, with such a funny face that both sharp voices softened to a laugh, and the pecking ended for that time. Really, girls, you are both to be blamed, said Meg, beginning to lecture in her elder-sisterly fashion. You are old enough to leave off boyish tricks, and to behave better, Josephine. It didn\'t matter so much when you were a little girl, but now you are so tall, and turn up your hair, you should remember that you are a young lady. I\'m not! And if turning up my hair makes me one, I\'ll wear it in two tails till I\'m twenty, cried Jo, pulling off her net, and shaking down a chestnut mane. I hate to think I\'ve got to grow up, and be Miss March, and wear long gowns, and look as prim as a China Aster! It\'s bad enough to be a girl, anyway, when I like boy\'s games and work and manners! I can\'t get over my disappointment in not being a boy. And it\'s worse than ever now, for I\'m dying to go and fight with Papa. And I can only stay home and knit, like a poky old woman! And Jo shook the blue army sock till the needles rattled like castanets, and her ball bounded across the room. Poor Jo! It\'s too bad, but it can\'t be helped. So you must try to be contented with making your name boyish, and playing brother to us girls, said Beth, stroking the rough head with a hand that all the dish washing and dusting in the world could not make ungentle in its touch. As for you, Amy, continued Meg, you are altogether to particular and prim. Your airs are funny now, but you\'ll grow up an affected little goose, if you don\'t take care. I I like your nice manners and refined ways of speaking, when you don\'t try to be elegant. But your absurd words are as bad as Jo\'s slang. If Jo is a tomboy and Amy a goose, what am I, please? asked Beth, ready to share the lecture. You\'re a dear, and nothing else, answered Meg warmly, and no one contradicted her, for the `Mouse\' was the pet of the family. As young readers like to know `how people look\', we will take this moment to give them a little sketch of the four sisters, who sat knitting away in the twilight, while the December snow fell quietly without, and the fire crackled cheerfully within. It was a comfortable room, though the carpet was faded and the furniture very plain, for a good picture or two hung on the walls, books filled the recesses, chrysanthemums and Christmas roses bloomed in the windows, and a pleasant atmosphere of home peace pervaded it. Margaret, the eldest of the four, was sixteen, and very pretty, being plump and fair, with large eyes, plenty of soft brown hair, a sweet mouth, and white hands, of which she was rather vain. Fifteen-year-old Jo was very tall, thin, and brown, and reminded one of a colt, for she never seemed to know what to do with her long limbs, which were very much in her way. She had a decided mouth, a comical nose, and sharp, gray eyes, which appeared to see everything, and were by turns fierce, funny, or thoughtful. Her long, thick hair was her one beauty, but it was usually bundled into a net, to be out of her way. Round shoulders had Jo, big hands and feet, a fly-away look to her clothes, and the uncomfortable appearance of a girl who was rapidly shooting up into a woman and didn\'t like it. Elizabeth, or Beth, as everyone called her, was a rosy, smooth-haired, bright-eyed girl of thirteen, with a shy manner, a timid voice, and a peaceful expression which was seldom disturbed. Her father called her `Little Miss Tranquillity\', and the name suited her excellently, for she seemed to live in a happy world of her own, only venturing out to meet the few whom she trusted and loved. Amy, though the youngest, was a most important person, in her own opinion at least. A regular snow maiden, with blue eyes, and yellow hair curling on her shoulders, pale and slender, and always carrying herself like a young lady mindful of her manners. What the characters of the four sisters were we will leave to be found out. The clock struck six and, having swept up the hearth, Beth put a pair of slippers down to warm. Somehow the sight of the old shoes had a good effect upon the girls, for Mother was coming, and everyone brightened to welcome her. Meg stopped lecturing, and lighted the lamp, Amy got out of the easy chair without being asked, and Jo forgot how tired she was as she sat up to hold the slippers nearer to the blaze. They are quite worn out. Marmee must have a new pair. I thought I\'d get her some with my dollar, said Beth. No, I shall! cried Amy. I\'m the oldest, began Meg, but Jo cut in with a decided, I\'m the man of the family now Papa is away, and I shall provide the slippers, for he told me to take special care of Mother while he was gone. I\'ll tell you what we\'ll do, said Beth, let\'s each get her something for Christmas, and not get anything for ourselves. That\'s like you, dear! What will we get? exclaimed Jo. Everyone thought soberly for a minute, then Meg announced, as if the idea was suggested by the sight of her own pretty hands, I shall give her a nice pair of gloves. Army shoes, best to be had, cried Jo. Some handkerchiefs, all hemmed, said Beth. I\'ll get a little bottle of cologne. She likes it, and it won\'t cost much, so I\'ll have some left to buy my pencils, added Amy. How will we give the things? asked Meg. Put them on the table, and bring her in and see her open the bundles. Don\'t you remember how we used to do on our birthdays? answered Jo. I used to be so frightened when it was my turn to sit in the chair with the crown on, and see you all come marching round to give the presents, with a kiss. I liked the things and the kisses, but it was dreadful to have you sit looking at me while I opened the bundles, said Beth, who was toasting her face and the bread for tea at the same time. Let Marmee think we are getting things for ourselves, and then surprise her. We must go shopping tomorrow afternoon, Meg. There is so much to do about the play for Christmas night, said Jo, marching up and down, with her hands behind her back, and her nose in the air. I don\'t mean to act any more after this time. I\'m getting too old for such things, observed Meg, who was as much a child as ever about `dressing-up\' frolics. You won\'t stop, I know, as long as you can trail round in a white gown with your hair down, and wear gold-paper jewelry. You are the best actress we\'ve got, and there\'ll be an end of everything if you quit the boards, said Jo. We ought to rehearse tonight. Come here, Amy, and do the fainting scene, for you are as stiff as a poker in that. I can\'t help it. I never saw anyone faint, and I don\'t choose to make myself all black and blue, tumbling flat as you do. If I can go down easily, I\'ll drop. If I can\'t, I shall fall into a chair and be graceful. I don\'t care if Hugo does come at me with a pistol, returned Amy, who was not gifted with dramatic power, but was chosen because she was small enough to be borne out shrieking by the villain of the piece. Do it this way. Clasp your hands so, and stagger across the room, crying frantically, `Roderigo` Save me! Save me! and away went Jo, with a melodramatic scream which was truly thrilling. Amy followed, but she poked her hands out stiffly before her, and jerked herself along as if she went by machinery, and her Ow! was more suggestive of pins being run into her than of fear and anguish. Jo gave a despairing groan, and Meg laughed outright, while Beth let her bread burn as she watched the fun with interest. It\'s no use! Do the best you can when the time comes, and if the audience laughs, don\'t blame me. Come on, Meg. Then things went smoothly, for Don Pedro defied the world in a speech of two pages without a single break. Hagar, the witch, chanted an awful incantation over her kettleful of simmering toads, with weird effect. Roderigo rent his chains asunder manfully, and Hugo died in agonies of remorse and arsenic, with a wild, Ha! Ha! It\'s the best we\'ve had yet, said Meg, as the dead villain sat up and rubbed his elbows. I don\'t see how you can write and act such splendid things, Jo. You\'re a regular Shakespeare! exclaimed Beth, who firmly believed that her sisters were gifted with wonderful genius in all things. Not quite, replied Jo modestly. I do think THE WITCHES CURSE, an Operatic Tragedy is rather a nice thing, but I\'d like to try MacBETH, if we only had a trapdoor for Banquo. I always wanted to do the killing part. `Is that a dagger that I see before me? muttered Jo, rolling her eyes and clutching at the air, as she had seen a famous tragedian do. No, it\'s the toasting fork, with Mother\'s shoe on it instead of the bread. Beth\'s stage-struck! cried Meg, and the rehearsal ended in a general burst of laughter. Glad to find you so merry, my girls, said a cheery voice at the door, and actors and audience turned to welcome a tall, motherly lady with a `can I help you\' look about her which was truly delightful. She was not elegantly dressed, but a noble-looking woman, and the girls thought the gray cloak and unfashionable bonnet covered the most splendid mother in the world. Well, dearies, how have you got on today? There was so much to do, getting the boxes ready to go tomorrow, that I didn\'t come home to dinner. Has anyone called, Beth? How is your cold, Meg? Jo, you look tired to death. Come and kiss me, baby. While making these maternal inquiries Mrs. March got her wet things off, her warm slippers on, and sitting down in the easy chair, drew Amy to her lap, preparing to enjoy the happiest hour of her busy day. The girls flew about, trying to make things comfortable, each in her own way. Meg arranged the tea table, Jo brought wood and set chairs, dropping, over-turning, and clattering everything she touched. Beth trotted to and fro between parlor kitchen, quiet and busy, while Amy gave directions to everyone, as she sat with her hands folded. As they gathered about the table, Mrs. March said, with a particularly happy face, I\'ve got a treat for you after supper. A quick, bright smile went round like a streak of sunshine. Beth clapped her hands, regardless of the biscuit she held, and Jo tossed up her napkin, crying, A letter! A letter! Three cheers for Father! Yes, a nice long letter. He is well, and thinks he shall get through the cold season better than we feared. He sends all sorts of loving wishes for Christmas, and an especial message to you girls, said Mrs. March, patting her pocket as if she had got a treasure there. Hurry and get done! Don\'t stop to quirk your little finger and simper over your plate, Amy, cried Jo, choking on her tea and dropping her bread, butter side down, on the carpet in her haste to get at the treat. Beth ate no more, but crept away to sit in her shadowy corner and brood over the delight to come, till the others were ready. I think it was so splendid in Father to go as chaplain when he was too old to be drafted, and not strong enough for a soldier, said Meg warmly. Don\'t I wish I could go as a drummer, a vivan—what\'s its name? Or a nurse, so I could be near him and help him, exclaimed Jo, with a groan. It must be very disagreeable to sleep in a tent, and eat all sorts of bad-tasting things, and drink out of a tin mug, sighed Amy. When will he come home, Marmee? asked Beth, with a little quiver in her voice. Not for many months, dear, unless he is sick. He will stay and do his work faithfully as long as he can, and we won\'t ask for him back a minute sooner than he can be spared. Now come and hear the letter. They all drew to the fire, Mother in the big chair with Beth at her feet, Meg and Amy perched on either arm of the chair, and Jo leaning on the back, where no one would see any sign of emotion if the letter should happen to be touching. Very few letters were written in those hard times that were not touching, especially those which fathers sent home. In this one little was said of the hardships endured, the dangers faced, or the homesickness conquered. It was a cheerful, hopeful letter, full of lively descriptions of camp life, marches, and military news, and only at the end did the writer\'s heart over-flow with fatherly love and longing for the little girls at home. Give them all of my dear love and a kiss. Tell them I think of them by day, pray for them by night, and find my best comfort in their affection at all times. A year seems very long to wait before I see them, but remind them that while we wait we may all work, so that these hard days need not be wasted. I know they will remember all I said to them, that they will be loving children to you, will do their duty faithfully, fight their bosom enemies bravely, and conquer themselves so beautifully that when I come back to them I may be fonder and prouder than ever of my little women. Everybody sniffed when they came to that part. Jo wasn\'t ashamed of the great tear that dropped off the end of her nose, and Amy never minded the rumpling of her curls as she hid her face on her mother\'s shoulder and sobbed out, I am a selfish girl! But I\'ll truly try to be better, so he mayn\'t be disappointed in me by-and-by. We all will, cried Meg. I think too much of my looks and hate to work, but won\'t any more, if I can help it. I\'ll try and be what he loves to call me, `a little woman\' and not be rough and wild, but do my duty here instead of wanting to be somewhere else, said Jo, thinking that keeping her temper at home was a much harder task than facing a rebel or two down South. Beth said nothing, but wiped away her tears with the blue army sock and began to knit with all her might, losing no time in doing the duty that lay nearest her, while she resolved in her quiet little soul to be all that Father hoped to find her when the year brought round the happy coming home. Mrs. March broke the silence that followed Jo\'s words, by saying in her cheery voice, Do you remember how you used to play Pilgrims Progress when you were little things? Nothing delighted you more than to have me tie my piece bags on your backs for burdens, give you hats and sticks and rolls of paper, and let you travel through the house from the cellar, which was the City of Destruction, up, up, to the housetop, where you had all the lovely things you could collect to make a Celestial City. What fun it was, especially going by the lions, fighting Apollyon, and passing through the valley where the hob-goblins were, said Jo. I liked the place where the bundles fell off and tumbled downstairs, said Meg. I don\'t remember much about it, except that I was afraid of the cellar and the dark entry, and always liked the cake and milk we had up at the top. If I wasn\'t too old for such things, I\'d rather like to play it over again, said Amy, who began to talk of renouncing childish things at the mature age of twelve. We never are too old for this, my dear, because it is a play we are playing all the time in one way or another. Out burdens are here, our road is before us, and the longing for goodness and happiness is the guide that leads us through many troubles and mistakes to the peace which is a true Celestial City. Now, my little pilgrims, suppose you begin again, not in play, but in earnest, and see how far on you can get before Father comes home. Really, Mother? Where are our bundles? asked Amy, who was a very literal young lady. Each of you told what your burden was just now, except Beth. I rather think she hasn\'t got any, said her mother. Yes, I have. Mine is dishes and dusters, and envying girls with nice pianos, and being afraid of people. Beth\'s bundle was such a funny one that everybody wanted to laugh, but nobody did, for it would have hurt her feelings very much. Let us do it, said Meg thoughtfully. It is only another name for trying to be good, and the story may help us, for though we do want to be good, it\'s hard work and we forget, and don\'t do our best. We were in the Slough of Despond tonight, and Mother came and pulled us out as Help did in the book. We ought to have our roll of directions, like Christian. What shall we do about that? asked Jo, delighted with the fancy which lent a little romance to the very dull task of doing her duty. Look under your pillows Christmas morning, and you will find your guidebook, replied Mrs. March. They talked over the new plan while old Hannah cleared the table, then out came the four little work baskets, and the needles flew as the girls made sheets for Aunt March. It was uninteresting sewing, but tonight no one grumbled. They adopted Jo\'s plan of dividing the long seams into four parts, and calling the quarters Europe, Asia, Africa, and America, and in that way got on capitally, especially when they talked about the different countries as they stitched their way through them. At nine they stopped work, and sang, as usual, before they went to bed. No one but Beth could get much music out of the old piano, but she had a way of softly touching the yellow keys and making a pleasant accompaniment to the simple songs they sang. Meg had a voice like a flute, and she and her mother led the little choir. Amy chirped like a cricket, and Jo wandered through the airs at her own sweet will, always coming out at the wrong place with a croak or a quaver that spoiled the most pensive tune. They had always done this from the time they could lisp . . . Crinkle, crinkle, \'ittle \'tar, and it had become a household custom,, for the mother was a born singer. The first sound in the morning was her voice as she went about the house singing like a lark, and the last sound at night was the same cheery sound, for the girls never grew too old for that familiar lullaby.';
+
+//==============================================================
+//==============================================================
+//==============================================================
+include("../mpdf.php");
+
+$mpdf=new mPDF('','A4','','',32,25,27,25,16,13);
+
+$mpdf->SetDisplayMode('fullpage');
+
+// LOAD a stylesheet
+$stylesheet = file_get_contents('mpdfstyleA4.css');
+$stylesheet .= '
+p { hyphens: auto; }
+';
+$mpdf->WriteHTML($stylesheet,1);
+
+$mpdf->WriteHTML(' Automatic Hyphenation');
+
+$mpdf->SetColumns(4,'J');
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+exit;
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example22_columns.php b/mpdf/examples/example22_columns.php
new file mode 100644
index 0000000..6b9aac5
--- /dev/null
+++ b/mpdf/examples/example22_columns.php
@@ -0,0 +1,80 @@
+mPDF
+Columns
+';
+//==============================================================
+
+$loremH = "Lectus facilisis
+Sed auctor viverra diam. In lacinia lectus.
+Praesent tincidunt massa in dolor. Morbi viverra leo quis ipsum. In vitae velit. In aliquam nulla nec mi. Sed accumsan, justo id congue fringilla, diam mauris volutpat ligula, sed aliquet elit diam at felis. Quisque et velit sed eros convallis posuere.
+Nunc tincidunt
+Nunc diam ipsum, consectetuer nec, hendrerit vitae, malesuada a, ante. Nulla ornare aliquet ante. Maecenas in lectus. Morbi porttitor mauris. Praesent ut.
+Pede quis ante tincidunt blandit. Maecenas bibendum erat. Curabitur sit amet ante quis velit ultricies facilisis. Ut hendrerit dolor commodo magna. In nec ligula a purus tincidunt adipiscing. Etiam non ante. Suspendisse potenti. Suspendisse accumsan euismod lectus. Nunc commodo pede et turpis. Pellentesque porta mauris sed lorem. Ut nec augue vitae elit eleifend eleifend.Quisque ornare feugiat diam. Duis nulla metus, tempus sit amet, scelerisque a, rutrum at, nisl. Nulla facilisi. Duis metus turpis, molestie nec, laoreet tincidunt, ultrices et, purus. Nullam faucibus aliquam nisi.  Ut leo. Etiam tempus interdum tortor. Donec porta, arcu vel tincidunt placerat, lacus lorem iaculis diam, id sagittis sapien metus eu nunc. Morbi vitae nunc. Mauris sapien. Phasellus elementum velit sed sapien. Nullam ante diam, consectetuer commodo, dignissim vitae, tempor vel, magna. Donec dictum. Nullam ultrices leo volutpat magna. Mauris blandit purus nec turpis. Curabitur nunc. Aliquam condimentum eleifend32 lectus. Praesent vitae nibh et libero ullamcorper scelerisque. Nullam auctor. Mauris ipsum nulla, malesuada id, aliquet at, feugiat vitae, eros.
+
+Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede.
+ Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim.
+ Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim.
+Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+";
+
+
+
+//==============================================================
+//==============================================================
+//==============================================================
+include("../mpdf.php");
+
+$mpdf=new mPDF('c','A4','','',32,25,27,25,16,13);
+
+$mpdf->SetDisplayMode('fullpage');
+
+$stylesheet = file_get_contents('mpdfstyleA4.css');
+$mpdf->WriteHTML($stylesheet,1); // The parameter 1 tells that this is css/style only and no body/html/text
+
+// Bullets in columns are probably best not indented
+$mpdf->list_indent_first_level = 0; // 1 or 0 - whether to indent the first level of a list
+
+$mpdf->max_colH_correction = 1.1;
+
+
+ $mpdf->WriteHTML($html,2);
+ $mpdf->WriteHTML($loremH,2);
+
+ // consider reducing lineheight when using columns - especially if vAligned justify
+ $mpdf->SetDefaultBodyCSS('line-height', 1.2);
+
+ $mpdf->SetColumns(3,'J');
+ $mpdf->WriteHTML($loremH,2);
+
+ $mpdf->SetColumns(0);
+ $mpdf->WriteHTML(' ');
+
+
+ $mpdf->SetColumns(2,'J');
+ $mpdf->WriteHTML($loremH,2);
+ $mpdf->WriteHTML(' ');
+ $mpdf->SetColumns(0);
+ $mpdf->WriteHTML(' ');
+
+ $mpdf->SetColumns(3,'J');
+ $mpdf->WriteHTML($loremH,2);
+
+ $mpdf->SetColumns(0);
+ $mpdf->WriteHTML(' ');
+ $mpdf->SetColumns(2,'J');
+ $mpdf->WriteHTML($loremH,2);
+
+
+
+$mpdf->Output();
+exit;
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example23_orientation.php b/mpdf/examples/example23_orientation.php
new file mode 100644
index 0000000..88ecb2b
--- /dev/null
+++ b/mpdf/examples/example23_orientation.php
@@ -0,0 +1,132 @@
+mPDF
+Page Orientation
+
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+
+
+Sed bibendum. Nunc eleifend ornare velit. Sed consectetuer urna in erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Mauris sodales semper metus. Maecenas justo libero, pretium at, malesuada eu, mollis et, arcu. Ut suscipit pede in nulla. Praesent elementum, dolor ac fringilla posuere, elit libero rutrum massa, vel tincidunt dui tellus a ante. Sed aliquet euismod dolor. Vestibulum sed dui. Duis lobortis hendrerit quam. Donec tempus orci ut libero. Pellentesque suscipit malesuada nisi.
+Praesent pharetra nulla in turpis. Sed ipsum nulla, sodales nec, vulputate in, scelerisque vitae, magna. Sed egestas justo nec ipsum. Nulla facilisi. Praesent sit amet pede quis metus aliquet vulputate. Donec luctus. Cras euismod tellus vel leo. Cras tellus. Fusce aliquet. Curabitur tincidunt viverra ligula. Fusce eget erat. Donec pede. Vestibulum id felis. Phasellus tincidunt ligula non pede. Morbi turpis. In vitae dui non erat placerat malesuada. Mauris adipiscing congue ante. Proin at erat. Aliquam mattis.
+Integer feugiat venenatis metus. Integer lacinia ultrices ipsum. Proin et arcu. Quisque varius libero. Nullam id arcu. Aenean justo quam, accumsan nec, luctus id, pellentesque molestie, mi. Aliquam sollicitudin feugiat eros. Nunc nisi turpis, consequat id, aliquet et, semper a, augue. Integer nisl ipsum, blandit et, lobortis a, egestas nec, odio. Nulla dolor ligula, nonummy ac, vulputate a, sollicitudin id, orci. Donec laoreet nisl id magna. Curabitur mollis, quam eget fermentum malesuada, risus tortor ullamcorper dolor, nec placerat nisi urna non pede. Aliquam pretium, leo in interdum interdum, ipsum neque accumsan lectus, ac fringilla dui ipsum sed justo. In tincidunt risus convallis odio egestas luctus. Integer volutpat. Donec ultricies, leo in congue iaculis, dolor neque imperdiet nibh, vitae feugiat mi enim nec sapien. Aenean turpis lorem, consequat quis, varius in, posuere vel, eros. Nulla facilisi.
+
+
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+
+include("../mpdf.php");
+
+
+$mpdf=new mPDF('c','A4','','',42,15,67,67,20,15);
+
+$mpdf->SetDisplayMode('fullpage','two');
+
+$mpdf->mirrorMargins = 1;
+
+
+$header = '
+
+| Left header p {PAGENO} |
+ |
+Right header |
+
+';
+$headerE = '
+
+| Outer header |
+ |
+Inner header p {PAGENO} |
+
+';
+$longfooter = '
+
+| Left footer p {PAGENO} |
+ |
+Right footer |
+
+';
+$longfooterE = '
+
+| Outer footer |
+ |
+Inner footer p {PAGENO} |
+
+';
+
+$footer = '{DATE j-m-Y} » {PAGENO} » My document ';
+$footerE = 'Even page footer - {PAGENO} - ';
+
+$shortheader = '{DATE j-m-Y} » {PAGENO} » My document ';
+$shortheaderE = 'Even page header - {PAGENO} - ';
+
+
+$mpdf->SetHTMLHeader($header);
+$mpdf->SetHTMLHeader($headerE,'E');
+$mpdf->setFooter('{PAGENO} of {nbpg} pages||{PAGENO} of {nbpg} pages') ;
+
+
+$mpdf->WriteHTML($html);
+
+
+$mpdf->setHeader(); // Clear headers before adding page
+$mpdf->AddPage('L','','','','',25,25,55,45,18,12);
+
+$mpdf->SetHTMLHeader($shortheader,'',true); // New parameter in v1.4 to add the header to the new page
+$mpdf->SetHTMLHeader($shortheaderE,'E',true);
+$mpdf->SetHTMLFooter($longfooter);
+$mpdf->SetHTMLFooter($longfooterE,'E');
+
+
+$mpdf->WriteHTML($html);
+$mpdf->WriteHTML($html);
+$mpdf->WriteHTML($html);
+
+
+
+$mpdf->setHeader('{PAGENO} of {nbpg} pages||{PAGENO} of {nbpg} pages') ;
+$mpdf->SetHTMLFooter($footer);
+$mpdf->SetHTMLFooter($footerE,'E');
+
+
+$mpdf->WriteHTML($html);
+$mpdf->WriteHTML($html);
+
+
+$mpdf->setHeader(); // Clear headers before adding page
+$mpdf->AddPage('','','','','',42,15,67,67,20,15); // Default is Portrait (because that was the document default)
+
+
+$mpdf->SetHTMLHeader($shortheader,'',true); // true adds the header to the new page
+$mpdf->SetHTMLHeader($shortheaderE,'E',true);
+$mpdf->SetHTMLFooter($longfooter);
+$mpdf->SetHTMLFooter($longfooterE,'E');
+
+
+$mpdf->WriteHTML($html);
+$mpdf->WriteHTML($html);
+
+
+$mpdf->SetHTMLHeader($header);
+$mpdf->SetHTMLHeader($headerE,'E');
+$mpdf->SetHTMLFooter($footer);
+$mpdf->SetHTMLFooter($footerE,'E');
+
+
+$mpdf->WriteHTML($html);
+$mpdf->WriteHTML($html);
+
+
+$mpdf->Output('mpdf.pdf','I');
+exit;
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example24_orientation_2.php b/mpdf/examples/example24_orientation_2.php
new file mode 100644
index 0000000..1cbbfda
--- /dev/null
+++ b/mpdf/examples/example24_orientation_2.php
@@ -0,0 +1,200 @@
+mPDF
+Page Orientation
+
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+
+
+Sed bibendum. Nunc eleifend ornare velit. Sed consectetuer urna in erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Mauris sodales semper metus. Maecenas justo libero, pretium at, malesuada eu, mollis et, arcu. Ut suscipit pede in nulla. Praesent elementum, dolor ac fringilla posuere, elit libero rutrum massa, vel tincidunt dui tellus a ante. Sed aliquet euismod dolor. Vestibulum sed dui. Duis lobortis hendrerit quam. Donec tempus orci ut libero. Pellentesque suscipit malesuada nisi.
+Praesent pharetra nulla in turpis. Sed ipsum nulla, sodales nec, vulputate in, scelerisque vitae, magna. Sed egestas justo nec ipsum. Nulla facilisi. Praesent sit amet pede quis metus aliquet vulputate. Donec luctus. Cras euismod tellus vel leo. Cras tellus. Fusce aliquet. Curabitur tincidunt viverra ligula. Fusce eget erat. Donec pede. Vestibulum id felis. Phasellus tincidunt ligula non pede. Morbi turpis. In vitae dui non erat placerat malesuada. Mauris adipiscing congue ante. Proin at erat. Aliquam mattis.
+Integer feugiat venenatis metus. Integer lacinia ultrices ipsum. Proin et arcu. Quisque varius libero. Nullam id arcu. Aenean justo quam, accumsan nec, luctus id, pellentesque molestie, mi. Aliquam sollicitudin feugiat eros. Nunc nisi turpis, consequat id, aliquet et, semper a, augue. Integer nisl ipsum, blandit et, lobortis a, egestas nec, odio. Nulla dolor ligula, nonummy ac, vulputate a, sollicitudin id, orci. Donec laoreet nisl id magna. Curabitur mollis, quam eget fermentum malesuada, risus tortor ullamcorper dolor, nec placerat nisi urna non pede. Aliquam pretium, leo in interdum interdum, ipsum neque accumsan lectus, ac fringilla dui ipsum sed justo. In tincidunt risus convallis odio egestas luctus. Integer volutpat. Donec ultricies, leo in congue iaculis, dolor neque imperdiet nibh, vitae feugiat mi enim nec sapien. Aenean turpis lorem, consequat quis, varius in, posuere vel, eros. Nulla facilisi.
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+
+
+';
+
+$htmlL = '
+Table in Landscape
+
+
+
+| Type |
+Details |
+Notes |
+
+
+
+| Causes |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit.
+Ut a eros at ligula vehicula pretium; maecenas feugiat pede vel risus.
+Suspendisse potenti. Fusce eleifend neque sit amet erat.
+Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. |
+
+
+| Mechanisms |
+Fusce eleifend neque sit amet erat.
+Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. |
+Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla.
+Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. |
+
+
+| Causes |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit.
+Ut a eros at ligula vehicula pretium; maecenas feugiat pede vel risus.
+Suspendisse potenti. Fusce eleifend neque sit amet erat.
+Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. |
+
+
+| Mechanisms |
+Fusce eleifend neque sit amet erat.
+Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. |
+Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla.
+Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. |
+
+
+| Causes |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit.
+Ut a eros at ligula vehicula pretium; maecenas feugiat pede vel risus.
+Suspendisse potenti. Fusce eleifend neque sit amet erat.
+Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. |
+
+
+| Mechanisms |
+Fusce eleifend neque sit amet erat.
+Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. |
+Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla.
+Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. |
+
+
+| Causes |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit.
+Ut a eros at ligula vehicula pretium; maecenas feugiat pede vel risus.
+Suspendisse potenti. Fusce eleifend neque sit amet erat.
+Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. |
+
+
+| Mechanisms |
+Fusce eleifend neque sit amet erat.
+Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. |
+Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla.
+Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. |
+
+
+| Causes |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit.
+Ut a eros at ligula vehicula pretium; maecenas feugiat pede vel risus.
+Suspendisse potenti. Fusce eleifend neque sit amet erat.
+Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. |
+
+
+| Mechanisms |
+Fusce eleifend neque sit amet erat.
+Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. |
+Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla.
+Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. |
+
+
+';
+
+//==============================================================
+
+$loremH = "Lectus facilisis
+Sed auctor viverra diam. In lacinia lectus.
+Praesent tincidunt massa in dolor. Morbi viverra leo quis ipsum. In vitae velit. In aliquam nulla nec mi. Sed accumsan, justo id congue fringilla, diam mauris volutpat ligula, sed aliquet elit diam at felis. Quisque et velit sed eros convallis posuere.
+Nunc tincidunt
+Nunc diam ipsum, consectetuer nec, hendrerit vitae, malesuada a, ante. Nulla ornare aliquet ante. Maecenas in lectus. Morbi porttitor mauris. Praesent ut.
+Pede quis ante tincidunt blandit. Maecenas bibendum erat. Curabitur sit amet ante quis velit ultricies facilisis. Ut hendrerit dolor commodo magna. In nec ligula a purus tincidunt adipiscing. Etiam non ante. Suspendisse potenti. Suspendisse accumsan euismod lectus. Nunc commodo pede et turpis. Pellentesque porta mauris sed lorem. Ut nec augue vitae elit eleifend eleifend. Quisque ornare feugiat diam. Duis nulla metus, tempus sit amet, scelerisque a, rutrum at, nisl. Nulla facilisi. Duis metus turpis, molestie nec, laoreet tincidunt, ultrices et, purus. Nullam faucibus aliquam nisi. ![]() Ut leo. Etiam tempus interdum tortor. Donec porta, arcu vel tincidunt placerat, lacus lorem iaculis diam, id sagittis sapien metus eu nunc. Morbi vitae nunc. Mauris sapien. Phasellus elementum velit sed sapien. Nullam ante diam, consectetuer commodo, dignissim vitae, tempor vel, magna. Donec dictum. Nullam ultrices leo volutpat magna. Mauris blandit purus nec turpis. Curabitur nunc. Aliquam condimentum eleifend32 lectus. Praesent vitae nibh et libero ullamcorper scelerisque. Nullam auctor. Mauris ipsum nulla, malesuada id, aliquet at, feugiat vitae, eros.
+
+Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras eu erat vel libero sodales congue. Sed erat est, interdum nec, elementum eleifend, pretium at, nibh. Praesent massa diam, adipiscing id, mollis sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor. Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem, ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+";
+
+//==============================================================
+$header = '
+
+| Left header p {PAGENO} |
+ |
+Right header |
+
+';
+$headerE = '
+
+| Outer header |
+ |
+Inner header p {PAGENO} |
+
+';
+$header = '';
+$headerE = 'Even page footer - {PAGENO} - My document My document My document ';
+$footer = '';
+$footerE = 'Even page footer - {PAGENO} - My document My document My document ';
+
+//==============================================================
+//==============================================================
+//==============================================================
+
+include("../mpdf.php");
+
+
+$mpdf=new mPDF('c','A4','','',42,15,57,57,20,17);
+
+$mpdf->displayDefaultOrientation = true;
+
+$mpdf->forcePortraitHeaders = true;
+$mpdf->forcePortraitMargins = true;
+
+$mpdf->SetDisplayMode('fullpage','two');
+
+$mpdf->mirrorMargins = 1;
+
+$stylesheet = file_get_contents('mpdfstyletables.css');
+$mpdf->WriteHTML($stylesheet,1);
+
+$mpdf->SetHTMLHeader($header);
+$mpdf->SetHTMLHeader($headerE,'E');
+$mpdf->SetHTMLFooter($footer);
+$mpdf->SetHTMLFooter($footerE,'E');
+
+$mpdf->WriteHTML($html);
+
+$mpdf->AddPage('L');
+
+$mpdf->WriteHTML($htmlL);
+$mpdf->WriteHTML($htmlL);
+
+// Columns
+$mpdf->AddPage('L');
+$mpdf->SetColumns(3,'J');
+$mpdf->WriteHTML($loremH);
+
+$mpdf->SetColumns(0);
+$mpdf->WriteHTML(' ');
+
+
+$mpdf->SetColumns(2,'J');
+$mpdf->WriteHTML($loremH);
+$mpdf->WriteHTML(' ');
+$mpdf->SetColumns(0);
+
+$mpdf->AddPage('L');
+
+$mpdf->WriteHTML($htmlL);
+$mpdf->WriteHTML($htmlL);
+
+$mpdf->AddPage();
+
+$mpdf->WriteHTML($html);
+$mpdf->WriteHTML($html);
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+exit;
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example26_RTL.php b/mpdf/examples/example26_RTL.php
new file mode 100644
index 0000000..08906c2
--- /dev/null
+++ b/mpdf/examples/example26_RTL.php
@@ -0,0 +1,363 @@
+
+div.mpdf_index_main {
+ font-family: xbriyaz;
+}
+div.mpdf_index_entry {
+ font-family: xbriyaz;
+}
+div.mpdf_index_letter {
+ font-family: xbriyaz;
+}
+
+
+
+mPDF
+RTL Languages
+
+English
+Please note that I do not understand any of the scripts below. The texts are borrowed from News websites, and I have used words and bits of phrases just to demonstrate the program.
+
+Hebrew (pangram)
+דג סקרן שט בים מאוכזב ולפתע מצא חברה
+
+או הנסה אלהים, לבוא לקחת לו גוי מקרב גוי, במסת באתת ובמופתים ובמלחמה וביד חזקה ובזרוע נטויה, ובמוראים גדלים: ככל אשר-עשה לכם יהוה אלהיכם, במצרים--לעיניך
+
+לכן חכו לי נאם יהוה ליום קומי לעד, כי משפטי לאסף גוים לקבצי ממלכות, לשפך עליהם זעמי כל חרון אפי, כי באש קנאתי תאכל כל הארץ
+
+שפן אכל קצת גזר בטעם חסה, ודי.
+
+
+
+
+
+Arabic
+الامريكي جورج بوش في حديث متلفز
+ في الذكرى الرابعة للغزو الامريكي للعراق ان الاولوية حاليا لاعادة الامن للعراق.
+
+
+هل ستسفر الجهود الدبلوماسية الجارية عن حلول؟ وكيف تنظر للاتهامات لبعض هذه الدول بالتدخل في الشأن العراقي، والتورط في دعم عمليات العنف؟ والى اي مدى يبدو الوضع في العراق انعكاسا للصراعات الإقليمية في المنطقة؟
+
+وادان البيت الابيض "بشدة" تفجير ايلات فيما اعربت وزارة الخارجية الروسية عن "ادانتها الشديدة" للحادث" واصفة اياه بـ"المتطرف" الذي استهدف "مدنيين مسالمين".
+
+واضافت وزارة الخارجية الروسية في بيانها: "من المؤسف ان يأتي هذا الحادث بينما تبذل الجهود لتخطي الازمة الفلسطينية الداخلية".
+
+ودعت موسكو السلطات الفلسطينية الى "بذل كل ما يمكن من اجل احتواء مظاهر التطرف التي لا مبرر لها والتي لا تفيد مصالح الشعب الفلسطيني على الامد الطويل".
+
+ودعت موسكو السلطات الفلسطينية الى "بذل كل ما ودعت موسكو السلطات الفلسطينية الى "بذل كل
+
+ودعت موسكو السلطات الفلسطينية الى ودعت موسكو السلطات الفلسطينية الى "بذل كل ما يمكن من اجل
+
+
+كما ادان الفارو دي سوتو مبعوث الامم المتحدة الخاص الى الشرق الاوسط العملية وقال "انه كان هجوما على اشخاص عاديين كانوا يقومون بنشاطهم اليومي وهذا امر لا يمكن تبريره".
+
+Farsi / Persian (fa)
+محمد البرادعی رئيس آژانس بين المللی انرژی اتمی پيشنهاد کرده است تهران برنامه جنجالی غنی سازی اورانيوم را متوقف کند و غرب نيز اجرای تحريم های تنبيهی مورد تائيد سازمان ملل متحد را به تعويق بياندازد.
+
+جورج بوش، در چهارمین سالگرد اشغال عراق می گوید استراتژی استقرار نیروهای آمریکایی بیشتری در بغداد، مدتی طول خواهد کشید.
+
+آمریکا ویزای رئیس جمهور ایران را به منظور حضور وی در جلسه رای گیری شورای امنیت برای قطعنامه تازه علیه این کشور صادر کرد.
+
+
+Urdu
+جسٹس افتخار کی جبری رخصت پر لاہورہائی کورٹ کے ایک اور سندھ میں کئی سول جج مستعفی ہوگئے ہیں۔
+
+چیف جسٹس کی سرگرمیاں محدود کرنے اور پولیس تعیناتی کے حکم نامے پر دستخط کرکے غلط کیا: جنرل مشرف
+
+Pashto (ps)
+په کابل او کندهار کې دوو ځانمرگو بريدونو لږ تر لږه يو ماشوم وژلى او اته تنه نور ىې ټپيان کړي.
+
+ه عراق کې يوه تازه نظر شمېرنه ښيي چې عراقيان په زياتېدونکي توگه د حالاتو په اړه بدبينه دي او د بې باوري احساس کوي، خو خپل هيواد يوموټى غواړي.
+
+
+Symbols
+©®™µ•…′″§<>≤≥°−±÷⁄׃∫∑∞√≈≠≡∏¬∩∂
+ΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ
+αβγδεζηθικλμνξοπρςστυφχψω
+←↑→↓↔◊♣♥♦
+
+Dingbats
+§<>→↔♣♥♦
+
+win-1252
+¢€©®™‰µ·•…§ß‹›«»‘’“”‚„<>–—ˆ˜°±÷×¼½¾ƒ¬†‡
+ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØŒŠÙÚÛÜÝŸ
+àáâãäåæçèéêëìíîïðñòôõöøœšùúûüýþÿ
+
+Bidirectional text
+
+ Text alignment, unless specified, is neutral and therefore dictated by the \'direction\' of the paragraph.
+
+ Ttext is analysed at the end of every block element (div, p, td). If the text contains RTL characters, those characters and words are reversed according to the Unicode BiDirectional algorithm e.g.
+
+ وادان البيت الابيض "بشدة" تفجير with some english in the middle ايلات فيما اعربت وزارة
+
+ To set the \'directionality\' of the whole document e.g. to reverse default alignment, tables, lists etc. you can set the dir attribute or the direction CSS property on the HTML or BODY tag to \'rtl\' e.g.
+ <body style="direction: rtl">
+ <body dir="rtl">
+ or you can use $mpdf->SetDirectionality(\'rtl\');
+
+
+
+The document now has a baseline direction; this determines the:
+- text-alignment in blocks for which text-align has not been specifically set
+- layout of mirrored page-margins, columns, ToC and Indexes, headers and footers
+- base direction can be set by any of:
+ - $mpdf->SetDirectionality(\'rtl\');
+ - <html dir="rtl" or style="direction: rtl;">
+ - <body dir="rtl" or style="direction: rtl;">
+Base direction is an inherited CSS property, so will affect all content, unless...
+- direction can be set for all HTML block elements e.g.
+ <DIV><P><TABLE><TD><UL><LI> etc using
+ - CSS property < style="direction: rtl;">
+NOTE
+- block/table margins/paddings are NOT reversed by direction
+ NB mPDF <5.1 reversed the margins/paddings for blocks when RTL set.
+- language (either CSS "lang", using Autofont, or through initial set-up e.g. $mpdf = new mPDF(\'ar\') )
+ no longer affects direction in any way.
+ - config_cp.php has been changed as a result; any values of "dir" set here are now ineffective
+- default text-align is now as per CSS spec: "a nameless value which is dependent on direction"
+ NB default text-align removed from default stylesheet in config.php
+- once text-align is specified, it is respected and inherited
+ NB mPDF <5.1 reversed the text-align property for all blocks when RTL set.
+- the configurable value is depracated, as it is no longer required
+- the algorithm for handling bidirectioal text was substantially re-written/improved in mPDF v 6.0
+
+
+
+
+Tables
+Tables are automatically transposed when the direction is rtl:
+
+
+
+| قال |
+الرئيس |
+الرئيس |
+
+| قال |
+
+ قال الرئيس الامريكي جورج بوش في حديث متلفز
+ |
+
+ قال الرئيس الامريكي جورج بوش في حديث متلفز
+ |
+
+|
+ قال
+ |
+
+ الرئيس
+ |
+الرئيس |
+
+|
+ قال
+الرئيس
+ |
+الرئيس |
+
+ الرئيس
+ |
+
+| قال |
+الرئيس |
+الرئيس |
+
+| قال |
+الرئيس |
+الرئيس |
+
+| قال |
+الرئيس |
+الرئيس |
+
+| قال |
+الرئيس |
+الرئيس |
+
+
+
+Lists
+Lists will automatically reverse as well (note the use of list-style to set numbering):
+
+
+- قال الرئيس
+- الامريكي
+
- جورج بوش في جورج بوش في جورج بوش في جورج بوش في جورج بوش في جورج
+ - حديث متلفز
+
+ - في الذكرى الرابعة
+ - للغزو الامريكي
+
+
+
+- للعراق ان الاولوية حاليا
+- لاعادة الامن للعراق
+
+
+';
+
+//==============================================================
+ // Set Header and Footer
+ $h = array (
+ 'odd' =>
+ array (
+ 'R' =>
+ array (
+ 'content' => '{PAGENO}',
+ 'font-size' => 8,
+ 'font-style' => 'B',
+ ),
+ 'L' =>
+ array (
+ 'content' => "\xd9\x82\xd8\xa7\xd9\x84 \xd8\xa7\xd9\x84\xd8\xb1\xd8\xa6\xd9\x8a\xd8\xb3",
+ 'font-size' => 8,
+ 'font-style' => 'B',
+ ),
+ 'line' => 1,
+ ),
+ 'even' =>
+ array (
+ 'L' =>
+ array (
+ 'content' => '{PAGENO}',
+ 'font-size' => 8,
+ 'font-style' => 'B',
+ ),
+ 'R' =>
+ array (
+ 'content' => "\xd9\x82\xd8\xa7\xd9\x84 \xd8\xa7\xd9\x84\xd8\xb1\xd8\xa6\xd9\x8a\xd8\xb3",
+ 'font-size' => 8,
+ 'font-style' => 'B',
+ ),
+ 'line' => 1,
+ ),
+);
+
+ $f = array (
+ 'odd' =>
+ array (
+ 'L' =>
+ array (
+ 'content' => '{DATE Y-m-d}',
+ 'font-size' => 8,
+ 'font-style' => 'BI',
+ ),
+ 'C' =>
+ array (
+ 'content' => '- {PAGENO} -',
+ 'font-size' => 8,
+ ),
+ 'R' =>
+ array (
+ 'content' => "\xd8\xa7\xd9\x84\xd8\xb1\xd8\xa6\xd9\x8a\xd8\xb3",
+ 'font-size' => 8,
+ ),
+ 'line' => 1,
+ ),
+ 'even' =>
+ array (
+ 'L' =>
+ array (
+ 'content' => "\xd8\xa7\xd9\x84\xd8\xb1\xd8\xa6\xd9\x8a\xd8\xb3",
+ 'font-size' => 8,
+ 'font-style' => 'B',
+ ),
+ 'C' =>
+ array (
+ 'content' => '- {PAGENO} -',
+ 'font-size' => 8,
+ ),
+ 'R' =>
+ array (
+ 'content' => '{DATE Y-m-d}',
+ 'font-size' => 8,
+ 'font-style' => 'BI',
+ ),
+ 'line' => 1,
+ ),
+);
+
+//==============================================================
+// Create Index entries from random words in $html
+ // Split $html into words
+ $a =preg_split('/<(.*?)>/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
+ $html = '';
+ foreach($a as $i => $e) {
+ if($i%2==0) {
+
+ $words = preg_split('/([\s,\.]+)/',$e,-1,PREG_SPLIT_DELIM_CAPTURE);
+ foreach($words as $w) {
+
+ $y = rand(1,10); // every tenth word
+ // If it is just a word use it as an index entry
+ if (preg_match("/^([0]{0,1}6[0-9a-f][0-9a-f];){4,30}$/i",$w) && ($y > 8)) {
+ $content = trim($w);
+ $html .= '';
+ }
+ $html .= $w;
+ }
+ }
+ else { $html .= '<'.$e.'>'; }
+ }
+//==============================================================
+//==============================================================
+include("../mpdf.php");
+
+
+$mpdf=new mPDF('','A4','','',32,25,27,25,16,13);
+
+$mpdf->SetDirectionality('rtl');
+$mpdf->mirrorMargins = true;
+$mpdf->SetDisplayMode('fullpage','two');
+
+$mpdf->autoLangToFont = true;
+
+$mpdf->defaultPageNumStyle = 'arabic-indic';
+
+$mpdf->setHeader($h);
+$mpdf->setFooter($f);
+
+$mpdf->debug = true;
+
+$stylesheet = file_get_contents('mpdfstyletables.css');
+$mpdf->WriteHTML($stylesheet,1); // The parameter 1 tells that this is css/style only and no body/html/text
+
+$mpdf->WriteHTML($html);
+$mpdf->AddPage();
+
+$mpdf->SetColumns(2,'J');
+$mpdf->WriteHTML($html);
+$mpdf->SetColumns(0);
+
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// INDEX
+$html = '
+
+Index
+
+
+';
+
+$mpdf->WriteHTML($html);
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+
+$mpdf->Output();
+exit;
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example27_CJK_using_Adobe_fonts.php b/mpdf/examples/example27_CJK_using_Adobe_fonts.php
new file mode 100644
index 0000000..6fca629
--- /dev/null
+++ b/mpdf/examples/example27_CJK_using_Adobe_fonts.php
@@ -0,0 +1,85 @@
+
+p { text-align: justify; }
+td { text-align: justify; }
+
+mPDF
+CJK Languages
+
+
+
+
+Japanese (pangrams)
+Iroha Uta
+
+いろはにほへと ちりぬるを わかよたれそ つねならむ うゐのおくやま けふこえて あさきゆめみし ゑひもせす
+
+色は匂へど 散りぬるを 我が世誰ぞ 常ならむ 有為の奥山 今日越えて 浅き夢見じ 酔ひもせず(ん)
+
+Tori Naku Uta
+
+とりなくこゑす ゆめさませ みよあけわたる ひんかしを そらいろはえて おきつへに ほふねむれゐぬ もやのうち
+
+鳥啼く声す 夢覚ませ 見よ明け渡る 東を 空色栄えて 沖つ辺に 帆船群れゐぬ 靄の中
+
+Ametsuchi No Uta
+
+あめ つち ほし そら / やま かは みね たに / くも きり むろ こけ / ひと いぬ うへ すゑ / ゆわ さる おふ せよ / えのえ*を なれ ゐて
+
+天 地 星 空 / 山 川 峰 谷 / 雲 霧 室 苔 / 人 犬 上 末 / 硫黄 猿 生ふ 為よ / 榎の 枝を 馴れ 居て
+
+Taini no Uta
+
+たゐにいて なつむわれをそ きみめすと あさりおひゆく やましろの うちゑへるこら もはほせよ えふねかけぬ
+
+田居に出で 菜摘むわれをぞ 君召すと 求食り追ひゆく 山城の 打酔へる子ら 藻葉干せよ え舟繋けぬ
+
+
+
+Chinese (simplified) GB2312
+
+来自商务部新闻办公室的消息称,中方免除与中国有外交关系的所有非洲重债穷国及最不发达国家截至2005年底对华到期政府无息贷款债务。有关部门已对相关债务进行全面清理核对,对与中国有外交关系的33个非洲重债穷国和最不发达国家,免除其截至2005年底168笔对华到期无息贷款债务。拟于2007年底前与受援国办理完免债协议。
+
+
+
+Chinese (Traditional - Hong Kong)
+
+「憂鬱小王子」是一個教育網站,它成功結合了香港賽馬會防止自殺研究中心各方面的專才,為青少年人提供精神健康的訊息,對普及抑鬱症知識的貢獻良多。在香港,它曾獲選為「2004年十大健康網站」之一,該項選舉自2005年起改名現時的「優秀網站選舉」。其貢獻在國際間亦備受肯定,2005年,該網站榮獲第八屆「亞洲創新大獎」銀獎。
+
+
+
+
+Korean
+키스의 고유조건은 입술끼리 만나야 하고 특별한 기술은 필요치 않다.
+
+
+
+';
+//==============================================================
+//==============================================================
+//==============================================================
+
+include("../mpdf.php");
+
+$mpdf=new mPDF('+aCJK','A4','','',32,25,27,25,16,13);
+$mpdf->SetDisplayMode('fullpage');
+
+// LOAD a stylesheet
+$stylesheet = file_get_contents('mpdfstyleA4.css');
+$mpdf->WriteHTML($stylesheet,1); // The parameter 1 tells that this is css/style only and no body/html/text
+
+$mpdf->autoLangToFont = true;
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+exit;
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example28_CJK_using_embedded_fonts.php b/mpdf/examples/example28_CJK_using_embedded_fonts.php
new file mode 100644
index 0000000..49db78d
--- /dev/null
+++ b/mpdf/examples/example28_CJK_using_embedded_fonts.php
@@ -0,0 +1,85 @@
+
+p { text-align: justify; }
+td { text-align: justify; }
+
+mPDF
+CJK Languages
+
+
+
+
+Japanese (pangrams)
+Iroha Uta
+
+いろはにほへと ちりぬるを わかよたれそ つねならむ うゐのおくやま けふこえて あさきゆめみし ゑひもせす
+
+色は匂へど 散りぬるを 我が世誰ぞ 常ならむ 有為の奥山 今日越えて 浅き夢見じ 酔ひもせず(ん)
+
+Tori Naku Uta
+
+とりなくこゑす ゆめさませ みよあけわたる ひんかしを そらいろはえて おきつへに ほふねむれゐぬ もやのうち
+
+鳥啼く声す 夢覚ませ 見よ明け渡る 東を 空色栄えて 沖つ辺に 帆船群れゐぬ 靄の中
+
+Ametsuchi No Uta
+
+あめ つち ほし そら / やま かは みね たに / くも きり むろ こけ / ひと いぬ うへ すゑ / ゆわ さる おふ せよ / えのえ*を なれ ゐて
+
+天 地 星 空 / 山 川 峰 谷 / 雲 霧 室 苔 / 人 犬 上 末 / 硫黄 猿 生ふ 為よ / 榎の 枝を 馴れ 居て
+
+Taini no Uta
+
+たゐにいて なつむわれをそ きみめすと あさりおひゆく やましろの うちゑへるこら もはほせよ えふねかけぬ
+
+田居に出で 菜摘むわれをぞ 君召すと 求食り追ひゆく 山城の 打酔へる子ら 藻葉干せよ え舟繋けぬ
+
+
+
+Chinese (simplified) GB2312
+
+来自商务部新闻办公室的消息称,中方免除与中国有外交关系的所有非洲重债穷国及最不发达国家截至2005年底对华到期政府无息贷款债务。有关部门已对相关债务进行全面清理核对,对与中国有外交关系的33个非洲重债穷国和最不发达国家,免除其截至2005年底168笔对华到期无息贷款债务。拟于2007年底前与受援国办理完免债协议。
+
+
+
+Chinese (Traditional - Hong Kong)
+
+「憂鬱小王子」是一個教育網站,它成功結合了香港賽馬會防止自殺研究中心各方面的專才,為青少年人提供精神健康的訊息,對普及抑鬱症知識的貢獻良多。在香港,它曾獲選為「2004年十大健康網站」之一,該項選舉自2005年起改名現時的「優秀網站選舉」。其貢獻在國際間亦備受肯定,2005年,該網站榮獲第八屆「亞洲創新大獎」銀獎。
+
+
+
+
+Korean
+키스의 고유조건은 입술끼리 만나야 하고 특별한 기술은 필요치 않다.
+
+
+
+';
+//==============================================================
+//==============================================================
+//==============================================================
+
+include("../mpdf.php");
+
+$mpdf=new mPDF('-aCJK','A4','','',32,25,27,25,16,13);
+$mpdf->SetDisplayMode('fullpage');
+
+// LOAD a stylesheet
+$stylesheet = file_get_contents('mpdfstyleA4.css');
+$mpdf->WriteHTML($stylesheet,1); // The parameter 1 tells that this is css/style only and no body/html/text
+
+$mpdf->autoLangToFont = true;
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+exit;
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example29_multilingual_autofont.php b/mpdf/examples/example29_multilingual_autofont.php
new file mode 100644
index 0000000..6663327
--- /dev/null
+++ b/mpdf/examples/example29_multilingual_autofont.php
@@ -0,0 +1,392 @@
+
+
+body { font-family: sans; text-align: justify; }
+p { font-family: sans; }
+div { font-family: sans; }
+
+
+
+This document includes many languages. Selection of appropriate fonts is done automatically by using AutoFont.
+Pangrams - (from Wikipedia)
+The quick brown fox jumps over a lazy dog
+
+Bulgarian
+Жълтата дюля беше щастлива, че пухът, който цъфна, замръзна като гьон.
+
+За миг бях в чужд плюшен скърцащ фотьойл.
+
+Catalan
+Jove xef, porti whisky amb quinze glaçons d\'hidrogen, coi!
+
+Aqueix betzol, Jan, comprava whisky de figa
+
+Czech
+Příliš žluťoučký kůň úpěl ďábelské ódy
+
+Danish
+Høj bly gom vandt fræk sexquiz på wc
+
+Dutch
+Doch Bep, flink sexy qua vorm, zwijgt
+
+Pa\'s wijze lynx bezag vroom het fikse aquaduct
+
+Finnish
+Törkylempijä vongahdus
+
+French
+Portez ce vieux whisky au juge blond qui fume
+
+Bâchez la queue du wagon-taxi avec les pyjamas du fakir
+
+Voyez le brick géant que j\'examine près du wharf
+
+German
+Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich
+
+"Fix, Schwyz!" quäkt Jürgen blöd vom Paß
+
+"Falsches Üben von Xylophonmusik quält jeden größeren Zwerg"
+
+Hungarian
+Egy hűtlen vejét fülöncsípő, dühös mexikói úr Wesselényinél mázol Quitóban.
+
+Icelandic
+Kæmi ný öxi hér ykist þjófum nú bæði víl og ádrepa
+
+Irish
+D\'fhuascail Íosa Úrmhac na hÓighe Beannaithe pór Éava agus Ádhaimh
+
+D\'ḟuascail Íosa Úrṁac na hÓiġe Beannaiṫe pór Éaḃa agus Áḋaiṁ
+
+Italian
+"Quel fez sghembo copre davanti"
+
+"Ma la volpe col suo balzo ha raggiunto il quieto Fido"
+
+"Quel vituperabile xenofobo zelante assaggia il whisky ed esclama: alleluja!"
+
+Lithuanian
+Įlinkdama fechtuotojo špaga sublykčiojusi pragręžė apvalų arbūzą
+
+Norwegian
+Vår sære Zulu fra badeøya spilte jo whist og quickstep i min taxi.
+
+Høvdingens kjære squaw får litt pizza i Mexico by
+
+Polish
+Pójdźże, kiń tę chmurność w głąb flaszy!
+
+Pchnąć w tę łódź jeża lub ośm skrzyń fig.
+
+Mężny bądź, chroń pułk twój i sześć flag.
+
+Portuguese
+Blitz prende ex-vesgo com cheque fajuto.
+
+Gazeta publica hoje no jornal uma breve nota de faxina na quermesse.
+
+À noite, vovô Kowalsky vê o ímã cair no pé do pingüim queixoso e vovó põe açúcar no chá de tâmaras do jabuti feliz.
+
+Luís argüia à Júlia que «brações, fé, chá, óxido, pôr, zângão» eram palavras do português.
+
+Romanian
+Gheorghe, obezul, a reuşit să obţină jucându-se un flux în Quebec de o mie kilowaţioră.
+
+Russian
+В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!
+
+(Using quasiobsolete spelling for last word to include ъ) В чащах юга жил бы цитрус? Да, но фальшивый экземпляръ!
+
+Эх, чужак! Общий съём цен шляп (юфть) — вдрызг!
+
+Экс-граф? Плюш изъят. Бьём чуждый цен хвощ!
+
+Съешь ещё этих мягких французских булок, да выпей же чаю.
+
+Широкая электрификация южных губерний даст мощный толчок подъёму сельского хозяйства.
+
+Serbian
+Љубазни фењерџија чађавог лица хоће да ми покаже штос.
+
+Ljubazni fenjerdžija čađavog lica hoće da mi pokaže štos.
+
+Slovene
+Šerif bo za vajo spet kuhal domače žgance
+
+Piškur molče grabi fižol z dna cezijeve hoste
+
+Spanish
+El veloz murciélago hindú comía feliz cardillo y kiwi. La cigüeña tocaba el saxofón detrás del palenque de paja.
+
+El pingüino Wenceslao hizo kilómetros bajo exhaustiva lluvia y frío, añoraba a su querido cachorro.
+
+Jovencillo emponzoñado de whisky: ¡qué figurota exhibe!
+
+Ese libro explica en su epígrafe las hazañas y aventuras de Don Quijote de la Mancha en Kuwait.
+
+Queda gazpacho, fibra, látex, jamón, kiwi y viñas.
+
+Whisky bueno: ¡excitad mi frágil pequeña vejez!
+
+Swedish
+Flygande bäckasiner söka hwila på mjuka tuvor.
+
+Yxskaftbud, ge vår wczonmö iqhjälp.
+
+Ukrainian
+Чуєш їх, доцю, га? Кумедна ж ти, прощайся без ґольфів!
+
+Жебракують філософи при ґанку церкви в Гадячі, ще й шатро їхнє п\'яне знаємо.
+
+Turkish (pangram)
+Pijamalı hasta yağız şoföre çabucak güvendi.
+
+Greek
+Monotonic
+Πάτερ ημών ο εν τοις ουρανοίς αγιασθήτω το όνομά σου· ελθέτω η βασιλεία σου· γενηθήτω το θέλημά σου, ως εν ουρανώ και επί της γης· τον άρτον ημών τον επιούσιον δος ημίν σήμερον· και άφες ημίν τα οφελήματα ημών, ως και ημείς αφίεμεν τοις οφειλέταις ημών· και μη εισενέγκης ημάς εις πειρασμόν, αλλά ρύσαι ημάς από του πονηρού. αμήν.
+
+Polytonic
+Πάτερ ἡμῶν ὁ ἐν τοῖς οὐρανοῖς ἁγιασθήτω τὸ ὄνομά σου· ἐλθέτω ἡ βασιλεία σου· γενηθήτω τὸ θέλημά σου, ὡς ἐν οὐρανῷ καὶ ἐπὶ τῆς γῆς· τὸν ἄρτον ἡμῶν τὸν ἐπιούσιον δὸς ἡμῖν σήμερον· καὶ ἄφες ἡμῖν τὰ ὀφελήματα ἡμῶν, ὡς καὶ ἡμεῖς ἀφίεμεν τοῖς ὀφειλέταις ἡμῶν· καὶ μὴ εἰσενέγκῃς ἡμᾶς εἰς πειρασμόν, ἀλλὰ ρῦσαι ἡμᾶς ἀπὸ τοῦ πονηροῦ. ἀμήν.
+
+
+Languages
+(The following are used for demonstration purposes only. Some of the following excerpts are taken from web pages from the BBC Foreign News just to show the script - I have no idea what they actually say!!)
+
+Latvian
+Latvijas institūts veic konsultatīvi koordinējošas funkcijas Latvijas starptautiskās atpazīstamības jomā;
+gatavo un izplata plašai sabiedrībai pieejamu, svarīgu pamatinformāciju saturošu, viegli izprotamu un iegaumējamu, kā arī pozitīvu iespaidu izraisošu vispārēju pamatinformāciju par Latviju, Latvijas dabu, sabiedrību, kultūru un vēsturi;
+
+Azeri (az)
+Qaz kəmərinin açılışında İran və Ermənistanın prezidentləri iştirak ediblər.
+
+İran qazını Ermənistana nəql edəcək bu kəmər Yerevan üçün xüsusi önəm daşıyır, belə ki, böyük etnik azərbaycanlı toplumuna malik İran təlatümlü regionda öz maraqlarını qorumaq üçün çox vaxt Ermənistanın müttəfiqi kimi görünüb.
+
+Bulgarian
+Последните донаборници в българската армия ще служат 9 месеца, както постановява закона 6 месеца е съкратеният срок само за завършилите висше образование - така министър Веселин Близнаков отхвърли различните интерпретации в публичното пространство по темата. Министърът на отбраната разформирова в Казанлък Втората ни рота от Ашраф и Втори пехотен взвод, завърнал се от миротворческа мисия от Баня Лука в Босна и Херцеговина.
+
+Macedonian (mk)
+Буш рече оти е суштински да се осигури безбедноста на Багдад и да се обнови нормалниот живот во остатокот од земјата.
+
+Митрева ја прозва владата за индолентен однос кон ова битката за зачувивање на уставното име на земјата.
+
+Uzbek (uz)
+Ироқликлар орасида тушкунлик ортиб бораяпти
+
+Ироқда ўтказилган сўнгги жамоатчилик фикрини ўрганиш натижаларига кўра, мамлакат келажаги борасида тушкун кайфиятда бўлган ироқликлар сони тобора ортиб бормоқда.
+
+Kyrgyz (ky)
+Казакстанда айыл тургундары уруша кетип 3 киши каза тапты
+Казакстандын Алматы шаарынын тушундагы айылда эки киши ортосундагы чатак чоң урушка айланып, ага элүү чакты киши аралашкан.
+
+
+
+Albanian (sq)
+Një anketë sugjeron se irakianët kanë një pesimizëm në rritje për të ardhmen e vendit të tyre.
+
+Presidenti shqiptar Alfred Moisiu dekretoi të hënën ndryshimet e propozuara nga kryeministri Sali Berisha në kabinetin e tij, pas zgjedhjeve lokale.
+
+
+Vietnamese (vi)
+Một khảo sát mới cho biết người dân Iraq ngày càng cảm thấy bi quan và không tin tưởng vào chính phủ cũng như liên quân
+
+Nga đang thực hiện chiến dịch cứu hộ sau khi có vụ nổ khí methane tại một mỏ than ở Siberia làm ít nhất 61 người thiệt mạng
+
+Thai (pangram)
+เป็นมนุษย์สุดประเสริฐเลิศคุณค่า กว่าบรรดาฝูงสัตว์เดรัจฉาน จงฝ่าฟันพัฒนาวิชาการ อย่าล้างผลาญฤๅเข่นฆ่าบีฑาใคร ไม่ถือโทษโกรธแช่งซัดฮึดฮัดด่า หัดอภัยเหมือนกีฬาอัชฌาสัย ปฏิบัติประพฤติกฎกำหนดใจ พูดจาให้จ๊ะๆ จ๋า น่าฟังเอยฯ
+
+
+
+
+
+ Hebrew (pangram)
+ דג סקרן שט בים מאוכזב ולפתע מצא חברה
+
+ או הנסה אלהים, לבוא לקחת לו גוי מקרב גוי, במסת באתת ובמופתים ובמלחמה וביד חזקה ובזרוע נטויה, ובמוראים גדלים: ככל אשר-עשה לכם יהוה אלהיכם, במצרים--לעיניך
+
+
+
+
+ Arabic
+ قال الرئيس الامريكي جورج بوش في حديث متلفز في الذكرى الرابعة للغزو الامريكي للعراق ان الاولوية حاليا لاعادة الامن للعراق.
+
+ هل ستسفر الجهود الدبلوماسية الجارية عن حلول؟ وكيف تنظر للاتهامات لبعض هذه الدول بالتدخل في الشأن العراقي، والتورط في دعم عمليات العنف؟ والى اي مدى يبدو الوضع في العراق انعكاسا للصراعات الإقليمية في المنطقة؟
+
+
+ Persian / Farsi
+ محمد البرادعی رئيس آژانس بين المللی انرژی اتمی پيشنهاد کرده است تهران برنامه جنجالی غنی سازی اورانيوم را متوقف کند و غرب نيز اجرای تحريم های تنبيهی مورد تائيد سازمان ملل متحد را به تعويق بياندازد.
+
+
+
+ Urdu
+ تمام انسان آزاد اور حقوق و عزت کے اعتبار سے برابر پیدا ہوۓ ہیں۔ انہیں ضمیر اور عقل ودیعت ہوئی ہی۔ اسلۓ انہیں ایک دوسرے کے ساتھ بھائی چارے کا سلوک کرنا چاہیۓ۔
+
+
+ Pashto (ps)
+ په کابل او کندهار کې دوو ځانمرگو بريدونو لږ تر لږه يو ماشوم وژلى او اته تنه نور ىې ټپيان کړي.
+
+
+
+ Sindhi (sd)
+
+واشنگٽن (م ڊ) آمريڪا چيو آهي ته ڪيري لوگربل تي پاڪ فوج جي تحفظات سان پاڪستان ۾ جمهوري طور آيل زرداري جي حڪومت کي ڪوبه خطرو ناهي، ان سوال تي تي ڪيري لوگربل ۾ پاڪستان کي غير مشروط امداد ڏيڻ جي ڳالهه ڪئي وئي آهي، جڏهن ته فوجي امداد تي شرط لاڳو ڪيا
+
+
+
+
+
+Indic Scripts
+
+
+Malayalam
+
+സംസ്ഥാനത്ത് രാഷ്ട്രീയ പുകമറ സൃഷ്ടിക്കാനാണ് വോട്ടര്പട്ടിക വിവാദത്തിലൂടെ കോണ്ഗ്രസ് ശ്രമിക്കുന്നതെന്ന് സിപിഎം സംസ്ഥാന സെക്രട്ടറി പിണറായി വിജയന് കുറ്റപ്പെടുത്തി। ഉദ്യോഗസ്ഥരെ ഭീഷണിപ്പെടുത്തി വരുതിയില് നിര്ത്താനാണ് വയലാര് രവി ഉള്പ്പെടെയുള്ളവര് ശ്രമിക്കുന്നതെന്നും പിണറായി പ്രസ്താവനയില് ആരോപിച്ചു।
+
+
+Kannada
+
+ತಮ್ಮದೇ ಕುಟುಂಬದ ಯುವತಿಯೊಬ್ಬಳನ್ನು ಸತತ ಹಲವಾರು ವರ್ಷ ಭೋಗಿಸಿದ ಭಾರತೀಯ ಮೂಲದ ಮೂವರು ದುರುಳ ಸಂಬಂಧಿಕರು ಅಪರಾಧಿಗಳೆಂದು ಸಾಬೀತಾಗಿದ್ದು, ಇಂಗ್ಲೆಂಡ್ ನ್ಯಾಯಾಲಯವು ದೀರ್ಘಾವಧಿ ಕಠಿಣ ಶಿಕ್ಷೆ ವಿಧಿಸಿದೆ.
+
+
+Telegu
+ఆగ్నేయ ఇరాన్లో ఆదివారం నాడు ఓ ఆత్మాహుతి దాడి జరగడంతో ఇరవై మంది మృతి చెందారు.
+
+
+ఆగ్నేయ ఇరాన్లో ఆత్మాహుతి దాడి జరగడంతో ఐదుగురు ఎలిట్ రెవల్యూషనరీ గార్డ్లతో సహా ప్రముఖ కమాండర్లతోసహా మొత్తం ఇరవై మంది మృతి చెందినట్లు ఇరాన్ లోక్సభ స్పీకర్ అలీ లారిజానీ తెలిపారు.
+
+
+
+
+Tamil (ta)
+இராக்கிய மக்கள் அவநம்பிக்கையுடன் இருப்பதாகவும், ஷியா மற்றும் சுனிக்கள் முரண்பட்ட கருத்துக்களுடன் துருவப்பட்ட நிலையில் இருப்பதாகவும் கருத்துக் கணிப்பு ஒன்று கூறுகிறது.
+
+
+Oriya
+ଓଡ଼ିଆ ଉଇକିପେଡିଆ ଆପଣଙ୍କୁ ସ୍ବାଗତ କରୁଛି। ଏହି ଉନ୍ମୁକ୍ତ ଜ୍ଞାନକୋଷଟି ଇଣ୍ଟରନେଟ ଉପରେ ଆଧାରିତ ଏବଂ ଏହା ବିଶ୍ବର ୫୦ଟି ଭାଷାରେ ଉପଲବ୍ଧ । ଏହାକୁ ଆପଣ ମଧ୍ୟ ବର୍ଦ୍ଧିତ ଓ ପରିବର୍ତିତ କରିପାରିବେ ଏବଂ ଏହାକୁ ଉନ୍ନତ କରିବା ପାଇଁ ନିଜର ଅବଦାନ ଦେଇ ପାରିବେ । ଆପଣଙ୍କ ପସନ୍ଦର ବିଷୟ ଗୁଡିକୁ ଆପଣ ନୂତନ ଭାବେରେ ଯୋଗ କରିପାରିବେ କିମ୍ବା ଏହି ପୃଷ୍ଠାକୁ ସମ୍ପାଦନ କରି ଏହା ସହିତ ଯୋଗ କରିପାରିବ । ସମସ୍ତ ପାଠ ଗୁଡିକ GNU ମୁକ୍ତ ଦଲିଲକରଣ ଲାଇସେନ୍ସର ସର୍ତ୍ତ ଅଧୀନରେ ଉପଲବ୍ଧ । ତଥାପି, ଆପଣ ଏହାକୁ ମୁକ୍ତ ଭାବେର ଇଲେକ୍ଟ୍ରୋନିକ୍ସ ପ୍ରିଣ୍ଟ୍ କିମ୍ବା ଅନ୍ୟାନ୍ୟ ପ୍ରିଣ୍ଟର ମାଧ୍ୟମରେ ବ୍ୟବହାର କରିପାରିବ ।
+
+
+Punjabi
+ਕੇਂਦਰੀ ਗ੍ਰਹਿਮੰਤਰੀ ਪੀ.ਚਿਦੰਬਰਮ ਨੇ ਐਤਵਾਰ ਨੂੰ ਤਮਿਲਨਾਢੂ ਦੇ ਮੁੱਖਮੰਤਰੀ ਐਮ.ਕਰੁਣਾਨਿਧੀ ਨਾਲ ਮੁਲਾਕਾਤ ਕੀਤੀ।ਉਨ੍ਹਾ ਨੇ ਸ਼੍ਰੀਲੰਕਾ \'ਚ ਲਿੱਟੇ ਦੇ ਖਿਲਾਫ਼ ਯੁੱਧ ਦੌਰਾਨ ਉੱਝੜੇ ਹੋਏ ਲੱਗਭਗ ਢਾਈ ਲੱਖ ਤਮਿਲਾਂ ਦੀ ਮੁੜ ਰਿਹਾਇਸ਼ \'ਤੇ ਚਰਚਾ ਕੀਤੀ।
+
+
+Gujarati (gu)
+
+આ વાત હજાર વાર કહેવામાં આવી છે કે ફિલ્મ બનાવતી વખેત હંમેશા સૌથી વધુ ધ્યાન વાર્તા અને સ્ક્રીનપ્લે પર આપવુ જોઈએ. કારણ કે આ કોઈ પણ ફિલ્મની સફળતાનો મુખ્ય આધાર હોય છે.
+
+મોટા ફિલ્મ સ્ટાર્સ સાઈન કરવાથી, સ્ટંટ અને ગીતોથી પાણીની અંદર કે આકાશમાં કરોડો રૂપિયા ખર્ચ કરી ફિલ્માવેલા દ્રશ્યોથી કશુ જ નથી થતુ. પરંતુ આ બુનિયાદી વાત અત્યાર સુધી કોઈ લોકોને સમજાતી નથી.
+
+
+
+Hindi (hi)
+भारत और बरमूडा के बीच बारिश के कारण रुका मैच दोबारा शुरु हो गया है. भारत ने बरमूडा के सामने रिकॉर्ड 414 रनों का लक्ष्य रखा है. बरमूडा ने दो विकेट खो दिए हैं.
+
+
+Nepali (ne) - Devanagari
+अन्तरिम सरकारको गठनमा ढीलाइ हुनुका साथै आउंदो जेठ महिनाभित्र संविधानसभाको चुनाव होला कि नहोला भन्ने बहस चर्कीरहेको बेला चुनावकै विषयमा निर्वाचन आयोग र आठ दलको बेग्ला, बेग्लै भनाइ रहेको देखिएको छ।
+
+
+Bengali (bn)
+
+দক্ষিণ ওয়াজিরিস্থানে কর্মরত স্বেচ্ছাসেবী ও ত্রাণ সংস্থাগুলো ধারণা করছে সেনা অভিযানের তীব্রতা বাড়লে এই সংখ্যাটা আরও অনেক বেড়ে যাবে
+
+শরণার্থীদের স্রোত সামলাতে তারা ইতিমধ্যেই হিমশিম খাচ্ছেন, ফলে লড়াই থেকে পালিয়ে আসা বেসামরিক মানুষজনের সংখ্যা আরও বাড়লে স্বভাবতই সঙ্কট আরও জটিল হয়ে উঠবে
+
+
+
+Assamese
+অসমীয়া ৱিকিপিডিয়াৰ উদ্দেশ্য হ\'ল সম্পূৰ্ণ অসমীয়া ভাষাত এখনি বিশ্বকোষ প্ৰণয়ন কৰা। অন্য কোনো ভাষাৰ প্ৰবন্ধ এই বিশ্বকোষৰ বাবে গ্ৰহন কৰা নহ\'ব। বিশ্বকোষৰ অৱদানকাৰীসকললৈ সাদৰেৰে অনুৰোধ জনোৱা হ\'ল যাতে তেখেতসকলে অসমীয়া ভাষাৰ প্ৰচলিত বানান পদ্ধতি মানি চলে। বিদেশী শব্দৰ অসমীয়া প্ৰতিৰূপৰ ক্ষেত্ৰত যিহেতু অসমীয়া সাহিত্যিকসকল এতিয়াও ঐক্যমতত উপনীত হ\'ব পৰা নাই, ৱিকিপিডিয়াত বিদেশী শব্দৰ যিকোনো ধৰনৰ অসমীয়া ৰূপ গ্ৰাহ্য কৰা হ\'ব।
+
+
+
+
+
+Japanese (pangrams)
+Iroha Uta SJIS
+
+いろはにほへと ちりぬるを わかよたれそ つねならむ うゐのおくやま けふこえて あさきゆめみし ゑひもせす
+
+Tori Naku Uta
+
+とりなくこゑす ゆめさませ みよあけわたる ひんかしを そらいろはえて おきつへに ほふねむれゐぬ もやのうち
+
+Ametsuchi No Uta
+
+あめ つち ほし そら / やま かは みね たに / くも きり むろ こけ / ひと いぬ うへ すゑ / ゆわ さる おふ せよ / えのえ*を なれ ゐて
+
+Taini no Uta
+
+たゐにいて なつむわれをそ きみめすと あさりおひゆく やましろの うちゑへるこら もはほせよ えふねかけぬ
+
+Chinese (simplified) GB2312 GB
+
+来自商务部新闻办公室的消息称,中方免除与中国有外交关系的所有非洲重债穷国及最不发达国家截至2005年底对华到期政府无息贷款债务。有关部门已对相关债务进行全面清理核对,对与中国有外交关系的33个非洲重债穷国和最不发达国家,免除其截至2005年底168笔对华到期无息贷款债务。拟于2007年底前与受援国办理完免债协议。
+
+
+Chinese (Traditional - Hong Kong) Big5
+
+「憂鬱小王子」是一個教育網站,它成功結合了香港賽馬會防止自殺研究中心各方面的專才,為青少年人提供精神健康的訊息,對普及抑鬱症知識的貢獻良多。在香港,它曾獲選為「2004年十大健康網站」之一,該項選舉自2005年起改名現時的「優秀網站選舉」。其貢獻在國際間亦備受肯定,2005年,該網站榮獲第八屆「亞洲創新大獎」銀獎。
+
+
+
+Korean UHC
+
+키스의 고유조건은 입술끼리 만나야 하고 특별한 기술은 필요치 않다.
+
+
+Mixed
+Distinguishes multiple languages enclosed in same element (tags): Arabic قال الرئيس
+English Cat sat on the large mat
+Tamil ஷியா
+Hindi भारत और
+Japanese いろはにほへと
+Chinese 来自商务部新闻办公
+Thai เป็นมนุษย
+Viet Một khảo sát mới cho biết người dân
+Tamil ஷியா
+Chinese 来自商务部新闻办公
+English Cat sat on the large mat
+
+
+
+Unicode Plane 2
+
+Unicode Plane 0 (BMP U+0000 - U+FFFF):
+鼂 鼈 鼗 鼦 鼧 鼹 齄 齅 齐 齓 齚 齢 齩 齿 龎 龙 龟 龥
+-------
+Unicode Plane 2 (SIP characters > U+20000):
+𠀡 𠀾 𠁆 𠁎 𠁨 𠂆 𠂇 𠂊 𠂔 𠃊 𠃋 𠃌 𠃍 𠃑 𠃮 𠄌 𠄎 𠄘 𠆤 𠆩 𠆫 𠇁 𠇔 𠇲 𠈄 𠈌 𠈔 𠈹 𠉛 𠉴 𠉵 𠊙 𠊞 𠊠 𠊷 𠊿 𠋀 𠋥 𠌊
+-------
+Unicode Plane 0 (BMPU+0000 - U+FFFF):
+鼂 鼈 鼗 鼦 鼧 鼹 齄 齅 齐 齓 齚 齢 齩 齿 龎 龙 龟 龥
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+include("../mpdf.php");
+
+$mpdf=new mPDF();
+
+$mpdf->autoScriptToLang = true;
+$mpdf->baseScript = 1;
+$mpdf->autoVietnamese = true;
+$mpdf->autoArabic = true;
+
+$mpdf->autoLangToFont = true;
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+
+exit;
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example32_indic.php b/mpdf/examples/example32_indic.php
new file mode 100644
index 0000000..b7e2b81
--- /dev/null
+++ b/mpdf/examples/example32_indic.php
@@ -0,0 +1,106 @@
+
+body, p, div { font-size: 14pt; font-family: freeserif;}
+h3 { font-size: 15pt; margin-bottom:0; font-family: sans-serif; }
+
+
+ Indic Fonts and Languages
+
+Malayalam
+സംസ്ഥാനത്ത് രാഷ്ട്രീയ പുകമറ സൃഷ്ടിക്കാനാണ് വോട്ടര്പട്ടിക വിവാദത്തിലൂടെ കോണ്ഗ്രസ് ശ്രമിക്കുന്നതെന്ന് സിപിഎം സംസ്ഥാന സെക്രട്ടറി പിണറായി വിജയന് കുറ്റപ്പെടുത്തി. ഉദ്യോഗസ്ഥരെ ഭീഷണിപ്പെടുത്തി വരുതിയില് നിര്ത്താനാണ് വയലാര് രവി ഉള്പ്പെടെയുള്ളവര് ശ്രമിക്കുന്നതെന്നും പിണറായി പ്രസ്താവനയില് ആരോപിച്ചു.
+
+
+൦൧൨൩൪൫൬൭൮൯
+
+
+Kannada
+
+ತಮ್ಮದೇ ಕುಟುಂಬದ ಯುವತಿಯೊಬ್ಬಳನ್ನು ಸತತ ಹಲವಾರು ವರ್ಷ ಭೋಗಿಸಿದ ಭಾರತೀಯ ಮೂಲದ ಮೂವರು ದುರುಳ ಸಂಬಂಧಿಕರು ಅಪರಾಧಿಗಳೆಂದು ಸಾಬೀತಾಗಿದ್ದು, ಇಂಗ್ಲೆಂಡ್ ನ್ಯಾಯಾಲಯವು ದೀರ್ಘಾವಧಿ ಕಠಿಣ ಶಿಕ್ಷೆ ವಿಧಿಸಿದೆ.
+
+೦೧೨೩೪೫೬೭೮೯
+
+
+Telegu
+ఆగ్నేయ ఇరాన్లో ఆదివారం నాడు ఓ ఆత్మాహుతి దాడి జరగడంతో ఇరవై మంది మృతి చెందారు.
+
+
+ఆగ్నేయ ఇరాన్లో ఆత్మాహుతి దాడి జరగడంతో ఐదుగురు ఎలిట్ రెవల్యూషనరీ గార్డ్లతో సహా ప్రముఖ కమాండర్లతోసహా మొత్తం ఇరవై మంది మృతి చెందినట్లు ఇరాన్ లోక్సభ స్పీకర్ అలీ లారిజానీ తెలిపారు.
+
+౦౧౨౩౪౫౬౭౮౯
+
+
+
+
+Tamil
+
+இராக்கில் அமெரிக்க மற்றும் பிரிட்டிஷ் துருப்புகளைக் கொன்ற வெடிமருந்துத் தொழில் நுட்பம் உட்பட பல்வேறு உதவிகளை இராக்கில் உள்ள தீவிரவாதிகளுக்கு இரான் வழங்கியதற்கான ஆதாரங்கள் அதிகரித்து வருவதை அமெரிக்கா கவனிக்கிறது என்று அமெரிக்க அரசுத் துறைத் துணைச் செயலர் நிக்கலஸ் பேர்ண்ஸ் கூறியிருக்கிறார்.
+
+௦௧௨௩௪௫௬௭௮௯
+
+
+
+Oriya
+ଓଡ଼ିଆ ଉଇକିପେଡିଆ ଆପଣଙ୍କୁ ସ୍ବାଗତ କରୁଛି। ଏହି ଉନ୍ମୁକ୍ତ ଜ୍ଞାନକୋଷଟି ଇଣ୍ଟରନେଟ ଉପରେ ଆଧାରିତ ଏବଂ ଏହା ବିଶ୍ବର ୫୦ଟି ଭାଷାରେ ଉପଲବ୍ଧ । ଏହାକୁ ଆପଣ ମଧ୍ୟ ବର୍ଦ୍ଧିତ ଓ ପରିବର୍ତିତ କରିପାରିବେ ଏବଂ ଏହାକୁ ଉନ୍ନତ କରିବା ପାଇଁ ନିଜର ଅବଦାନ ଦେଇ ପାରିବେ । ଆପଣଙ୍କ ପସନ୍ଦର ବିଷୟ ଗୁଡିକୁ ଆପଣ ନୂତନ ଭାବେରେ ଯୋଗ କରିପାରିବେ କିମ୍ବା ଏହି ପୃଷ୍ଠାକୁ ସମ୍ପାଦନ କରି ଏହା ସହିତ ଯୋଗ କରିପାରିବ । ସମସ୍ତ ପାଠ ଗୁଡିକ GNU ମୁକ୍ତ ଦଲିଲକରଣ ଲାଇସେନ୍ସର ସର୍ତ୍ତ ଅଧୀନରେ ଉପଲବ୍ଧ । ତଥାପି, ଆପଣ ଏହାକୁ ମୁକ୍ତ ଭାବେର ଇଲେକ୍ଟ୍ରୋନିକ୍ସ ପ୍ରିଣ୍ଟ୍ କିମ୍ବା ଅନ୍ୟାନ୍ୟ ପ୍ରିଣ୍ଟର ମାଧ୍ୟମରେ ବ୍ୟବହାର କରିପାରିବ ।
+
+୦୧୨୩୪୫୬୭୮୯
+
+
+Punjabi
+ਕੇਂਦਰੀ ਗ੍ਰਹਿਮੰਤਰੀ ਪੀ.ਚਿਦੰਬਰਮ ਨੇ ਐਤਵਾਰ ਨੂੰ ਤਮਿਲਨਾਢੂ ਦੇ ਮੁੱਖਮੰਤਰੀ ਐਮ.ਕਰੁਣਾਨਿਧੀ ਨਾਲ ਮੁਲਾਕਾਤ ਕੀਤੀ।ਉਨ੍ਹਾ ਨੇ ਸ਼੍ਰੀਲੰਕਾ \'ਚ ਲਿੱਟੇ ਦੇ ਖਿਲਾਫ਼ ਯੁੱਧ ਦੌਰਾਨ ਉੱਝੜੇ ਹੋਏ ਲੱਗਭਗ ਢਾਈ ਲੱਖ ਤਮਿਲਾਂ ਦੀ ਮੁੜ ਰਿਹਾਇਸ਼ \'ਤੇ ਚਰਚਾ ਕੀਤੀ।
+
+੦੧੨੩੪੫੬੭੮੯
+
+
+
+Gujarati
+આ વાત હજાર વાર કહેવામાં આવી છે કે ફિલ્મ બનાવતી વખેત હંમેશા સૌથી વધુ ધ્યાન વાર્તા અને સ્ક્રીનપ્લે પર આપવુ જોઈએ. કારણ કે આ કોઈ પણ ફિલ્મની સફળતાનો મુખ્ય આધાર હોય છે.
+
+૦૧૨૩૪૫૬૭૮૯
+
+
+
+Hindi
+भारत और बरमूडा के बीच बारिश के कारण रुका मैच दोबारा शुरु हो गया है. भारत ने बरमूडा के सामने रिकॉर्ड 414 रनों का लक्ष्य रखा है. बरमूडा ने दो विकेट खो दिए हैं.
+
+पाकिस्तान में सुप्रीम कोर्ट के मुख्य न्यायाधीश को निलंबित किए जाने के विरोध में कई जजों ने अपने पद से इस्तीफ़ा दे दिया है.
+
+०१२३४५६७८९
+
+
+Nepali - (Devanagari)
+अन्तरिम सरकारको गठनमा ढीलाइ हुनुका साथै आउंदो जेठ महिनाभित्र
+संविधानसभाको चुनाव होला कि नहोला भन्ने बहस चर्कीरहेको बेला चुनावकै विषयमा निर्वाचन आयोग र आठ दलको बेग्ला, बेग्लै भनाइ रहेको देखिएको छ।
+
+
+
+Bengali
+দক্ষিণ ওয়াজিরিস্থানে কর্মরত স্বেচ্ছাসেবী ও ত্রাণ সংস্থাগুলো ধারণা করছে সেনা অভিযানের তীব্রতা বাড়লে এই সংখ্যাটা আরও অনেক বেড়ে যাবে
+
+শরণার্থীদের স্রোত সামলাতে তারা ইতিমধ্যেই হিমশিম খাচ্ছেন, ফলে লড়াই থেকে পালিয়ে আসা বেসামরিক মানুষজনের সংখ্যা আরও বাড়লে স্বভাবতই সঙ্কট আরও জটিল হয়ে উঠবে
+
+০১২৩৪৫৬৭৮৯
+
+
+
+Assamese
+অসমীয়া ৱিকিপিডিয়াৰ উদ্দেশ্য হ\'ল সম্পূৰ্ণ অসমীয়া ভাষাত এখনি বিশ্বকোষ প্ৰণয়ন কৰা। অন্য কোনো ভাষাৰ প্ৰবন্ধ এই বিশ্বকোষৰ বাবে গ্ৰহন কৰা নহ\'ব। বিশ্বকোষৰ অৱদানকাৰীসকললৈ সাদৰেৰে অনুৰোধ জনোৱা হ\'ল যাতে তেখেতসকলে অসমীয়া ভাষাৰ প্ৰচলিত বানান পদ্ধতি মানি চলে। বিদেশী শব্দৰ অসমীয়া প্ৰতিৰূপৰ ক্ষেত্ৰত যিহেতু অসমীয়া সাহিত্যিকসকল এতিয়াও ঐক্যমতত উপনীত হ\'ব পৰা নাই, ৱিকিপিডিয়াত বিদেশী শব্দৰ যিকোনো ধৰনৰ অসমীয়া ৰূপ গ্ৰাহ্য কৰা হ\'ব।
+
+';
+//==============================================================
+//==============================================================
+//==============================================================
+include("../mpdf.php");
+
+$mpdf=new mPDF('');
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+exit;
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example33_unicode_supplementary_planes.php b/mpdf/examples/example33_unicode_supplementary_planes.php
new file mode 100644
index 0000000..b1e8709
--- /dev/null
+++ b/mpdf/examples/example33_unicode_supplementary_planes.php
@@ -0,0 +1,282 @@
+
+body {
+ font-family: sans-serif;
+ font-size: 10pt;
+}
+h4 {
+ font-variant: small-caps;
+}
+h5 {
+ margin-bottom: 0;
+ color: #110044;
+}
+dl {
+ margin: 0;
+}
+
+mPDF
+Unicode Supplementary Planes
+The original Unicode allocated characters between x0000 and xFFFF (65,536 characters). This \'Basic Multilingual Plane\' supported most characters in common use, including a large number of Unified Chinese-Japanese-Korean characters (CJK). Later the Unicode standard was extended to 16 Planes.
+
+The first plane (plane 0), the Basic Multilingual Plane (BMP), is where most characters have been assigned so far.
+Plane 1, the Supplementary Multilingual Plane (SMP), is mostly used for historic scripts such as Linear B, but is also used for musical and mathematical symbols.
+Plane 2, the Supplementary Ideographic Plane (SIP), is used for about 40,000 Unified Han (CJK) Ideographs.
+
+mPDF supports fonts containing characters from all Unicode Planes. By choosing the correct font, almost every single character from Unicode 5 can be displayed in a PDF file.
+
+Unicode Supplementary Multilingual Plane (SMP or Plane 1) U+10000 - U+1FFFF
+Gothic text
+
+This paragraph shows Gothic text. These characters lie in the Unicode Supplementary Multilingual Plane U+10330 - U+1034F.
+
+
+
+𐌰 𐌱 𐌲 𐌳 𐌴 𐌵 𐌶 𐌷 𐌸 𐌹 𐌺 𐌻 𐌼 𐌽 𐌾 𐌿 𐍀 𐍁 𐍂 𐍃 𐍄 𐍅 𐍆 𐍇 𐍈 𐍉 𐍊
+
+
+
+Font: MPH2BDamase (damase_v.2.ttf) available from: http://www.wazu.jp/gallery/views/View_MPH2BDamase.html
+
+
+Egyptian Hieroglyphics
+
+This paragraph shows Egyptian Hieroglyphics. These characters lie in the Unicode Supplementary Multilingual Plane U+13000 - U+1342F.
+
+
+
+𓀀 𓀁 𓀂 𓀃 𓀄 𓀅 𓀆 𓀇 𓀈 𓀉 𓀊 𓀋 𓀌 𓀍 𓀎 𓀏 𓀐 𓀑
+
+
+
+Font: Aegyptus.otf available from: http://users.teilar.gr/~g1951d/
+
+
+SMP contains mainly ancient scripts - see http://mpdf1.com/manual/index.php?tid=451 for full list.
+
+mPDF uses a different method to embed fonts in the PDF file if they include characters from SMP or SIP, because the characters cannot be represented by a 4 character hex code 0000-FFFF. This method is less eficient than the default method, and it can be suppressed by adding the font name to the array \'BMPonly\' in the config_fonts.php configuration file.
+
+Note that the DejaVu fonts distributed with mPDF and (GNU)FreeSans and FreeSerif fonts do contain a few characters in the SMP plane, but most users will not require them and by default they have been added to the array \'BMPonly\'.
+
+
+
+CJK characters
+Below are examples of all the CJK Unicode blocks contained in the Basic Multilingual Plane and Supplemental Ideographic Plane
+
+
+ Plane 0 (BMP)
+
+- CJK Radicals Supplement
+- ⺎ ⺏ ⺐ ⺑ ⺒ ⺓ ⺔ ⺕ ⺖ ⺗ ⺘ ⺙ ⺛ ⺜ ⺝ ⺞ ⺟ ⺠ ⺡ ⺢ ⺣ ⺤ ⺥ ⺦ ⺧ ⺨ ⺩ ⺪
+- Kangxi Radicals
+- ⼳ ⼴ ⼵ ⼶ ⼷ ⼸ ⼹ ⼺ ⼻ ⼼ ⼽ ⼾ ⼿ ⽀ ⽁ ⽂ ⽃ ⽄ ⽅ ⽆ ⽇ ⽈ ⽉ ⽊ ⽋ ⽌ ⽍
+- Ideographic Description Characters
+- ⿰ ⿱ ⿲ ⿳ ⿴ ⿵ ⿶ ⿷ ⿸ ⿹ ⿺ ⿻
+- CJK Symbols and Punctuation
+- 〈 〉 《 》 「 」 『 』 【 】 〒 〓 〔 〕 〖 〗 〘 〙 〚 〛 〜 〝 〞 〦 〧 〨 〩 〪
+- Hiragana
+- ぁ あ ぃ い ぅ う ぇ え ぉ お か が き ぎ く ぐ け げ こ ご さ ざ
+- Katakana
+- ゠ ァ ア ィ イ ゥ ウ ェ エ ォ オ カ ガ キ ギ ク グ ケ ゲ コ ゴ
+- Bopomofo
+- ㄅ ㄆ ㄇ ㄈ ㄉ ㄊ ㄋ ㄌ ㄍ ㄎ ㄏ ㄐ ㄑ ㄒ ㄓ ㄔ ㄕ ㄖ
+- Hangul Compatibility Jamo
+- ㄱ ㄲ ㄳ ㄴ ㄵ ㄶ ㄷ ㄸ ㄹ ㄺ ㄻ ㄼ ㄽ ㄾ ㄿ ㅀ ㅁ ㅂ
+- Kanbun
+- ㆐ ㆑ ㆒ ㆓ ㆔ ㆕ ㆖ ㆗ ㆘ ㆙ ㆚ ㆛ ㆜ ㆝ ㆞ ㆟
+- Bopomofo Extended
+- ㆠ ㆡ ㆢ ㆣ ㆤ ㆥ ㆦ ㆧ ㆨ ㆩ ㆪ ㆫ ㆬ ㆭ ㆮ ㆯ ㆰ ㆱ ㆲ ㆳ ㆴ ㆵ ㆶ ㆷ
+- Katakana Phonetic Extensions
+- ㇰ ㇱ ㇲ ㇳ ㇴ ㇵ ㇶ ㇷ ㇸ ㇹ ㇺ ㇻ ㇼ ㇽ ㇾ ㇿ
+- Enclosed CJK Letters and Months
+- ㈄ ㈅ ㈆ ㈇ ㈈ ㈉ ㈊ ㈋ ㈌ ㈍ ㈎ ㈏ ㈐ ㈑ ㈒ ㈓ ㈔ ㈕ ㈖ ㈗ ㈘ ㈙ ㈚ ㈛ ㈜
+- CJK Compatibility
+- ㌀ ㌁ ㌂ ㌃ ㌄ ㌅ ㌆ ㌇ ㌈ ㌉ ㌊ ㌋ ㌌ ㌍ ㌎ ㌏ ㌐ ㌑ ㌒ ㌓ ㌔ ㌕ ㌖ ㌗ ㌘
+- CJK Unified Ideographs Extension A
+- 㐀 㐁 㐂 㐃 㐄 㐅 㐆 㐇 㐈 㐉 㐊 㐋 㐌 㐍 㐎 㐏 㐐 㐑 㐒 㐓 㐔 㐕 㐖 㐗 㐘
+- CJK Unified Ideographs
+- 一 丁 丂 七 丄 丅 丆 万 丈 三 上 下 丌 不 与 丏 丐 丑 丒 专 且 丕 世 丗 丘
+- Yi Syllables
+- ꀀ ꀁ ꀂ ꀃ ꀄ ꀅ ꀆ ꀇ ꀈ ꀉ ꀊ ꀋ ꀌ ꀍ ꀎ ꀏ ꀐ ꀑ ꀒ ꀓ ꀔ ꀕ ꀖ ꀗ ꀘ ꀙ ꀚ
+- Yi Radicals
+- ꒐ ꒑ ꒒ ꒓ ꒔ ꒕ ꒖ ꒗ ꒘ ꒙ ꒚ ꒛ ꒜ ꒝ ꒞ ꒟ ꒠ ꒡ ꒢ ꒣ ꒤ ꒥ ꒦ ꒧ ꒨ ꒩
+- Hangul Syllables
+- 가 각 갂 갃 간 갅 갆 갇 갈 갉 갊 갋 갌 갍 갎 갏 감 갑 값 갓 갔 강 갖 갗 갘
+- CJK Compatibility Ideographs
+- 豈 更 車 賈 滑 串 句 龜 契 金 喇 奈 懶 癩 羅 蘿 螺 裸 邏 樂 洛 烙 珞 落 酪
+
+
+ Plane 2 (SIP)
+
+- CJK Unified Ideographs Extension B
+- 𠀀 𠀁 𠀂 𠀃 𠀄 𠀅 𠀆 𠀇 𠀈 𠀉 𠀊 𠀋 𠀌 𠀍 𠀎 𠀏 𠀐 𠀑 𠀒 𠀓
+
+- CJK Unified Ideographs Extension C
+- 𪜀 𪜁 𪜂 𪜃 𪜄 𪜅 𪜆 𪜇 𪜈 𪜉 𪜊 𪜋 𪜌 𪜍 𪜎 𪜏 𪜐 𪜑 𪜒 𪜓
+
+- CJK Compatibility Ideographs Supplement
+- 丽 丸 乁 𠄢 你 侮 侻 倂 偺 備 僧 像 㒞 𠘺 免 兔 兤 具 𠔜 㒹
+
+
+
+
+
+
+Using CJK fonts in mPDF
+
+Fonts containing CJK characters are large files, typically 10-30MB. Adobe provides a free download of an \'Asian font pack\' allowing you to create PDF files without including (embedding) the font information in the file. This keeps the file size to a minimum and minimises resource usage on your website generating the PDF file. However, users will have to download the Adobe font packs to read the file, and other PDF software will not display the text correctly.
+
+mPDF allows you to embed subsets of CJK fonts keeping file size down, although there is increased memory usage to generate these files.
+
+Some CJK fonts are broken up into 2 files because of the size of the files. One freely available font with almost complete coverage of all CJK characters (in both BMP and SIP) is \'Sun\' available from Alan Wood\'s excellent website: http://www.alanwood.net/unicode/fonts-east-asian.html. This comes as 2 files, Sun-ExtA and Sun-ExtB (both about 20MB in size) containing the characters from BMP and SIP respectively.
+
+
+mPDF allows you to treat these as one font by defining the second file as an SIP-extension of the first in the config_fonts.php configuration file. The following text includes random characters from the BMP and SIP mixed together:
+
+
+
+鼂 鼈 鼗 𣈏 𣈥 鼦 鼧 𣈯 𣈱 鼹 齄 𣈲 𣈳 齅 齐 𣈴 𣉖 齓 齚 𣉢 𣊁 齢 齩 𣊉 𣊊
+
+
+
+This is the entry in the config_fonts.php configuration file:
+
+$this->fontdata = array(
+...
+ "sun-exta" => array(
+ \'R\' => "Sun-ExtA.ttf",
+ \'sip-ext\' => \'sun-extb\',
+ ),
+ "sun-extb" => array(
+ \'R\' => "Sun-ExtB.ttf",
+ ),
+
+...
+);
+
+
+
+This is the HTML code - note only the sun-exta font-family needs to be referenced:
+
+<div style="font-family:sun-extA;">
+鼂 鼈 鼗 𣈏 𣈥 鼦 鼧 𣈯 𣈱 鼹 齄 𣈲 𣈳 齅 齐 𣈴 𣉖 齓 齚 𣉢 𣊁 齢 齩 𣊉 𣊊
+</div>
+
+
+NB You may also need to edit the value $this->useAdobeCJK=false in config.php or use new mPDF(\'-aCJK\'), and edit the config_cp.php configuration file.
+
+
+
+
+TrueType Collections
+
+TrueType Collections (.ttc files) contain more than one font. mPDF treats each font separately by defining the TTCfontID array in the config_fonts.php configuration file.
+
+This example uses the Windows MingLiU fonts, which consist of 2 files containing 6 fonts (note that mingliub is not a Bold variant):
+
+Font collection file (mingliu.ttc) contains the following fonts:
+[1] MingLiU (mingliu) Regular
+[2] PMingLiU (pmingliu) Regular (Proportional)
+[3] MingLiU_HKSCS (mingliu_hkscs) Regular
+
+
+Font collection file (mingliub.ttc) contains the following fonts:
+[1] MingLiU-ExtB (mingliu-extb) Regular
+[2] PMingLiU-ExtB (pmingliu-extb) Regular (Proportional)
+[3] MingLiU_HKSCS-ExtB (mingliu_hkscs-extb) Regular
+
+
+This is a sample entry in the config_fonts.php configuration file:
+
+$this->fontdata = array(
+ "mingliu" => array(
+ \'R\' => "mingliu.ttc",
+ \'TTCfontID\' => array (
+ \'R\' => 1,
+ ),
+ \'sip-ext\' => \'mingliu-extb\',
+ ),
+
+ "pmingliu" => array(
+ \'R\' => "mingliu.ttc",
+ \'TTCfontID\' => array (
+ \'R\' => 2,
+ ),
+ \'sip-ext\' => \'pmingliu-extb\',
+ ),
+
+ "mingliu_hkscs" => array(
+ \'R\' => "mingliu.ttc",
+ \'TTCfontID\' => array (
+ \'R\' => 3,
+ ),
+ \'sip-ext\' => \'mingliu_hkscs-extb\',
+ ),
+
+ "mingliu-extb" => array(
+ \'R\' => "mingliub.ttc",
+ \'TTCfontID\' => array (
+ \'R\' => 1,
+ ),
+ ),
+
+ "pmingliu-extb" => array(
+ \'R\' => "mingliub.ttc",
+ \'TTCfontID\' => array (
+ \'R\' => 2,
+ ),
+ ),
+
+ "mingliu_hkscs-extb" => array(
+ \'R\' => "mingliub.ttc",
+ \'TTCfontID\' => array (
+ \'R\' => 3,
+ ),
+ ),
+);
+
+
+
+This is sample HTML code:
+
+<div style="font-family:mingliu;">
+鼂 鼦 齄 齐 齢 齩 𣊉 𣊊
+</div>
+
+<div style="font-family:mingliu_hkscs;">
+鼂 鼦 齄 齐 齢 齩 𣊉 𣊊
+</div>
+
+<div style="font-family:pmingliu;">
+鼂 鼦 齄 齐 齢 齩 𣊉 𣊊
+</div>
+
+
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+include("../mpdf.php");
+
+$mpdf=new mPDF();
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+exit;
+
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example34_invoice_example.php b/mpdf/examples/example34_invoice_example.php
new file mode 100644
index 0000000..0bb41c2
--- /dev/null
+++ b/mpdf/examples/example34_invoice_example.php
@@ -0,0 +1,295 @@
+
+
+
+
+
+
+
+
+Date: 13th November 2008
+
+
+SOLD TO:
345 Anotherstreet Little Village Their City CB22 6SO |
+ |
+SHIP TO:
345 Anotherstreet Little Village Their City CB22 6SO |
+
+
+
+
+
+
+
+| Ref. No. |
+Quantity |
+Description |
+Unit Price |
+Amount |
+
+
+
+
+
+| MF1234567 |
+10 |
+Large pack Hoover bags |
+£2.56 |
+£25.60 |
+
+
+| MX37801982 |
+1 |
+Womans waterproof jacket Options - Red and charcoal. |
+£102.11 |
+£102.11 |
+
+
+| MR7009298 |
+25 |
+Steel nails; oval head; 30mm x 3mm. Packs of 1000. |
+£12.26 |
+£325.60 |
+
+
+| MF1234567 |
+10 |
+Large pack Hoover bags |
+£2.56 |
+£25.60 |
+
+
+| MX37801982 |
+1 |
+Womans waterproof jacket Options - Red and charcoal. |
+£102.11 |
+£102.11 |
+
+
+| MR7009298 |
+25 |
+Steel nails; oval head; 30mm x 3mm. Packs of 1000. |
+£12.26 |
+£325.60 |
+
+
+| MF1234567 |
+10 |
+Large pack Hoover bags |
+£2.56 |
+£25.60 |
+
+
+| MX37801982 |
+1 |
+Womans waterproof jacket Options - Red and charcoal. |
+£102.11 |
+£102.11 |
+
+
+| MR7009298 |
+25 |
+Steel nails; oval head; 30mm x 3mm. Packs of 1000. |
+£12.26 |
+£325.60 |
+
+
+| MF1234567 |
+10 |
+Large pack Hoover bags |
+£2.56 |
+£25.60 |
+
+
+| MX37801982 |
+1 |
+Womans waterproof jacket Options - Red and charcoal. |
+£102.11 |
+£102.11 |
+
+
+| MR7009298 |
+25 |
+Steel nails; oval head; 30mm x 3mm. Packs of 1000. |
+£12.26 |
+£325.60 |
+
+
+| MF1234567 |
+10 |
+Large pack Hoover bags |
+£2.56 |
+£25.60 |
+
+
+| MX37801982 |
+1 |
+Womans waterproof jacket Options - Red and charcoal. |
+£102.11 |
+£102.11 |
+
+
+| MF1234567 |
+10 |
+Large pack Hoover bags |
+£2.56 |
+£25.60 |
+
+
+| MX37801982 |
+1 |
+Womans waterproof jacket Options - Red and charcoal. |
+£102.11 |
+£102.11 |
+
+
+| MR7009298 |
+25 |
+Steel nails; oval head; 30mm x 3mm. Packs of 1000. |
+£12.26 |
+£325.60 |
+
+
+| MR7009298 |
+25 |
+Steel nails; oval head; 30mm x 3mm. Packs of 1000. |
+£12.26 |
+£325.60 |
+
+
+| MF1234567 |
+10 |
+Large pack Hoover bags |
+£2.56 |
+£25.60 |
+
+
+| MX37801982 |
+1 |
+Womans waterproof jacket Options - Red and charcoal. |
+£102.11 |
+£102.11 |
+
+
+| MR7009298 |
+25 |
+Steel nails; oval head; 30mm x 3mm. Packs of 1000. |
+£12.26 |
+£325.60 |
+
+
+
+ |
+Subtotal: |
+£1825.60 |
+
+
+| Tax: |
+£18.25 |
+
+
+| Shipping: |
+£42.56 |
+
+
+| TOTAL: |
+£1882.56 |
+
+
+| Deposit: |
+£100.00 |
+
+
+| Balance due: |
+£1782.56 |
+
+
+
+
+
+Payment terms: payment due in 30 days
+
+
+
+
+';
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+define('_MPDF_PATH','../');
+include("../mpdf.php");
+
+$mpdf=new mPDF('c','A4','','',20,15,48,25,10,10);
+$mpdf->SetProtection(array('print'));
+$mpdf->SetTitle("Acme Trading Co. - Invoice");
+$mpdf->SetAuthor("Acme Trading Co.");
+$mpdf->SetWatermarkText("Paid");
+$mpdf->showWatermarkText = true;
+$mpdf->watermark_font = 'DejaVuSansCondensed';
+$mpdf->watermarkTextAlpha = 0.1;
+$mpdf->SetDisplayMode('fullpage');
+
+
+
+$mpdf->WriteHTML($html);
+
+
+$mpdf->Output(); exit;
+
+exit;
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example35_watermarks.php b/mpdf/examples/example35_watermarks.php
new file mode 100644
index 0000000..a4c1ae6
--- /dev/null
+++ b/mpdf/examples/example35_watermarks.php
@@ -0,0 +1,58 @@
+mPDF
+Watermarks
+P: Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+
+
+
+DIV: Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim.
+DIV: Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim.
+
+Blockquote: Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus.
+
+Address: Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus.
+
+';
+
+
+//==============================================================
+//==============================================================
+//==============================================================
+
+include("../mpdf.php");
+
+$mpdf=new mPDF('c');
+
+$mpdf->SetDisplayMode('fullpage');
+
+$mpdf->SetWatermarkText('DRAFT');
+$mpdf->watermark_font = 'DejaVuSansCondensed';
+$mpdf->showWatermarkText = true;
+
+$mpdf->WriteHTML($html);
+$mpdf->AddPage();
+
+$mpdf->SetWatermarkImage('tiger.wmf', 1, '', array(160,10));
+$mpdf->showWatermarkImage = true;
+
+$mpdf->WriteHTML('Using a Watermark as a Header');
+$mpdf->WriteHTML($html);
+$mpdf->AddPage();
+
+$mpdf->SetWatermarkImage('tiger.wmf', 0.15, 'F');
+
+$mpdf->WriteHTML('Using a Watermark Image as Background');
+$mpdf->WriteHTML($html);
+
+
+$mpdf->Output();
+exit;
+
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example36_annotations_and_Attached_files.php b/mpdf/examples/example36_annotations_and_Attached_files.php
new file mode 100644
index 0000000..63e8c5d
--- /dev/null
+++ b/mpdf/examples/example36_annotations_and_Attached_files.php
@@ -0,0 +1,36 @@
+mPDF
+Annotations
+Heading 5
+Heading 6
+P: Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+
+';
+//==============================================================
+//==============================================================
+//==============================================================
+include("../mpdf.php");
+
+$mpdf=new mPDF('c');
+
+$mpdf->title2annots = true;
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+
+exit;
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example37_barcodes.php b/mpdf/examples/example37_barcodes.php
new file mode 100644
index 0000000..34ec882
--- /dev/null
+++ b/mpdf/examples/example37_barcodes.php
@@ -0,0 +1,437 @@
+
+
+
+
+
+
+
+
+mPDF
+Barcodes
+NB Quiet zones - The barcode object includes space to the right/left or top/bottom only when the specification states a \'quiet zone\' or \'light margin\'. All the examples below also have CSS property set on the barcode object i.e. padding: 1.5mm;
+
+EAN-13 Barcodes (EAN-2 and EAN-5)
+NB EAN-13, UPC-A, UPC-E, and EAN-8 may all include an additional bar code(EAN-2 and EAN-5) to the right of the main bar code (see below).
+A nominal height and width for these barcodes is defined by the specification. \'size\' will scale both the height and width. Values between 0.8 and 2 are allowed (i.e. 80% to 200% of the nominal size). \'height\' can also be varied as a factor of 1; this is applied after the scaling factor used for \'size\'.
+
+
+
+| CODE |
+DESCRIPTION |
+BARCODE |
+
+
+
+
+
+| EAN13 |
+Standard EAN-13 barcode. Accepts 12 or 13 characters (creating checksum digit if required). [0-9] numeric only. |
+ |
+
+
+| ISBN |
+Standard EAN-13 barcode with \'ISBN\' number shown above [shown at height="0.66"] |
+ |
+
+
+| ISSN |
+Standard EAN-13 barcode with \'ISSN\' number shown above [shown at size="0.8"] |
+ |
+
+
+
+
+EAN-8, UPC-A and UPC-E Barcodes
+UPC-A, UPC-E, EAN-13, and EAN-8 may all include an additional bar code(EAN-2 and EAN-5) to the right of the main bar code (see below).
+A nominal height and width for these barcodes is defined by the specification. \'size\' will scale both the height and width. Values between 0.8 and 2 are allowed (i.e. 80% to 200% of the nominal size). \'height\' can also be varied as a factor of 1; this is applied after the scaling factor used for \'size\'.
+
+
+
+| CODE |
+DESCRIPTION |
+BARCODE |
+
+
+
+
+
+| UPCA |
+UPC-A barcode. This is a subset of the EAN-13. (098277211236) Accepts 11 or 12 characters (creating checksum digit if required). [0-9] numeric only |
+ |
+
+
+| UPCE |
+UPC-E barcode. Requires the UPC-A code to be entered as above (e.g. 042100005264 to give 425261). NB mPDF will die with an error message if the code is not valid, as only some UPC-A codes can be converted into valid UPC-E codes. UPC-E doesn\'t have a check digit encoded explicity, rather the check digit is encoded in the parity of the other six characters. The check digit that is encoded is the check digit from the original UPC-A barcode. |
+ |
+
+
+| EAN8 |
+EAN-8. Accepts 7 or 8 characters (creating checksum digit if required). [0-9] numeric only |
+ |
+
+
+
+
+EAN-2 and EAN-5 supplements, and combined forms
+UPC-A, UPC-E, EAN-13, and EAN-8 may all include an additional bar code(EAN-2 and EAN-5) to the right of the main bar code.
+
+
+
+| CODE |
+DESCRIPTION |
+BARCODE |
+
+
+
+
+
+| EAN2 |
+EAN-2 supplement barcode. mPDF does not generate EAN-5 barcode on its own; see supplements below. Used to denote an issue of a periodical. EAN-2 supplement accepts 2 digits [0-9] only, EAN-5 five. |
+
+
+| EAN5 |
+EAN-5 supplement barcode. mPDF does not generate EAN-5 barcode on its own; see supplements below. Usually used in conjunction with EAN-13 for the price of books. 90000 is the code for no price. |
+
+
+| EAN13P2 |
+Standard EAN-13 barcode with 2-digit UPC supplement (07) |
+ |
+
+
+| ISBNP2 |
+Standard EAN-13 barcode with \'ISBN\' number shown above, and 2-digit EAN-2 supplement |
+ |
+
+
+| ISSNP2 |
+Standard EAN-13 barcode with \'ISSN\' number shown above, and 2-digit EAN-2 supplement |
+ |
+
+
+| UPCAP2 |
+UPC-A barcode with 2-digit EAN-2 supplement. This is a subset of the EAN-13. |
+ |
+
+
+| UPCEP2 |
+UPC-E barcode with 2-digit EAN-2 supplement. |
+ |
+
+
+| EAN8P2 |
+EAN-8 barcode with 2-digit EAN-2 supplement |
+ |
+
+
+| EAN13P5 |
+Standard EAN-13 barcode with 5-digit UPC supplement (90000) |
+ |
+
+
+| ISBNP5 |
+Standard EAN-13 barcode with \'ISBN\' number shown above, and 5-digit EAN-5 supplement |
+ |
+
+
+| ISSNP5 |
+Standard EAN-13 barcode with \'ISSN\' number shown above, and 5-digit EAN-5 supplement |
+ |
+
+
+| UPCAP5 |
+UPC-A barcode with 5-digit EAN-5 supplement. This is a subset of the EAN-13 |
+ |
+
+
+| UPCEP5 |
+UPC-E barcode with 5-digit EAN-5 supplement. (042100005264 90000) |
+ |
+
+
+| EAN8P5 |
+EAN-8 barcode with 5-digit EAN-5 supplement (55123457 90000) |
+ |
+
+
+
+
+Postcode Barcodes
+These all have sizes fixed by their specification. Although they can be altered using \'size\' it is not recommended. \'height\' is ignored.
+
+
+
+| CODE |
+DESCRIPTION |
+BARCODE |
+
+
+
+
+
+| IMB |
+Intelligent Mail Barcode - also known as: USPS OneCode 4-State Customer Barcode, OneCode 4CB, USPS 4CB, 4-CB, 4-State Customer Barcode, USPS OneCode Solution Barcode. (01234567094987654321-01234567891) Accepts: Up to 31 digits (required 20-digit Tracking Code, and up to 11-digit Routing Code; this may be 0, 5, 9, or 11 digits). If the Routing code is included, it should be spearated by a hyphen - like this example. |
+ |
+
+
+| RM4SCC |
+Royal Mail 4-state Customer barcode (SN34RD1A). Accepts: max. 9 characters. Valid characters: [A-Z,0-9] Checksum digit: automatic. |
+ |
+
+
+| KIX |
+Dutch KIX version of Royal Mail 4-state Customer barcode (SN34RD1A). Valid characters: [A-Z,0-9]. Checksum digit: automatic. |
+ |
+
+
+| POSTNET |
+POSTNET barcode. Accepts 5, 9 or 11 digits. Valid characters: [0-9]. Checksum digit: automatic. |
+ |
+
+
+| PLANET |
+PLANET barcode. Accepts 11 or 13 digits. Valid characters: [0-9]. Checksum digit: automatic. |
+ |
+
+
+
+
+
+Variable width Barcodes
+These barcodes are all of variable length depending on the code entered. There is no recommended maximum size for any of these specs, but all recommend a minimum X-dimension (width of narrowest bar) as 7.5mil (=0.19mm). The default used here is twice the minimum i.e. X-dim = 0.38mm.
+The specifications give a minimum height of 15% of the barcode length (which can be variable). The bar height in mPDF is set to a default value of 10mm.
+\'size\' will scale the barcode in both dimensions. mPDF will accept any number, but bear in mind that size="0.5" will set the bar width to the minimum. The \'height\' attribute further allows scaling - this factor is applied to already scaled barcode. Thus size="2" height="0.5" will give a barcode twice the default width (X-dim=0.76mm) and at the default height set in mPDF i.e. 10mm.
+
+
+
+| CODE |
+DESCRIPTION |
+BARCODE |
+
+
+
+
+| C128A |
+CODE 128 A. Valid characters: [A-Z uppercase and control chars ASCII 0-31]. Checksum digit: automatic. |
+ |
+
+
+| C128B |
+CODE 128 B. Valid characters: [Upper / Lower Case + All ASCII Printable Characters]. Checksum digit: automatic. |
+ |
+
+
+| C128C |
+CODE 128 C. Valid characters: [0-9]. Must be an even number of digits. Checksum digit: automatic. |
+ |
+
+
+
+| EAN128C [A/B/C] |
+EAN128 (A, B, and C). Specified variant of Code 128, utilising an FNC1 start code. Also known as UCC/EAN-128 or GS1-128. Valid characters: [cf. Code 128]. Checksum digit: automatic. |
+ |
+
+
+
+| C39 |
+CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9. Valid characters: [0-9 A-Z \'-\' . Space $/+%] |
+ |
+
+
+| C39+ |
+CODE 39 + CHECKSUM. Checksum digit: automatic. |
+ |
+
+
+| C39E |
+CODE 39 EXTENDED. Valid characters: [ASCII-characters between 0..127] |
+ |
+
+
+| C39E+ |
+CODE 39 EXTENDED + CHECKSUM. Checksum digit: automatic. |
+ |
+
+
+
+| S25 |
+Standard 2 of 5. Valid characters: [0-9] |
+ |
+
+
+| S25+ |
+Standard 2 of 5 + CHECKSUM. Valid characters: [0-9]. Checksum digit: automatic. |
+ |
+
+
+| I25 |
+Interleaved 2 of 5. Valid characters: [0-9] |
+ |
+
+
+| I25+ |
+Interleaved 2 of 5 + CHECKSUM. Valid characters: [0-9]. Checksum digit: automatic. |
+ |
+
+
+| I25B |
+Interleaved 2 of 5 with bearer bars. Valid characters: [0-9] |
+ |
+
+
+| I25B+ |
+Interleaved 2 of 5 + CHECKSUM with bearer bars. Valid characters: [0-9]. Checksum digit: automatic. |
+ |
+
+
+
+| C93 |
+CODE 93 - USS-93 (extended). Valid characters: [ASCII-characters between 0..127]. Checksum digits: automatic. |
+ |
+
+
+
+| MSI |
+MSI. Modified Plessey. Valid characters: [0-9] |
+ |
+
+
+| MSI+ |
+MSI + CHECKSUM (module 11). Checksum digit: automatic. |
+ |
+
+
+
+| CODABAR |
+CODABAR. Valid characters: [0-9 \'-\' $:/.+ ABCD] ABCD are used as stop and start characters e.g. A34698735B |
+ |
+
+
+
+| CODE11 |
+CODE 11. Valid characters: [0-9 and \'-\']. Checksum digits: 1 (or 2 if length of code is > 10 characters) - automatic. |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Human-readable text
+Human-readable text is only produced as part of the barcode object in EAN-13, ISBN, ISSN, EAN-8, UPC-A and UPC-E. Here is an example to add text to a barcode:
+
+
+
+
+<div style="position:fixed; right: 50mm; top: 60mm; border: 0.2mm solid #000000; text-align: center; padding: 0.5mm; padding-top: 2mm;">
+<barcode code="00034698735346987355" type="EAN128C" /><br />
+<div style="font-family: ocrb;">(00) 0346987 35346987 355</div>
+</div>
+
+
+
+
+
+ (00) 0346987 35346987 355
+
+
+
+
+';
+//==============================================================
+//==============================================================
+include("../mpdf.php");
+
+$mpdf=new mPDF('','','','',20,15,25,25,10,10);
+$mpdf->WriteHTML($html);
+$mpdf->Output();
+
+exit;
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example38_dot_tab.php b/mpdf/examples/example38_dot_tab.php
new file mode 100644
index 0000000..6d9d425
--- /dev/null
+++ b/mpdf/examples/example38_dot_tab.php
@@ -0,0 +1,43 @@
+
+dottab.menu {
+ outdent: 4em;
+}
+p.menu {
+ text-align: left;
+ padding-right: 4em;
+}
+
+
+Menu
+
+
+
+
+
+
+
+
+
+
+
+
+';
+
+
+include("../mpdf.php");
+
+$mpdf=new mPDF();
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+
+exit;
+
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example39_PDFA_compliance.php b/mpdf/examples/example39_PDFA_compliance.php
new file mode 100644
index 0000000..f43b023
--- /dev/null
+++ b/mpdf/examples/example39_PDFA_compliance.php
@@ -0,0 +1,31 @@
+mPDF
+PDFA Compliance
+PDF/A1-b is a file format for the long-term archiving of electronic documents. This is an example of a PDF/A1-b compliant files.
+';
+//==============================================================
+//==============================================================
+//==============================================================
+include("../mpdf.php");
+
+$mpdf=new mPDF();
+
+$mpdf->PDFA = true;
+$mpdf->PDFAauto = true;
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+
+exit;
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example40_MPDFI_thumbnails.php b/mpdf/examples/example40_MPDFI_thumbnails.php
new file mode 100644
index 0000000..709ea8d
--- /dev/null
+++ b/mpdf/examples/example40_MPDFI_thumbnails.php
@@ -0,0 +1,20 @@
+SetImportUse();
+
+$mpdf->Thumbnail('sample_orientation2.pdf', 4, 5); // number per row // spacing in mm
+
+$mpdf->WriteHTML('Now with rotated pages ');
+
+$mpdf->Thumbnail('sample_orientation3.pdf', 4); // number per row // spacing in mm
+
+
+$mpdf->Output();
+
+exit;
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example41_MPDFI_template.php b/mpdf/examples/example41_MPDFI_template.php
new file mode 100644
index 0000000..12f592d
--- /dev/null
+++ b/mpdf/examples/example41_MPDFI_template.php
@@ -0,0 +1,36 @@
+SetImportUse();
+
+$mpdf->SetDisplayMode('fullpage');
+
+$mpdf->SetCompression(false);
+
+// Add First page
+$pagecount = $mpdf->SetSourceFile('sample_basic.pdf');
+
+$crop_x = 50;
+$crop_y = 50;
+$crop_w = 100;
+$crop_h = 100;
+
+$tplIdx = $mpdf->ImportPage(2, $crop_x, $crop_y, $crop_w, $crop_h);
+
+$x = 50;
+$y = 50;
+$w = 100;
+$h = 100;
+
+$mpdf->UseTemplate($tplIdx, $x, $y, $w, $h);
+
+$mpdf->Rect($x, $y, $w, $h);
+
+$mpdf->Output('newpdf.pdf', 'I');
+
+exit;
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example42_MPDFI_templatedoc.php b/mpdf/examples/example42_MPDFI_templatedoc.php
new file mode 100644
index 0000000..2b670ca
--- /dev/null
+++ b/mpdf/examples/example42_MPDFI_templatedoc.php
@@ -0,0 +1,35 @@
+SetImportUse();
+
+$mpdf->SetDocTemplate('sample_logoheader2.pdf',1); // 1|0 to continue after end of document or not - used on matching page numbers
+
+//===================================================
+$mpdf->AddPage();
+$mpdf->WriteHTML('Hallo World');
+$mpdf->AddPage();
+$mpdf->WriteHTML('Hallo World');
+$mpdf->AddPage();
+$mpdf->WriteHTML('Hallo World');
+//===================================================
+
+$mpdf->RestartDocTemplate();
+
+//===================================================
+$mpdf->AddPage();
+$mpdf->WriteHTML('Hallo World');
+$mpdf->AddPage();
+$mpdf->WriteHTML('Hallo World');
+$mpdf->AddPage();
+$mpdf->WriteHTML('Hallo World');
+//===================================================
+
+
+$mpdf->Output();
+
+exit;
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example43_MPDFI_booklet.php b/mpdf/examples/example43_MPDFI_booklet.php
new file mode 100644
index 0000000..8144a3a
--- /dev/null
+++ b/mpdf/examples/example43_MPDFI_booklet.php
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+mPDF Example Booklet
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+
+
+Sed bibendum. Nunc eleifend ornare velit. Sed consectetuer urna in erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Mauris sodales semper metus. Maecenas justo libero, pretium at, malesuada eu, mollis et, arcu. Ut suscipit pede in nulla. Praesent elementum, dolor ac fringilla posuere, elit libero rutrum massa, vel tincidunt dui tellus a ante. Sed aliquet euismod dolor. Vestibulum sed dui. Duis lobortis hendrerit quam. Donec tempus orci ut libero. Pellentesque suscipit malesuada nisi.
+
+Little Women - Chapter One - Playing Pilgrims
+
+ Christmas won\'t be Christmas without any presents, grumbled Jo, lying on the rug. It\'s so dreadful to be poor! sighed Meg, looking down at her old dress. I don\'t think it\'s fair for some girls to have plenty of pretty things, and other girls nothing at all, added little Amy, with an injured sniff. We\'ve got Father and Mother, and each other, said Beth contentedly from her corner. The four young faces on which the firelight shone brightened at the cheerful words, but darkened again as Jo said sadly, We haven\'t got Father, and shall not have him for a long time. She didn\'t say perhaps never, but each silently added it, thinking of Father far away, where the fighting was. Nobody spoke for a minute; then Meg said in an altered tone, You know the reason Mother proposed not having any presents this Christmas was because it is going to be a hard winter for everyone; and she thinks we ought not to spend money for pleasure, when our men are suffering so in the army. We can\'t do much, but we can make our little sacrifices, and ought to do it gladly. But I am afraid I don\'t And Meg shook her head, as she thought regretfully of all the pretty things she wanted. But I don\'t think the little we should spend would do any good. We\'ve each got a dollar, and the army wouldn\'t be much helped by our giving that. I agree not to expect anything from Mother or you, but I do want to buy UNDINE AND SINTRAM for myself. I\'ve wanted it so long, said Jo, who was a bookworm. I planned to spend mine in new music, said Beth, with a little sigh, which no one heard but the hearth brush and kettle holder. I shall get a nice box of Faber\'s drawing pencils. I really need them, said Amy decidedly. Mother didn\'t say anything about our money, and she won\'t wish us to give up everything. Let\'s each buy what we want, and have a little fun. I\'m sure we work hard enough to earn it, cried Jo, examining the heels of her shoes in a gentlemanly manner. I know I do—teaching those tiresome children nearly all day, when I\'m longing to enjoy myself at home, began Meg, in the complaining tone again. You don\'t have half such a hard time as I do, said Jo. How would you like to be shut up for hours with a nervous, fussy old lady, who keeps you trotting, is never satisfied, and worries you till you you\'re ready to fly out the window or cry? It\'s naughty to fret, but I do think washing dishes and keeping things tidy is the worst work in the world. It makes me cross, and my hands get so stiff, I can\'t practice well at all. And Beth looked at her rough hands with a sigh that any one could hear that time. I don\'t believe any of you suffer as I do, cried Amy, for you don\'t have to go to school with impertinent girls, who plague you if you don\'t know your lessons, and laugh at your dresses, and label your father if he isn\'t rich, and insult you when your nose isn\'t nice. If you mean libel, I\'d say so, and not talk about labels, as if Papa was a pickle bottle, advised Jo, laughing. I know what I mean, and you needn\'t be satirical about it. It\'s proper to use good words, and improve your vocabulary, returned Amy, with dignity. Don\'t peck at one another, children. Don\'t you wish we had the money Papa lost when we were little, Jo? Dear me! How happy and good we\'d be, if we had no worries! said Meg, who could remember better times. You said the other day you thought we were a deal happier than the King children, for they were fighting and fretting all the time, in spite of their money. So I did, Beth. Well, I think we are. For though we do have to work, we make fun of ourselves, and are a pretty jolly set, as Jo would say. Jo does use such slang words! observed Amy, with a reproving look at the long figure stretched on the rug. Jo immediately sat up, put her hands in her pockets, and began to whistle. Don\'t, Jo. It\'s so boyish! That\'s why I do it. I detest rude, unladylike girls! I hate affected, niminy-piminy chits! Birds in their little nests agree, sang Beth, the peacemaker, with such a funny face that both sharp voices softened to a laugh, and the pecking ended for that time. Really, girls, you are both to be blamed, said Meg, beginning to lecture in her elder-sisterly fashion. You are old enough to leave off boyish tricks, and to behave better, Josephine. It didn\'t matter so much when you were a little girl, but now you are so tall, and turn up your hair, you should remember that you are a young lady. I\'m not! And if turning up my hair makes me one, I\'ll wear it in two tails till I\'m twenty, cried Jo, pulling off her net, and shaking down a chestnut mane. I hate to think I\'ve got to grow up, and be Miss March, and wear long gowns, and look as prim as a China Aster! It\'s bad enough to be a girl, anyway, when I like boy\'s games and work and manners! I can\'t get over my disappointment in not being a boy. And it\'s worse than ever now, for I\'m dying to go and fight with Papa. And I can only stay home and knit, like a poky old woman! And Jo shook the blue army sock till the needles rattled like castanets, and her ball bounded across the room. Poor Jo! It\'s too bad, but it can\'t be helped. So you must try to be contented with making your name boyish, and playing brother to us girls, said Beth, stroking the rough head with a hand that all the dish washing and dusting in the world could not make ungentle in its touch. As for you, Amy, continued Meg, you are altogether to particular and prim. Your airs are funny now, but you\'ll grow up an affected little goose, if you don\'t take care. I I like your nice manners and refined ways of speaking, when you don\'t try to be elegant. But your absurd words are as bad as Jo\'s slang. If Jo is a tomboy and Amy a goose, what am I, please? asked Beth, ready to share the lecture. You\'re a dear, and nothing else, answered Meg warmly, and no one contradicted her, for the \'Mouse\' was the pet of the family.
+
+Little Women - Chapter One - Playing Pilgrims
+
+ Christmas won\'t be Christmas without any presents, grumbled Jo, lying on the rug. It\'s so dreadful to be poor! sighed Meg, looking down at her old dress. I don\'t think it\'s fair for some girls to have plenty of pretty things, and other girls nothing at all, added little Amy, with an injured sniff. We\'ve got Father and Mother, and each other, said Beth contentedly from her corner. The four young faces on which the firelight shone brightened at the cheerful words, but darkened again as Jo said sadly, We haven\'t got Father, and shall not have him for a long time. She didn\'t say perhaps never, but each silently added it, thinking of Father far away, where the fighting was. Nobody spoke for a minute; then Meg said in an altered tone, You know the reason Mother proposed not having any presents this Christmas was because it is going to be a hard winter for everyone; and she thinks we ought not to spend money for pleasure, when our men are suffering so in the army. We can\'t do much, but we can make our little sacrifices, and ought to do it gladly. But I am afraid I don\'t And Meg shook her head, as she thought regretfully of all the pretty things she wanted. But I don\'t think the little we should spend would do any good. We\'ve each got a dollar, and the army wouldn\'t be much helped by our giving that. I agree not to expect anything from Mother or you, but I do want to buy UNDINE AND SINTRAM for myself. I\'ve wanted it so long, said Jo, who was a bookworm. I planned to spend mine in new music, said Beth, with a little sigh, which no one heard but the hearth brush and kettle holder. I shall get a nice box of Faber\'s drawing pencils. I really need them, said Amy decidedly. Mother didn\'t say anything about our money, and she won\'t wish us to give up everything. Let\'s each buy what we want, and have a little fun. I\'m sure we work hard enough to earn it, cried Jo, examining the heels of her shoes in a gentlemanly manner. I know I do—teaching those tiresome children nearly all day, when I\'m longing to enjoy myself at home, began Meg, in the complaining tone again. You don\'t have half such a hard time as I do, said Jo. How would you like to be shut up for hours with a nervous, fussy old lady, who keeps you trotting, is never satisfied, and worries you till you you\'re ready to fly out the window or cry? It\'s naughty to fret, but I do think washing dishes and keeping things tidy is the worst work in the world. It makes me cross, and my hands get so stiff, I can\'t practice well at all. And Beth looked at her rough hands with a sigh that any one could hear that time. I don\'t believe any of you suffer as I do, cried Amy, for you don\'t have to go to school with impertinent girls, who plague you if you don\'t know your lessons, and laugh at your dresses, and label your father if he isn\'t rich, and insult you when your nose isn\'t nice. If you mean libel, I\'d say so, and not talk about labels, as if Papa was a pickle bottle, advised Jo, laughing. I know what I mean, and you needn\'t be satirical about it. It\'s proper to use good words, and improve your vocabulary, returned Amy, with dignity. Don\'t peck at one another, children. Don\'t you wish we had the money Papa lost when we were little, Jo? Dear me! How happy and good we\'d be, if we had no worries! said Meg, who could remember better times. You said the other day you thought we were a deal happier than the King children, for they were fighting and fretting all the time, in spite of their money. So I did, Beth. Well, I think we are. For though we do have to work, we make fun of ourselves, and are a pretty jolly set, as Jo would say. Jo does use such slang words! observed Amy, with a reproving look at the long figure stretched on the rug. Jo immediately sat up, put her hands in her pockets, and began to whistle. Don\'t, Jo. It\'s so boyish! That\'s why I do it. I detest rude, unladylike girls! I hate affected, niminy-piminy chits! Birds in their little nests agree, sang Beth, the peacemaker, with such a funny face that both sharp voices softened to a laugh, and the pecking ended for that time. Really, girls, you are both to be blamed, said Meg, beginning to lecture in her elder-sisterly fashion. You are old enough to leave off boyish tricks, and to behave better, Josephine. It didn\'t matter so much when you were a little girl, but now you are so tall, and turn up your hair, you should remember that you are a young lady. I\'m not! And if turning up my hair makes me one, I\'ll wear it in two tails till I\'m twenty, cried Jo, pulling off her net, and shaking down a chestnut mane. I hate to think I\'ve got to grow up, and be Miss March, and wear long gowns, and look as prim as a China Aster! It\'s bad enough to be a girl, anyway, when I like boy\'s games and work and manners! I can\'t get over my disappointment in not being a boy. And it\'s worse than ever now, for I\'m dying to go and fight with Papa. And I can only stay home and knit, like a poky old woman! And Jo shook the blue army sock till the needles rattled like castanets, and her ball bounded across the room. Poor Jo! It\'s too bad, but it can\'t be helped. So you must try to be contented with making your name boyish, and playing brother to us girls, said Beth, stroking the rough head with a hand that all the dish washing and dusting in the world could not make ungentle in its touch. As for you, Amy, continued Meg, you are altogether to particular and prim. Your airs are funny now, but you\'ll grow up an affected little goose, if you don\'t take care. I I like your nice manners and refined ways of speaking, when you don\'t try to be elegant. But your absurd words are as bad as Jo\'s slang. If Jo is a tomboy and Amy a goose, what am I, please? asked Beth, ready to share the lecture. You\'re a dear, and nothing else, answered Meg warmly, and no one contradicted her, for the \'Mouse\' was the pet of the family.
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+include("../mpdf.php");
+
+$mpdf=new mPDF('c','A4','','',32,25,27,25,16,13);
+
+$mpdf->mirrorMargins = 1;
+$mpdf->SetDisplayMode('fullpage','two');
+$mpdf->useOnlyCoreFonts = true;
+$mpdf->defaultfooterfontsize = 13;
+$mpdf->AddPage();
+$mpdf->Image('clematis.jpg',0,0,210,297,'jpg','',true, false); // e.g. the last "false" allows a full page picture
+$mpdf->y = 70;
+$mpdf->Shaded_box('mPDF Example File', 'Arial', '', 28, '70%', 'DF', 3, '#FFFFFF', '#000044', 10);
+
+$mpdf->AddPage();
+$mpdf->SetFooter('{PAGENO}');
+$mpdf->WriteHTML($html);
+
+
+$mpdf->AddPage('','NEXT-EVEN');
+$mpdf->SetFooter();
+$mpdf->SetAlpha(0.5);
+$mpdf->Image('clematis.jpg',0,0,210,297,'jpg','',true, false); // e.g. the last "false" allows a full page picture
+$mpdf->SetAlpha(1);
+
+$mpdf->writeBarcode('978-0-9542246-0-8', 1, 130, 230, 1,0, 3,3,4,4);
+
+// Save the pages to a file
+$mpdf->Output('test.pdf','F');
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+function GetBookletPages($np, $backcover=true) {
+ $lastpage = $np;
+ $np = 4*ceil($np/4);
+ $pp = array();
+ for ($i=1; $i<=$np/2; $i++) {
+ $p1 = $np - $i + 1;
+ if ($backcover) {
+ if ($i == 1) { $p1 = $lastpage; }
+ else if ($p1 >= $lastpage) { $p1 = 0; }
+ }
+ if ($i % 2 == 1) {
+ $pp[] = array( $p1, $i );
+ }
+ else {
+ $pp[] = array( $i, $p1 );
+ }
+ }
+ return $pp;
+}
+
+
+
+$mpdf=new mPDF('','A4-L','','',0,0,0,0,0,0);
+$mpdf->SetImportUse();
+$ow = $mpdf->h;
+$oh = $mpdf->w;
+$pw = $mpdf->w / 2;
+$ph = $mpdf->h;
+
+$mpdf->SetDisplayMode('fullpage');
+
+$pagecount = $mpdf->SetSourceFile('test.pdf');
+$pp = GetBookletPages($pagecount);
+
+foreach($pp AS $v) {
+ $mpdf->AddPage();
+ if ($v[0]>0 && $v[0]<=$pagecount) {
+ $tplIdx = $mpdf->ImportPage($v[0], 0,0,$ow,$oh);
+ $mpdf->UseTemplate($tplIdx, 0, 0, $pw, $ph);
+ }
+ if ($v[1]>0 && $v[1]<=$pagecount) {
+ $tplIdx = $mpdf->ImportPage($v[1], 0,0,$ow,$oh);
+ $mpdf->UseTemplate($tplIdx, $pw, 0, $pw, $ph);
+ }
+}
+
+$mpdf->Output();
+
+exit;
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example44_MPDFI_yearbook.php b/mpdf/examples/example44_MPDFI_yearbook.php
new file mode 100644
index 0000000..2420b9f
--- /dev/null
+++ b/mpdf/examples/example44_MPDFI_yearbook.php
@@ -0,0 +1,150 @@
+
+div { text-align: justify; }
+
+Joanne Smith 2002-2007This is the normal text in the div: Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque,  risus at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed,  nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+';
+
+$html2 = '
+
+Tim Another 2001-2007This is the normal text in the div: Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque,  risus at eleifend lacus sapien et risus. Phasellus metus, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+';
+
+for($i=1; $i<=10; $i++) {
+ // $html = $html;
+ if ($i % 3 == 1) { $html = $html2; }
+ else { $html = $html1; }
+ $pph[$i] = SinglePage($html, $pw, $ph, $minK) ; // $pph saves the actual height of each page
+}
+//==============================================================
+// Save the pages to a file
+$mpdf->Output('test.pdf','F');
+
+// Now collate those pages using IMPORT - 4 pages to one page
+
+$mpdf=new mPDF();
+$mpdf->SetImportUse();
+$mpdf->SetDisplayMode('fullpage');
+
+$mpdf->SetHeader('{DATE j-m-Y}|My Yearbook 2005|{PAGENO}');
+$mpdf->SetFooter('|Printed using mPDF|');
+
+$pagecount = $mpdf->SetSourceFile('test.pdf');
+for($i=1; $i<=$pagecount; $i++) {
+ if ($i % 4 == 1) { $mpdf->AddPage(); }
+ $pgheight = $mpdf->h - $mpdf->tMargin - $mpdf->bMargin;
+ $hspacing = min($spacing,($mpdf->pgwidth - $pw*2) );
+ $vspacing = min($spacing,($pgheight - $ph*2) );
+ $x1 = $mpdf->lMargin + ($mpdf->pgwidth/2 - $hspacing/2 - $pw)/2;
+ $x2 = $mpdf->lMargin + $mpdf->pgwidth/2 + $hspacing/2 + ($mpdf->pgwidth/2 - $hspacing/2 - $pw)/2;
+ $y1 = $mpdf->tMargin + ($pgheight /2 - $vspacing/2 - $ph)/2;
+ $y2 = $mpdf->tMargin + $pgheight /2 + $vspacing/2 + ($pgheight /2 - $vspacing/2 - $ph)/2;
+ if ($i % 4 == 1) { $x = $x1; $y = $y1; }
+ else if ($i % 4 == 2) { $x = $x2; $y = $y1; }
+ else if ($i % 4 == 3) { $x = $x1; $y = $y2; }
+ else if ($i % 4 == 0) { $x = $x2; $y = $y2; }
+ $tplIdx = $mpdf->ImportPage($i, 0,0,$pw,$pph[$i]);
+
+ if ($align=='T') { $mpdf->UseTemplate($tplIdx, $x, $y, $pw, $pph[$i]); }
+ else { $mpdf->UseTemplate($tplIdx, $x, ($y + (($ph - $pph[$i])/2)), $pw, $pph[$i]); }
+
+ if ($border >= 0) { $mpdf->Rect($x-$border, $y-$border, $pw+2*$border, $ph+2*$border); }
+}
+
+$mpdf->Output();
+
+exit;
+
+//==============================================================
+function SinglePage($html, $pw, $ph, $minK=1, $inc=0.1) {
+// returns height of page
+global $mpdf;
+ $mpdf->AddPage('','','','','','',($mpdf->w - $pw),'',($mpdf->h - $ph),0,0);
+ $k = 1;
+
+ $currpage = $mpdf->page;
+ $mpdf->WriteHTML($html);
+
+ $newpage = $mpdf->page;
+ while($currpage != $newpage) {
+ for($u=0;$u<=($newpage-$currpage);$u++) {
+ // DELETE PAGE - the added page
+ unset($mpdf->pages[$mpdf->page]);
+ if (isset($mpdf->ktAnnots[$mpdf->page])) { unset( $mpdf->ktAnnots[$mpdf->page] ); }
+ if (isset($mpdf->tbrot_Annots[$mpdf->page])) { unset( $mpdf->tbrot_Annots[$mpdf->page] ); }
+ if (isset($mpdf->kwt_Annots[$mpdf->page])) { unset( $mpdf->kwt_Annots[$mpdf->page] ); }
+ if (isset($mpdf->PageAnnots[$mpdf->page])) { unset( $mpdf->PageAnnots[$mpdf->page] ); }
+ if (isset($mpdf->ktBlock[$mpdf->page])) { unset( $mpdf->ktBlock[$mpdf->page] ); }
+ if (isset($mpdf->PageLinks[$mpdf->page])) { unset( $mpdf->PageLinks[$mpdf->page] ); }
+ if (isset($mpdf->pageoutput[$mpdf->page])) { unset( $mpdf->pageoutput[$mpdf->page] ); }
+ // Go to page before - so can addpage
+ $mpdf->page--;
+ }
+ // mPDF 2.4 Float Images
+ if (count($mpdf->floatbuffer)) {
+ $mpdf->objectbuffer[] = $mpdf->floatbuffer['objattr'];
+ $mpdf->printobjectbuffer(false);
+ $mpdf->objectbuffer = array();
+ $mpdf->floatbuffer = array();
+ $mpdf->float = false;
+ }
+
+
+ $k += $inc;
+ if ((1/$k) < $minK) { die("Page no. ".$mpdf->page." is too large to fit"); }
+ $w = $pw * $k;
+ $h = $ph * $k;
+ $mpdf->_beginpage('','',($mpdf->w - $w),'',($mpdf->h - $h));
+ $currpage = $mpdf->page;
+
+ $mpdf->_out('2 J');
+ $mpdf->_out(sprintf('%.2f w',0.1*$mpdf->k));
+ $mpdf->SetFont($mpdf->default_font,'',$mpdf->default_font_size ,true,true); // forces write
+ $mpdf->SetDrawColor(0);
+ $mpdf->SetFillColor(255);
+ $mpdf->SetTextColor(0);
+ $mpdf->ColorFlag=false;
+
+ // Start Transformation
+ $mpdf->StartTransform();
+ $mpdf->transformScale((100/$k), (100/$k), 0, 0);
+
+ $mpdf->WriteHTML($html);
+
+ $newpage = $mpdf->page;
+
+ //Stop Transformation
+ $mpdf->StopTransform();
+ }
+ return ($mpdf->y / $k);
+}
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example46_progress_bars_simple.php b/mpdf/examples/example46_progress_bars_simple.php
new file mode 100644
index 0000000..165678c
--- /dev/null
+++ b/mpdf/examples/example46_progress_bars_simple.php
@@ -0,0 +1,1652 @@
+
+
+
+
+
+
+
+
+mPDF Example File
+
+
+mPDF Example File
+
+
+{PAGENO}/{nbpg}
+
+
+{PAGENO}/{nbpg}
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+The front cover can also be produced like this:
+
+'. nl2br(htmlspecialchars('/* ALTERNATIVE PHP METHOD */
+$mpdf->Image(\'clematis.jpg\',0,0,210,297,\'jpg\',\'\',true, false);
+// the last "false" allows a full page picture
+
+$mpdf->y = 70;
+$mpdf->Shaded_box(\'mPDF Example File\', \'Trebuchet\', \'\', 28, \'70%\', \'DF\', 3, \'#FFFFFF\', \'#000044\', 10);
+')) .'
+
+
+
+
+
+
+
+
+
+
+
+
+
+(H1) mPDF
+(H2) Section 1
+(H3) HTML Markup
+
+
+
+
+Heading 4
+Heading 5
+Heading 6
+P: Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+
+
+
+DIV: Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim.
+DIV: Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim.
+
+Blockquote: Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus.
+
+Address: Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus.
+
+PRE: Cum sociis natoque penatibus et magnis dis parturient montes,
+nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis
+dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras
+sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor.
+Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem,
+ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+
+
+
+Styles - tt(teletype) italic bold big small emphasis strong new lines
+ code sample keyboard variable citation abbr. ACRONYM sup sub strike strike-s underline delete insert To be or not to be font changing face, size and color
+
+
+Paragraph using the in-line style to determine the font-size (15pt) and colour
+
+
+Testing BIG, SMALL, UNDERLINE, STRIKETHROUGH, FONT color, ACRONYM, SUPERSCRIPT and SUBSCRIPT
+This is strikethrough in block and small strikethrough in small span and big strikethrough in big span and then underline and strikethrough and sup but out of span again but blue font and ACRONYM text
+
+This is a green reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 then Strikethrough reference32-47 and strikethrough reference32-47
+
+Repeated in BIG: This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 but out of span again but blue font and ACRONYM text
+
+Repeated in small: This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 but out of span again but blue font and ACRONYM text
+
+The above repeated, but starting with a paragraph with font-size specified (7pt)
+
+This is strikethrough in block and small strikethrough in small span and then underline but out of span again but blue font and ACRONYM text
+
+This is strikethrough in block and big strikethrough in big span and then underline but out of span again but blue font and ACRONYM text
+
+This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 then Strikethrough reference32-47 and strikethrough reference32-47
+
+This tests underline and strikethrough when they are used together as they both use text-decoration
+
+
+Repeated in small: This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 but out of span again but blue font and ACRONYM text
+
+Repeated in BIG but with font-size set to 7pt by in-line css: This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 but out of span again but blue font and ACRONYM text
+
+
+- Item 1
+- Item 232
+- Item 3
+- Praesent pharetra nulla in turpis. Sed ipsum nulla, sodales nec, vulputate in, scelerisque vitae, magna. Sed egestas justo nec ipsum. Nulla facilisi. Praesent sit amet pede quis metus aliquet vulputate. Donec luctus. Cras euismod tellus vel leo.
+
+- Praesent pharetra nulla in turpis. Sed ipsum nulla, sodales nec, vulputate in, scelerisque vitae, magna. Sed egestas justo nec ipsum. Nulla facilisi. Praesent sit amet pede quis metus aliquet vulputate. Donec luctus. Cras euismod tellus vel leo.
+- Subitem 2
+
+
+
+
+- Item 5
+
+
+Sed bibendum. Nunc eleifend ornare velit. Sed consectetuer urna in erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Mauris sodales semper metus. Maecenas justo libero, pretium at, malesuada eu, mollis et, arcu. Ut suscipit pede in nulla. Praesent elementum, dolor ac fringilla posuere, elit libero rutrum massa, vel tincidunt dui tellus a ante. Sed aliquet euismod dolor. Vestibulum sed dui. Duis lobortis hendrerit quam. Donec tempus orci ut libero. Pellentesque suscipit malesuada nisi.
+
+
+
+
+| Data |
+Data |
+Data |
+Data 2nd line |
+
+
+
+
+| More Data |
+More Data |
+More Data |
+Data 2nd line |
+
+
+| Data |
+Data |
+Data |
+Data 2nd line |
+
+
+| Data |
+Data |
+Data |
+Data 2nd line |
+
+
+
+
+This paragraph has border-radius and background-gradient set. Minimum padding is recommended as 1/3rd of the border-radius. Or can use $mpdf->autoPadding.
+Sed bibendum. Nunc eleifend ornare velit. Sed consectetuer urna in erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Mauris sodales semper metus. Maecenas justo libero, pretium at, malesuada eu, mollis et, arcu. Ut suscipit pede in nulla. Praesent elementum, dolor ac fringilla posuere, elit libero rutrum massa, vel tincidunt dui tellus a ante. Sed aliquet euismod dolor. Vestibulum sed dui. Duis lobortis hendrerit quam. Donec tempus orci ut libero. Pellentesque suscipit malesuada nisi.
+
+
+
+
+
+Hyphenation
+
+Little Women - Chapter One - Playing Pilgrims
+
+
+ Christmas won\'t be Christmas without any presents, grumbled Jo, lying on the rug. It\'s so dreadful to be poor! sighed Meg, looking down at her old dress. I don\'t think it\'s fair for some girls to have plenty of pretty things, and other girls nothing at all, added little Amy, with an injured sniff. We\'ve got Father and Mother, and each other, said Beth contentedly from her corner. The four young faces on which the firelight shone brightened at the cheerful words, but darkened again as Jo said sadly, We haven\'t got Father, and shall not have him for a long time. She didn\'t say perhaps never, but each silently added it, thinking of Father far away, where the fighting was. Nobody spoke for a minute; then Meg said in an altered tone, You know the reason Mother proposed not having any presents this Christmas was because it is going to be a hard winter for everyone; and she thinks we ought not to spend money for pleasure, when our men are suffering so in the army. We can\'t do much, but we can make our little sacrifices, and ought to do it gladly. But I am afraid I don\'t And Meg shook her head, as she thought regretfully of all the pretty things she wanted. But I don\'t think the little we should spend would do any good. We\'ve each got a dollar, and the army wouldn\'t be much helped by our giving that. I agree not to expect anything from Mother or you, but I do want to buy UNDINE AND SINTRAM for myself. I\'ve wanted it so long, said Jo, who was a bookworm. I planned to spend mine in new music, said Beth, with a little sigh, which no one heard but the hearth brush and kettle holder. I shall get a nice box of Faber\'s drawing pencils. I really need them, said Amy decidedly. Mother didn\'t say anything about our money, and she won\'t wish us to give up everything. Let\'s each buy what we want, and have a little fun. I\'m sure we work hard enough to earn it, cried Jo, examining the heels of her shoes in a gentlemanly manner. I know I do—teaching those tiresome children nearly all day, when I\'m longing to enjoy myself at home, began Meg, in the complaining tone again. You don\'t have half such a hard time as I do, said Jo. How would you like to be shut up for hours with a nervous, fussy old lady, who keeps you trotting, is never satisfied, and worries you till you you\'re ready to fly out the window or cry? It\'s naughty to fret, but I do think washing dishes and keeping things tidy is the worst work in the world. It makes me cross, and my hands get so stiff, I can\'t practice well at all. And Beth looked at her rough hands with a sigh that any one could hear that time. I don\'t believe any of you suffer as I do, cried Amy, for you don\'t have to go to school with impertinent girls, who plague you if you don\'t know your lessons, and laugh at your dresses, and label your father if he isn\'t rich, and insult you when your nose isn\'t nice. If you mean libel, I\'d say so, and not talk about labels, as if Papa was a pickle bottle, advised Jo, laughing. I know what I mean, and you needn\'t be satirical about it. It\'s proper to use good words, and improve your vocabulary, returned Amy, with dignity. Don\'t peck at one another, children. Don\'t you wish we had the money Papa lost when we were little, Jo? Dear me! How happy and good we\'d be, if we had no worries! said Meg, who could remember better times. You said the other day you thought we were a deal happier than the King children, for they were fighting and fretting all the time, in spite of their money. So I did, Beth. Well, I think we are. For though we do have to work, we make fun of ourselves, and are a pretty jolly set, as Jo would say. Jo does use such slang words! observed Amy, with a reproving look at the long figure stretched on the rug. Jo immediately sat up, put her hands in her pockets, and began to whistle. Don\'t, Jo. It\'s so boyish! That\'s why I do it. I detest rude, unladylike girls! I hate affected, niminy-piminy chits! Birds in their little nests agree, sang Beth, the peacemaker, with such a funny face that both sharp voices softened to a laugh, and the pecking ended for that time. Really, girls, you are both to be blamed, said Meg, beginning to lecture in her elder-sisterly fashion. You are old enough to leave off boyish tricks, and to behave better, Josephine. It didn\'t matter so much when you were a little girl, but now you are so tall, and turn up your hair, you should remember that you are a young lady. I\'m not! And if turning up my hair makes me one, I\'ll wear it in two tails till I\'m twenty, cried Jo, pulling off her net, and shaking down a chestnut mane. I hate to think I\'ve got to grow up, and be Miss March, and wear long gowns, and look as prim as a China Aster! It\'s bad enough to be a girl, anyway, when I like boy\'s games and work and manners! I can\'t get over my disappointment in not being a boy. And it\'s worse than ever now, for I\'m dying to go and fight with Papa. And I can only stay home and knit, like a poky old woman! And Jo shook the blue army sock till the needles rattled like castanets, and her ball bounded across the room. Poor Jo! It\'s too bad, but it can\'t be helped. So you must try to be contented with making your name boyish, and playing brother to us girls, said Beth, stroking the rough head with a hand that all the dish washing and dusting in the world could not make ungentle in its touch. As for you, Amy, continued Meg, you are altogether to particular and prim. Your airs are funny now, but you\'ll grow up an affected little goose, if you don\'t take care. I I like your nice manners and refined ways of speaking, when you don\'t try to be elegant. But your absurd words are as bad as Jo\'s slang. If Jo is a tomboy and Amy a goose, what am I, please? asked Beth, ready to share the lecture. You\'re a dear, and nothing else, answered Meg warmly, and no one contradicted her, for the \'Mouse\' was the pet of the family.
+
+
+
+
+
+
+
+
+
+
+Lists
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Big text indent 25mm: Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Big text indent 25mm: Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- No class specified. Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+
+
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+
+
+
+Tables
+mPDF supports all in-line properties inside tables.
+
+| Row 1 | This is data | This is data |
+| Row 2 |
+
+ This is data p
+This is data out of p
+This is bold data p
+This is bold data out of p
+This is normal data after br
+Heading 3 inside a table
+Text here lorem ipsum ibisque totum.32
+This is data div
+This is data out of div
+This is data div (bold)
+This is data out of div
+ |
+
+Also data |
+
+
+This table has padding-top and -bottom set to 3mm i.e. padding within the cells. Also background-, border colour and style, font family and size are set by in-line CSS.
+
+| Row 1 | This is data | This is data |
+| Row 2 | This is data p | More data |
+Row 3 | This is long data | This is data |
+
+
+
+Tables
+The style sheet used for these examples shows some of the table styles I use on my website. The property \'topntail\' defined by a border-type definition e.g. "1px solid #880000" puts a border at the top and bottom of the table, and also below a header row (thead) if defined. Note also that <thead> will automatically turn on the header-repeat i.e. reproduce the header row at the top of each page.
+bpmTopic Class
+
+
+| Row 1 |
+This is data |
+This is data |
+
+
+| Row 2 |
+
+ This is data p
+ |
+
+ More data
+ |
+
+
+|
+ Row 3
+ |
+
+ This is long data
+ |
+This is data |
+
+
+|
+ Row 4 <td> cell
+ |
+This is data |
+
+ This is data
+ |
+
+
+| Row 5 |
+Also data |
+Also data |
+
+
+| Row 6 |
+Also data |
+Also data |
+
+
+| Row 7 |
+Also data |
+Also data |
+
+
+| Row 8 |
+Also data |
+Also data |
+
+
+
+
+
+bpmTopicC Class (centered) Odd and Even rows
+
+
+
+| Row header 1 |
+This is data |
+This is data |
+
+| Row header 2 |
+
+ This is data p
+ |
+
+ This is data
+ |
+
+|
+ Row header 3
+ |
+
+ This is long data
+ |
+This is data |
+
+|
+ Row header 4
+<th> cell acting as header
+ |
+This is data |
+
+ This is data
+ |
+
+| Row header 5 |
+Also data |
+Also data |
+
+| Row header 6 |
+Also data |
+Also data |
+
+| Row header 7 |
+Also data |
+Also data |
+
+| Row header 8 |
+Also data |
+Also data |
+
+
+
+
+
+bpmTopnTail Class
+
+
+| Row 1 |
+This is data |
+This is data |
+
+
+| Row 2 |
+
+ This is data p
+ |
+
+ This is data
+ |
+
+
+|
+ Row 3
+ |
+
+ This is long data
+ |
+This is data |
+
+
+|
+ Row 4 <td> cell
+ |
+This is data |
+
+ This is data
+ |
+
+
+| Row 5 |
+Also data |
+Also data |
+
+
+| Row 6 |
+Also data |
+Also data |
+
+
+| Row 7 |
+Also data |
+Also data |
+
+
+| Row 8 |
+Also data |
+Also data |
+
+
+
+bpmTopnTailC Class (centered) Odd and Even rows
+
+
+
+| Row header 1 |
+This is data |
+This is data |
+
+| Row header 2 |
+
+ This is data p
+ |
+
+ This is data
+ |
+
+|
+ Row header 3
+ |
+
+ This is long data
+ |
+This is data |
+
+|
+ Row header 4
+<th> cell acting as header
+ |
+This is data |
+
+ This is data
+ |
+
+| Row header 5 |
+Also data |
+Also data |
+
+| Row header 6 |
+Also data |
+Also data |
+
+| Row header 7 |
+Also data |
+Also data |
+
+| Row header 8 |
+Also data |
+Also data |
+
+
+
+
+
+TopnTail Class
+
+
+
+|
+ Row header 1 p
+ |
+This is data |
+This is data |
+
+| Row header 2 |
+Bottom right align |
+
+ This is data. Can use
+bold italic sub or sup text
+ |
+
+|
+ Bottom right align
+ |
+
+ This is data. This cell
+uses Cell Styles to set
+the borders.
+All borders are collapsible
+in mPDF.
+ |
+This is data |
+
+| Row header 4 |
+
+ This is data p
+ |
+More data |
+
+| Row header 5 |
+Also data merged and centered |
+
+
+
+
+
+Lists in a Table
+
+
+
+|
+ Row header 1 p
+ |
+This is data |
+This is data |
+
+| Row header 2 |
+
+
+- Item 1
+- Item 2
+
+- Subitem of ordered list
+- Subitem 2
+
+- Level 3 subitem
+- Level 3 subitem
+
+
+
+
+- Item 3
+- Another Item
+- Subitem
+
+- Level 3 subitem
+
+
+- Another Item
+
+ |
+
+Unordered list:
+
+- Item 1
+- Item 2
+
+- Subitem of unordered list
+- Subitem 2
+
+- Level 3 subitem
+- Level 3 subitem
+- Level 3 subitem
+
+
+
+
+- Item 3
+
+ |
+
+
+
+
+
+Automatic Column Width
+
+
+| Causes |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit.
+Ut a eros at ligula vehicula pretium; maecenas feugiat pede vel risus.
+Suspendisse potenti |
+
+
+| Mechanisms |
+Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. |
+
+
+
+
+Column span
+
+
+| Causes |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit.
+Ut a eros at ligula vehicula pretium; maecenas feugiat pede vel risus.
+Suspendisse potenti |
+
+
+| Mechanisms |
+Fusce eleifend neque sit amet erat.
+Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. |
+Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla.
+Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. |
+
+
+
+
+
+Header & Footer Rows
+A table using a header or footer row should repeat the header/footer row across pages:
+bpmTopicC Class
+
+
+
+
+
+
+
+
+| Row header 1 |
+This is data |
+This is data |
+
+| Row header 2 |
+This is data |
+
+ This is data
+ |
+
+|
+ Row header 3
+ |
+
+ This is data
+ |
+This is data |
+
+| Row header 4 |
+This is data |
+
+ This is data
+ |
+
+| Row header 5 |
+Also data |
+Also data |
+
+| Row header 6 |
+Also data |
+Also data |
+
+| Row header 7 |
+Also data |
+Also data |
+
+| Row header 8 |
+Also data |
+Also data |
+
+| Row header 9 |
+Also data |
+Also data |
+
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+
+
+
+Autosizing Tables
+Periodic Table of elements. Tables are set by default to reduce font size if complete words will not fit inside each cell, to a maximum of 1/1.4 * the set font-size. This value can be changed by setting $mpdf->shrink_tables_to_fit=1.8 or using html attribute <table autosize="1.8">.
+
+Periodic Table
+
+
+| 1A | 2A | 3B | 4B | 5B | 6B | 7B | 8B | 8B | 8B | 1B | 2B | 3A | 4A | 5A | 6A | 7A | 8A |
+
+ |
+
+
+| H | | He |
+
+
+| Li | Be | | B | C | N | O | F | Ne |
+
+
+| Na | Mg | | Al | Si | P | S | Cl | Ar |
+
+
+| K | Ca | Sc | Ti | V | Cr | Mn | Fe | Co | Ni |
+Cu | Zn | Ga | Ge | As | Se | Br | Kr |
+
+
+| Rb | Sr | Y | Zr | Nb | Mo | Tc | Ru | Rh | Pd | Ag | Cd |
+In | Sn | Sb | Te | I | Xe |
+
+
+| Cs | Ba | La | Hf | Ta | W | Re | Os | Ir | Pt | Au |
+Hg | Tl | Pb | Bi | Po | At | Rn |
+
+
+| Fr | Ra | Ac | |
+
+
+ |
+
+ | Ce | Pr | Nd | Pm | Sm | Eu | Gd | Tb |
+Dy | Ho | Er | Tm | Yb | Lu | |
+
+
+ | Th | Pa | U | Np | Pu | Am | Cm | Bk | Cf |
+Es | Fm | Md | No | Lr | |
+
+
+
+
+
+Rotated Tables
+This is set to rotate -90 degrees (counterclockwise).
+
+Periodic Table
+
+
+| 1A | 2A | 3B | 4B | 5B | 6B | 7B | 8B | 8B | 8B | 1B | 2B | 3A | 4A | 5A | 6A | 7A | 8A |
+
+ |
+ |
+
+
+| H | | | He |
+
+
+| Li | Be | | B | C | N | O | F | Ne |
+
+
+| Na | Mg | | Al | Si | P | S | Cl | Ar |
+
+
+| K | Ca | Sc | Ti | V | Cr | Mn | Fe | Co | Ni | Cu |
+Zn | Ga | Ge | As | Se | Br | Kr |
+
+
+| Rb | Sr | Y | Zr | Nb | Mo | Tc | Ru | Rh | Pd |
+Ag | Cd | In | Sn | Sb | Te | I | Xe |
+
+
+| Cs | Ba | La | Hf | Ta | W | Re | Os | Ir | Pt | Au |
+Hg | Tl | Pb | Bi | Po | At | Rn |
+
+
+| Fr | Ra | Ac |
+
+
+ |
+ |
+
+
+ | Ce | Pr | Nd | Pm | Sm | Eu | Gd | Tb | Dy |
+Ho | Er | Tm | Yb | Lu | |
+
+
+ | Th | Pa | U | Np | Pu | Am | Cm | Bk |
+Cf | Es | Fm | Md | No | Lr | |
+
+
+
+
+
+Rotated text in Tables
+
+Periodic Table
+
+
+
+Element type 1A Second line | Element type longer 2A |
+Element type 3B | Element type 4B | Element type 5B | Element type 6B | 7B | 8B |
+Element type 8B R | 8B | Element type 1B | 2B |
+Element type 3A | Element type 4A | Element type 5A | Element type 6A | 7A | Element type 8A |
+
+
+
+
+
+| H | | | He |
+
+
+| Li | Be | | B | C | N | O | F | Ne |
+
+
+| Na | Mg | | Al | Si | P | S | Cl | Ar |
+
+
+| K | Ca | Sc | Ti | Va | Cr | Mn | Fe | Co | Ni |
+Cu | Zn | Ga | Ge | As | Se | Br | Kr |
+
+
+| Rb | Sr | Y | Zr | Nb | Mo | Tc | Ru |
+Rh | Pd | Ag | Cd | In | Sn |
+Sb | Te | I | Xe |
+
+
+| Cs | Ba | La | Hf | Ta | W | Re | Os | Ir |
+Pt | Au | Hg | Tl | Pb | Bi | Po | At | Rn |
+
+
+| Fr | Ra | Ac |
+
+
+ |
+Ce | Pr | Nd | Pm | Sm | Eu | Gd | Tb | Dy |
+Ho | Er | Tm | Yb | Lu | |
+
+
+ |
+Th | Pa | U | Np | Pu | Am | Cm | Bk | Cf | Es |
+Fm | Md | No | Lr | |
+
+
+
+
+
+
+
+
+Nested Tables
+
+
+Text before table
+
+
+
+
+
+
+| This is data |
+This is data |
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+| Row C |
+C2 |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+This is data |
+
+
+| This is data |
+This is data |
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+| Row C |
+C2 |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+This is data |
+
+
+| This is data |
+This is data |
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+| Row C |
+C2 |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+This is data |
+
+
+| This is data |
+This is data |
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+| Row C |
+C2 |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+This is data |
+
+
+| This is data |
+This is data |
+This is data |
+This is data |
+
+
+| This is data |
+ |
+This is data |
+This is data |
+
+
+| This is data |
+This is data |
+This is data |
+This is data |
+
+
+
+
+
+
+
+ Text before table
+
+
+
+
+| Row 1 |
+This is data |
+
+Text before table
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+| Row C |
+C2 |
+C3 |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+Text after table
+ |
+This is data |
+
+
+| Row 2 |
+This is data |
+This is data |
+This is data |
+
+
+| Row 3 |
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+ |
+B4 |
+
+
+| Row C |
+C2 |
+
+
+
+
+| F1 |
+F2 |
+
+
+| Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec et nulla. Sed quis orci. |
+G2 |
+
+
+ |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+| Row C |
+C2 |
+C3 |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+This is data |
+
+
+| Row 4 |
+This is data |
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+ |
+B4 |
+
+
+| Row C |
+C2 |
+
+
+
+
+| F1 |
+F2 |
+
+
+| Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec et nulla. Sed quis orci. |
+G2 |
+
+
+ |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+This is data |
+
+
+
+
+
+
+
+
+
+Forms
+
+
+
+
+
+Annotations
+Praesent pharetra nulla in turpis. Sed ipsum nulla, sodales nec, vulputate in, scelerisque vitae, magna. Sed egestas justo nec ipsum. Nulla facilisi. Praesent sit amet pede quis metus aliquet vulputate. Donec luctus. Cras euismod tellus vel leo. Cras tellus. Fusce aliquet. Curabitur tincidunt viverra ligula. Fusce eget erat. Donec pede. Vestibulum id felis. Phasellus tincidunt ligula non pede. Morbi turpis. In vitae dui non erat placerat malesuada. Mauris adipiscing congue ante. Proin at erat. Aliquam mattis.
+P: Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+
+
+
+
+Full Images & Barcode
+On the first and last page of this document, an image is reproduced full page size by placing it inside a DIV element with CSS "position:absolute". In all other situations, images are constrained to the width and height of the printable page (i.e. inside the margins). The image on the back page has CSS "opacity:0.5".
+
+
+
+'. nl2br(htmlspecialchars('/* ALTERNATIVE PHP METHOD */
+$mpdf->SetAlpha(0.5);
+$mpdf->Image(\'clematis.jpg\',0,0,210,297,\'jpg\',\'\',true, false);
+// the last "false" allows a full page picture
+$mpdf->SetAlpha(1);
+')) .'
+
+
+The back cover also has an ISBN barcode
+
+
+'. nl2br(htmlspecialchars('/* ALTERNATIVE PHP METHOD */
+$mpdf->writeBarcode(\'978-0-9542246-0-8\', 1, 130, 230, 1,0, 3,3,4,4);
+')) .'
+
+
+But next is inserted the Index, which can also be done like this:
+
+
+'. nl2br(htmlspecialchars('/* ALTERNATIVE PHP METHOD */
+$mpdf->AddPage(\'\',NEXT-ODD\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',-1,-1,-1,-1);
+$mpdf->WriteHTML(\' Index\');
+$mpdf->WriteHTML(\'\');
+')) .'
+
+
+
+
+
+
+Index
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+
+include("../mpdf.php");
+
+$mpdf=new mPDF('','A4','','',25,15,21,22,10,10);
+
+$mpdf->StartProgressBarOutput();
+
+$mpdf->mirrorMargins = 1;
+$mpdf->SetDisplayMode('fullpage','two');
+$mpdf->list_number_suffix = ')';
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+
+exit;
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example47_progress_bars_simple_custom.php b/mpdf/examples/example47_progress_bars_simple_custom.php
new file mode 100644
index 0000000..07b5d3f
--- /dev/null
+++ b/mpdf/examples/example47_progress_bars_simple_custom.php
@@ -0,0 +1,1659 @@
+
+
+
+
+
+
+
+
+mPDF Example File
+
+
+mPDF Example File
+
+
+{PAGENO}/{nbpg}
+
+
+{PAGENO}/{nbpg}
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+The front cover can also be produced like this:
+
+'. nl2br(htmlspecialchars('/* ALTERNATIVE PHP METHOD */
+$mpdf->Image(\'clematis.jpg\',0,0,210,297,\'jpg\',\'\',true, false);
+// the last "false" allows a full page picture
+
+$mpdf->y = 70;
+$mpdf->Shaded_box(\'mPDF Example File\', \'Trebuchet\', \'\', 28, \'70%\', \'DF\', 3, \'#FFFFFF\', \'#000044\', 10);
+')) .'
+
+
+
+
+
+
+
+
+
+
+
+
+
+(H1) mPDF
+(H2) Section 1
+(H3) HTML Markup
+
+
+
+
+Heading 4
+Heading 5
+Heading 6
+P: Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+
+
+
+DIV: Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim.
+DIV: Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim.
+
+Blockquote: Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus.
+
+Address: Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus.
+
+PRE: Cum sociis natoque penatibus et magnis dis parturient montes,
+nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis
+dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras
+sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor.
+Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem,
+ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+
+
+
+Styles - tt(teletype) italic bold big small emphasis strong new lines
+ code sample keyboard variable citation abbr. ACRONYM sup sub strike strike-s underline delete insert To be or not to be font changing face, size and color
+
+
+Paragraph using the in-line style to determine the font-size (15pt) and colour
+
+
+Testing BIG, SMALL, UNDERLINE, STRIKETHROUGH, FONT color, ACRONYM, SUPERSCRIPT and SUBSCRIPT
+This is strikethrough in block and small strikethrough in small span and big strikethrough in big span and then underline and strikethrough and sup but out of span again but blue font and ACRONYM text
+
+This is a green reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 then Strikethrough reference32-47 and strikethrough reference32-47
+
+Repeated in BIG: This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 but out of span again but blue font and ACRONYM text
+
+Repeated in small: This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 but out of span again but blue font and ACRONYM text
+
+The above repeated, but starting with a paragraph with font-size specified (7pt)
+
+This is strikethrough in block and small strikethrough in small span and then underline but out of span again but blue font and ACRONYM text
+
+This is strikethrough in block and big strikethrough in big span and then underline but out of span again but blue font and ACRONYM text
+
+This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 then Strikethrough reference32-47 and strikethrough reference32-47
+
+This tests underline and strikethrough when they are used together as they both use text-decoration
+
+
+Repeated in small: This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 but out of span again but blue font and ACRONYM text
+
+Repeated in BIG but with font-size set to 7pt by in-line css: This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 but out of span again but blue font and ACRONYM text
+
+
+- Item 1
+- Item 232
+- Item 3
+- Praesent pharetra nulla in turpis. Sed ipsum nulla, sodales nec, vulputate in, scelerisque vitae, magna. Sed egestas justo nec ipsum. Nulla facilisi. Praesent sit amet pede quis metus aliquet vulputate. Donec luctus. Cras euismod tellus vel leo.
+
+- Praesent pharetra nulla in turpis. Sed ipsum nulla, sodales nec, vulputate in, scelerisque vitae, magna. Sed egestas justo nec ipsum. Nulla facilisi. Praesent sit amet pede quis metus aliquet vulputate. Donec luctus. Cras euismod tellus vel leo.
+- Subitem 2
+
+
+
+
+- Item 5
+
+
+Sed bibendum. Nunc eleifend ornare velit. Sed consectetuer urna in erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Mauris sodales semper metus. Maecenas justo libero, pretium at, malesuada eu, mollis et, arcu. Ut suscipit pede in nulla. Praesent elementum, dolor ac fringilla posuere, elit libero rutrum massa, vel tincidunt dui tellus a ante. Sed aliquet euismod dolor. Vestibulum sed dui. Duis lobortis hendrerit quam. Donec tempus orci ut libero. Pellentesque suscipit malesuada nisi.
+
+
+
+
+| Data |
+Data |
+Data |
+Data 2nd line |
+
+
+
+
+| More Data |
+More Data |
+More Data |
+Data 2nd line |
+
+
+| Data |
+Data |
+Data |
+Data 2nd line |
+
+
+| Data |
+Data |
+Data |
+Data 2nd line |
+
+
+
+
+This paragraph has border-radius and background-gradient set. Minimum padding is recommended as 1/3rd of the border-radius. Or can use $mpdf->autoPadding.
+Sed bibendum. Nunc eleifend ornare velit. Sed consectetuer urna in erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Mauris sodales semper metus. Maecenas justo libero, pretium at, malesuada eu, mollis et, arcu. Ut suscipit pede in nulla. Praesent elementum, dolor ac fringilla posuere, elit libero rutrum massa, vel tincidunt dui tellus a ante. Sed aliquet euismod dolor. Vestibulum sed dui. Duis lobortis hendrerit quam. Donec tempus orci ut libero. Pellentesque suscipit malesuada nisi.
+
+
+
+
+
+Hyphenation
+
+Little Women - Chapter One - Playing Pilgrims
+
+
+ Christmas won\'t be Christmas without any presents, grumbled Jo, lying on the rug. It\'s so dreadful to be poor! sighed Meg, looking down at her old dress. I don\'t think it\'s fair for some girls to have plenty of pretty things, and other girls nothing at all, added little Amy, with an injured sniff. We\'ve got Father and Mother, and each other, said Beth contentedly from her corner. The four young faces on which the firelight shone brightened at the cheerful words, but darkened again as Jo said sadly, We haven\'t got Father, and shall not have him for a long time. She didn\'t say perhaps never, but each silently added it, thinking of Father far away, where the fighting was. Nobody spoke for a minute; then Meg said in an altered tone, You know the reason Mother proposed not having any presents this Christmas was because it is going to be a hard winter for everyone; and she thinks we ought not to spend money for pleasure, when our men are suffering so in the army. We can\'t do much, but we can make our little sacrifices, and ought to do it gladly. But I am afraid I don\'t And Meg shook her head, as she thought regretfully of all the pretty things she wanted. But I don\'t think the little we should spend would do any good. We\'ve each got a dollar, and the army wouldn\'t be much helped by our giving that. I agree not to expect anything from Mother or you, but I do want to buy UNDINE AND SINTRAM for myself. I\'ve wanted it so long, said Jo, who was a bookworm. I planned to spend mine in new music, said Beth, with a little sigh, which no one heard but the hearth brush and kettle holder. I shall get a nice box of Faber\'s drawing pencils. I really need them, said Amy decidedly. Mother didn\'t say anything about our money, and she won\'t wish us to give up everything. Let\'s each buy what we want, and have a little fun. I\'m sure we work hard enough to earn it, cried Jo, examining the heels of her shoes in a gentlemanly manner. I know I do—teaching those tiresome children nearly all day, when I\'m longing to enjoy myself at home, began Meg, in the complaining tone again. You don\'t have half such a hard time as I do, said Jo. How would you like to be shut up for hours with a nervous, fussy old lady, who keeps you trotting, is never satisfied, and worries you till you you\'re ready to fly out the window or cry? It\'s naughty to fret, but I do think washing dishes and keeping things tidy is the worst work in the world. It makes me cross, and my hands get so stiff, I can\'t practice well at all. And Beth looked at her rough hands with a sigh that any one could hear that time. I don\'t believe any of you suffer as I do, cried Amy, for you don\'t have to go to school with impertinent girls, who plague you if you don\'t know your lessons, and laugh at your dresses, and label your father if he isn\'t rich, and insult you when your nose isn\'t nice. If you mean libel, I\'d say so, and not talk about labels, as if Papa was a pickle bottle, advised Jo, laughing. I know what I mean, and you needn\'t be satirical about it. It\'s proper to use good words, and improve your vocabulary, returned Amy, with dignity. Don\'t peck at one another, children. Don\'t you wish we had the money Papa lost when we were little, Jo? Dear me! How happy and good we\'d be, if we had no worries! said Meg, who could remember better times. You said the other day you thought we were a deal happier than the King children, for they were fighting and fretting all the time, in spite of their money. So I did, Beth. Well, I think we are. For though we do have to work, we make fun of ourselves, and are a pretty jolly set, as Jo would say. Jo does use such slang words! observed Amy, with a reproving look at the long figure stretched on the rug. Jo immediately sat up, put her hands in her pockets, and began to whistle. Don\'t, Jo. It\'s so boyish! That\'s why I do it. I detest rude, unladylike girls! I hate affected, niminy-piminy chits! Birds in their little nests agree, sang Beth, the peacemaker, with such a funny face that both sharp voices softened to a laugh, and the pecking ended for that time. Really, girls, you are both to be blamed, said Meg, beginning to lecture in her elder-sisterly fashion. You are old enough to leave off boyish tricks, and to behave better, Josephine. It didn\'t matter so much when you were a little girl, but now you are so tall, and turn up your hair, you should remember that you are a young lady. I\'m not! And if turning up my hair makes me one, I\'ll wear it in two tails till I\'m twenty, cried Jo, pulling off her net, and shaking down a chestnut mane. I hate to think I\'ve got to grow up, and be Miss March, and wear long gowns, and look as prim as a China Aster! It\'s bad enough to be a girl, anyway, when I like boy\'s games and work and manners! I can\'t get over my disappointment in not being a boy. And it\'s worse than ever now, for I\'m dying to go and fight with Papa. And I can only stay home and knit, like a poky old woman! And Jo shook the blue army sock till the needles rattled like castanets, and her ball bounded across the room. Poor Jo! It\'s too bad, but it can\'t be helped. So you must try to be contented with making your name boyish, and playing brother to us girls, said Beth, stroking the rough head with a hand that all the dish washing and dusting in the world could not make ungentle in its touch. As for you, Amy, continued Meg, you are altogether to particular and prim. Your airs are funny now, but you\'ll grow up an affected little goose, if you don\'t take care. I I like your nice manners and refined ways of speaking, when you don\'t try to be elegant. But your absurd words are as bad as Jo\'s slang. If Jo is a tomboy and Amy a goose, what am I, please? asked Beth, ready to share the lecture. You\'re a dear, and nothing else, answered Meg warmly, and no one contradicted her, for the \'Mouse\' was the pet of the family.
+
+
+
+
+
+
+
+
+
+
+Lists
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Big text indent 25mm: Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Big text indent 25mm: Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- No class specified. Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+
+
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+
+
+
+Tables
+mPDF supports all in-line properties inside tables.
+
+| Row 1 | This is data | This is data |
+| Row 2 |
+
+ This is data p
+This is data out of p
+This is bold data p
+This is bold data out of p
+This is normal data after br
+Heading 3 inside a table
+Text here lorem ipsum ibisque totum.32
+This is data div
+This is data out of div
+This is data div (bold)
+This is data out of div
+ |
+
+Also data |
+
+
+This table has padding-top and -bottom set to 3mm i.e. padding within the cells. Also background-, border colour and style, font family and size are set by in-line CSS.
+
+| Row 1 | This is data | This is data |
+| Row 2 | This is data p | More data |
+Row 3 | This is long data | This is data |
+
+
+
+Tables
+The style sheet used for these examples shows some of the table styles I use on my website. The property \'topntail\' defined by a border-type definition e.g. "1px solid #880000" puts a border at the top and bottom of the table, and also below a header row (thead) if defined. Note also that <thead> will automatically turn on the header-repeat i.e. reproduce the header row at the top of each page.
+bpmTopic Class
+
+
+| Row 1 |
+This is data |
+This is data |
+
+
+| Row 2 |
+
+ This is data p
+ |
+
+ More data
+ |
+
+
+|
+ Row 3
+ |
+
+ This is long data
+ |
+This is data |
+
+
+|
+ Row 4 <td> cell
+ |
+This is data |
+
+ This is data
+ |
+
+
+| Row 5 |
+Also data |
+Also data |
+
+
+| Row 6 |
+Also data |
+Also data |
+
+
+| Row 7 |
+Also data |
+Also data |
+
+
+| Row 8 |
+Also data |
+Also data |
+
+
+
+
+
+bpmTopicC Class (centered) Odd and Even rows
+
+
+
+| Row header 1 |
+This is data |
+This is data |
+
+| Row header 2 |
+
+ This is data p
+ |
+
+ This is data
+ |
+
+|
+ Row header 3
+ |
+
+ This is long data
+ |
+This is data |
+
+|
+ Row header 4
+<th> cell acting as header
+ |
+This is data |
+
+ This is data
+ |
+
+| Row header 5 |
+Also data |
+Also data |
+
+| Row header 6 |
+Also data |
+Also data |
+
+| Row header 7 |
+Also data |
+Also data |
+
+| Row header 8 |
+Also data |
+Also data |
+
+
+
+
+
+bpmTopnTail Class
+
+
+| Row 1 |
+This is data |
+This is data |
+
+
+| Row 2 |
+
+ This is data p
+ |
+
+ This is data
+ |
+
+
+|
+ Row 3
+ |
+
+ This is long data
+ |
+This is data |
+
+
+|
+ Row 4 <td> cell
+ |
+This is data |
+
+ This is data
+ |
+
+
+| Row 5 |
+Also data |
+Also data |
+
+
+| Row 6 |
+Also data |
+Also data |
+
+
+| Row 7 |
+Also data |
+Also data |
+
+
+| Row 8 |
+Also data |
+Also data |
+
+
+
+bpmTopnTailC Class (centered) Odd and Even rows
+
+
+
+| Row header 1 |
+This is data |
+This is data |
+
+| Row header 2 |
+
+ This is data p
+ |
+
+ This is data
+ |
+
+|
+ Row header 3
+ |
+
+ This is long data
+ |
+This is data |
+
+|
+ Row header 4
+<th> cell acting as header
+ |
+This is data |
+
+ This is data
+ |
+
+| Row header 5 |
+Also data |
+Also data |
+
+| Row header 6 |
+Also data |
+Also data |
+
+| Row header 7 |
+Also data |
+Also data |
+
+| Row header 8 |
+Also data |
+Also data |
+
+
+
+
+
+TopnTail Class
+
+
+
+|
+ Row header 1 p
+ |
+This is data |
+This is data |
+
+| Row header 2 |
+Bottom right align |
+
+ This is data. Can use
+bold italic sub or sup text
+ |
+
+|
+ Bottom right align
+ |
+
+ This is data. This cell
+uses Cell Styles to set
+the borders.
+All borders are collapsible
+in mPDF.
+ |
+This is data |
+
+| Row header 4 |
+
+ This is data p
+ |
+More data |
+
+| Row header 5 |
+Also data merged and centered |
+
+
+
+
+
+Lists in a Table
+
+
+
+|
+ Row header 1 p
+ |
+This is data |
+This is data |
+
+| Row header 2 |
+
+
+- Item 1
+- Item 2
+
+- Subitem of ordered list
+- Subitem 2
+
+- Level 3 subitem
+- Level 3 subitem
+
+
+
+
+- Item 3
+- Another Item
+- Subitem
+
+- Level 3 subitem
+
+
+- Another Item
+
+ |
+
+Unordered list:
+
+- Item 1
+- Item 2
+
+- Subitem of unordered list
+- Subitem 2
+
+- Level 3 subitem
+- Level 3 subitem
+- Level 3 subitem
+
+
+
+
+- Item 3
+
+ |
+
+
+
+
+
+Automatic Column Width
+
+
+| Causes |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit.
+Ut a eros at ligula vehicula pretium; maecenas feugiat pede vel risus.
+Suspendisse potenti |
+
+
+| Mechanisms |
+Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. |
+
+
+
+
+Column span
+
+
+| Causes |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit.
+Ut a eros at ligula vehicula pretium; maecenas feugiat pede vel risus.
+Suspendisse potenti |
+
+
+| Mechanisms |
+Fusce eleifend neque sit amet erat.
+Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. |
+Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla.
+Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. |
+
+
+
+
+
+Header & Footer Rows
+A table using a header or footer row should repeat the header/footer row across pages:
+bpmTopicC Class
+
+
+
+
+
+
+
+
+| Row header 1 |
+This is data |
+This is data |
+
+| Row header 2 |
+This is data |
+
+ This is data
+ |
+
+|
+ Row header 3
+ |
+
+ This is data
+ |
+This is data |
+
+| Row header 4 |
+This is data |
+
+ This is data
+ |
+
+| Row header 5 |
+Also data |
+Also data |
+
+| Row header 6 |
+Also data |
+Also data |
+
+| Row header 7 |
+Also data |
+Also data |
+
+| Row header 8 |
+Also data |
+Also data |
+
+| Row header 9 |
+Also data |
+Also data |
+
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+
+
+
+Autosizing Tables
+Periodic Table of elements. Tables are set by default to reduce font size if complete words will not fit inside each cell, to a maximum of 1/1.4 * the set font-size. This value can be changed by setting $mpdf->shrink_tables_to_fit=1.8 or using html attribute <table autosize="1.8">.
+
+Periodic Table
+
+
+| 1A | 2A | 3B | 4B | 5B | 6B | 7B | 8B | 8B | 8B | 1B | 2B | 3A | 4A | 5A | 6A | 7A | 8A |
+
+ |
+
+
+| H | | He |
+
+
+| Li | Be | | B | C | N | O | F | Ne |
+
+
+| Na | Mg | | Al | Si | P | S | Cl | Ar |
+
+
+| K | Ca | Sc | Ti | V | Cr | Mn | Fe | Co | Ni |
+Cu | Zn | Ga | Ge | As | Se | Br | Kr |
+
+
+| Rb | Sr | Y | Zr | Nb | Mo | Tc | Ru | Rh | Pd | Ag | Cd |
+In | Sn | Sb | Te | I | Xe |
+
+
+| Cs | Ba | La | Hf | Ta | W | Re | Os | Ir | Pt | Au |
+Hg | Tl | Pb | Bi | Po | At | Rn |
+
+
+| Fr | Ra | Ac | |
+
+
+ |
+
+ | Ce | Pr | Nd | Pm | Sm | Eu | Gd | Tb |
+Dy | Ho | Er | Tm | Yb | Lu | |
+
+
+ | Th | Pa | U | Np | Pu | Am | Cm | Bk | Cf |
+Es | Fm | Md | No | Lr | |
+
+
+
+
+
+Rotated Tables
+This is set to rotate -90 degrees (counterclockwise).
+
+Periodic Table
+
+
+| 1A | 2A | 3B | 4B | 5B | 6B | 7B | 8B | 8B | 8B | 1B | 2B | 3A | 4A | 5A | 6A | 7A | 8A |
+
+ |
+ |
+
+
+| H | | | He |
+
+
+| Li | Be | | B | C | N | O | F | Ne |
+
+
+| Na | Mg | | Al | Si | P | S | Cl | Ar |
+
+
+| K | Ca | Sc | Ti | V | Cr | Mn | Fe | Co | Ni | Cu |
+Zn | Ga | Ge | As | Se | Br | Kr |
+
+
+| Rb | Sr | Y | Zr | Nb | Mo | Tc | Ru | Rh | Pd |
+Ag | Cd | In | Sn | Sb | Te | I | Xe |
+
+
+| Cs | Ba | La | Hf | Ta | W | Re | Os | Ir | Pt | Au |
+Hg | Tl | Pb | Bi | Po | At | Rn |
+
+
+| Fr | Ra | Ac |
+
+
+ |
+ |
+
+
+ | Ce | Pr | Nd | Pm | Sm | Eu | Gd | Tb | Dy |
+Ho | Er | Tm | Yb | Lu | |
+
+
+ | Th | Pa | U | Np | Pu | Am | Cm | Bk |
+Cf | Es | Fm | Md | No | Lr | |
+
+
+
+
+
+Rotated text in Tables
+
+Periodic Table
+
+
+
+Element type 1A Second line | Element type longer 2A |
+Element type 3B | Element type 4B | Element type 5B | Element type 6B | 7B | 8B |
+Element type 8B R | 8B | Element type 1B | 2B |
+Element type 3A | Element type 4A | Element type 5A | Element type 6A | 7A | Element type 8A |
+
+
+
+
+
+| H | | | He |
+
+
+| Li | Be | | B | C | N | O | F | Ne |
+
+
+| Na | Mg | | Al | Si | P | S | Cl | Ar |
+
+
+| K | Ca | Sc | Ti | Va | Cr | Mn | Fe | Co | Ni |
+Cu | Zn | Ga | Ge | As | Se | Br | Kr |
+
+
+| Rb | Sr | Y | Zr | Nb | Mo | Tc | Ru |
+Rh | Pd | Ag | Cd | In | Sn |
+Sb | Te | I | Xe |
+
+
+| Cs | Ba | La | Hf | Ta | W | Re | Os | Ir |
+Pt | Au | Hg | Tl | Pb | Bi | Po | At | Rn |
+
+
+| Fr | Ra | Ac |
+
+
+ |
+Ce | Pr | Nd | Pm | Sm | Eu | Gd | Tb | Dy |
+Ho | Er | Tm | Yb | Lu | |
+
+
+ |
+Th | Pa | U | Np | Pu | Am | Cm | Bk | Cf | Es |
+Fm | Md | No | Lr | |
+
+
+
+
+
+
+
+
+Nested Tables
+
+
+Text before table
+
+
+
+
+
+
+| This is data |
+This is data |
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+| Row C |
+C2 |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+This is data |
+
+
+| This is data |
+This is data |
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+| Row C |
+C2 |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+This is data |
+
+
+| This is data |
+This is data |
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+| Row C |
+C2 |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+This is data |
+
+
+| This is data |
+This is data |
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+| Row C |
+C2 |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+This is data |
+
+
+| This is data |
+This is data |
+This is data |
+This is data |
+
+
+| This is data |
+ |
+This is data |
+This is data |
+
+
+| This is data |
+This is data |
+This is data |
+This is data |
+
+
+
+
+
+
+
+ Text before table
+
+
+
+
+| Row 1 |
+This is data |
+
+Text before table
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+| Row C |
+C2 |
+C3 |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+Text after table
+ |
+This is data |
+
+
+| Row 2 |
+This is data |
+This is data |
+This is data |
+
+
+| Row 3 |
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+ |
+B4 |
+
+
+| Row C |
+C2 |
+
+
+
+
+| F1 |
+F2 |
+
+
+| Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec et nulla. Sed quis orci. |
+G2 |
+
+
+ |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+| Row C |
+C2 |
+C3 |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+This is data |
+
+
+| Row 4 |
+This is data |
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+ |
+B4 |
+
+
+| Row C |
+C2 |
+
+
+
+
+| F1 |
+F2 |
+
+
+| Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec et nulla. Sed quis orci. |
+G2 |
+
+
+ |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+This is data |
+
+
+
+
+
+
+
+
+
+Forms
+
+
+
+
+
+Annotations
+Praesent pharetra nulla in turpis. Sed ipsum nulla, sodales nec, vulputate in, scelerisque vitae, magna. Sed egestas justo nec ipsum. Nulla facilisi. Praesent sit amet pede quis metus aliquet vulputate. Donec luctus. Cras euismod tellus vel leo. Cras tellus. Fusce aliquet. Curabitur tincidunt viverra ligula. Fusce eget erat. Donec pede. Vestibulum id felis. Phasellus tincidunt ligula non pede. Morbi turpis. In vitae dui non erat placerat malesuada. Mauris adipiscing congue ante. Proin at erat. Aliquam mattis.
+P: Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+
+
+
+
+
+Full Images & Barcode
+On the first and last page of this document, an image is reproduced full page size by placing it inside a DIV element with CSS "position:absolute". In all other situations, images are constrained to the width and height of the printable page (i.e. inside the margins). The image on the back page has CSS "opacity:0.5".
+
+
+
+'. nl2br(htmlspecialchars('/* ALTERNATIVE PHP METHOD */
+$mpdf->SetAlpha(0.5);
+$mpdf->Image(\'clematis.jpg\',0,0,210,297,\'jpg\',\'\',true, false);
+// the last "false" allows a full page picture
+$mpdf->SetAlpha(1);
+')) .'
+
+
+The back cover also has an ISBN barcode
+
+
+'. nl2br(htmlspecialchars('/* ALTERNATIVE PHP METHOD */
+$mpdf->writeBarcode(\'978-0-9542246-0-8\', 1, 130, 230, 1,0, 3,3,4,4);
+')) .'
+
+
+But next is inserted the Index, which can also be done like this:
+
+
+'. nl2br(htmlspecialchars('/* ALTERNATIVE PHP METHOD */
+$mpdf->AddPage(\'\',NEXT-ODD\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',-1,-1,-1,-1);
+$mpdf->WriteHTML(\' Index\');
+$mpdf->WriteHTML(\'\');
+')) .'
+
+
+
+
+
+
+Index
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+
+include("../mpdf.php");
+
+$mpdf=new mPDF('','A4','','',25,15,21,22,10,10);
+$mpdf->progbar_altHTML = '
+  Creating PDF file. Please wait... ';
+$mpdf->StartProgressBarOutput();
+
+$mpdf->mirrorMargins = 1;
+$mpdf->SetDisplayMode('fullpage','two');
+$mpdf->list_number_suffix = ')';
+
+$mpdf->debug = true;
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+
+exit;
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example48_progress_bars_advanced.php b/mpdf/examples/example48_progress_bars_advanced.php
new file mode 100644
index 0000000..7d1a634
--- /dev/null
+++ b/mpdf/examples/example48_progress_bars_advanced.php
@@ -0,0 +1,1658 @@
+
+
+
+
+
+
+
+
+mPDF Example File
+
+
+mPDF Example File
+
+
+{PAGENO}/{nbpg}
+
+
+{PAGENO}/{nbpg}
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+The front cover can also be produced like this:
+
+'. nl2br(htmlspecialchars('/* ALTERNATIVE PHP METHOD */
+$mpdf->Image(\'clematis.jpg\',0,0,210,297,\'jpg\',\'\',true, false);
+// the last "false" allows a full page picture
+
+$mpdf->y = 70;
+$mpdf->Shaded_box(\'mPDF Example File\', \'Trebuchet\', \'\', 28, \'70%\', \'DF\', 3, \'#FFFFFF\', \'#000044\', 10);
+')) .'
+
+
+
+
+
+
+
+
+
+
+
+
+
+(H1) mPDF
+(H2) Section 1
+(H3) HTML Markup
+
+
+
+
+Heading 4
+Heading 5
+Heading 6
+P: Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+
+
+
+DIV: Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim.
+DIV: Proin aliquet lorem id felis. Curabitur vel libero at mauris nonummy tincidunt. Donec imperdiet. Vestibulum sem sem, lacinia vel, molestie et, laoreet eget, urna. Curabitur viverra faucibus pede. Morbi lobortis. Donec dapibus. Donec tempus. Ut arcu enim, rhoncus ac, venenatis eu, porttitor mollis, dui. Sed vitae risus. In elementum sem placerat dui. Nam tristique eros in nisl. Nulla cursus sapien non quam porta porttitor. Quisque dictum ipsum ornare tortor. Fusce ornare tempus enim.
+
+Blockquote: Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus. Maecenas arcu justo, malesuada eu, dapibus ac, adipiscing vitae, turpis. Fusce mollis. Aliquam egestas. In purus dolor, facilisis at, fermentum nec, molestie et, metus.
+
+Address: Vestibulum feugiat, orci at imperdiet tincidunt, mauris erat facilisis urna, sagittis ultricies dui nisl et lectus. Sed lacinia, lectus vitae dictum sodales, elit ipsum ultrices orci, non euismod arcu diam non metus.
+
+PRE: Cum sociis natoque penatibus et magnis dis parturient montes,
+nascetur ridiculus mus. In suscipit turpis vitae odio. Integer convallis
+dui at metus. Fusce magna. Sed sed lectus vitae enim tempor cursus. Cras
+sed, posuere et, urna. Quisque ut leo. Aliquam interdum hendrerit tortor.
+Vestibulum elit. Vestibulum et arcu at diam mattis commodo. Nam ipsum sem,
+ultricies at, rutrum sit amet, posuere nec, velit. Sed molestie mollis dui.
+
+
+
+Styles - tt(teletype) italic bold big small emphasis strong new lines
+ code sample keyboard variable citation abbr. ACRONYM sup sub strike strike-s underline delete insert To be or not to be font changing face, size and color
+
+
+Paragraph using the in-line style to determine the font-size (15pt) and colour
+
+
+Testing BIG, SMALL, UNDERLINE, STRIKETHROUGH, FONT color, ACRONYM, SUPERSCRIPT and SUBSCRIPT
+This is strikethrough in block and small strikethrough in small span and big strikethrough in big span and then underline and strikethrough and sup but out of span again but blue font and ACRONYM text
+
+This is a green reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 then Strikethrough reference32-47 and strikethrough reference32-47
+
+Repeated in BIG: This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 but out of span again but blue font and ACRONYM text
+
+Repeated in small: This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 but out of span again but blue font and ACRONYM text
+
+The above repeated, but starting with a paragraph with font-size specified (7pt)
+
+This is strikethrough in block and small strikethrough in small span and then underline but out of span again but blue font and ACRONYM text
+
+This is strikethrough in block and big strikethrough in big span and then underline but out of span again but blue font and ACRONYM text
+
+This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 then Strikethrough reference32-47 and strikethrough reference32-47
+
+This tests underline and strikethrough when they are used together as they both use text-decoration
+
+
+Repeated in small: This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 but out of span again but blue font and ACRONYM text
+
+Repeated in BIG but with font-size set to 7pt by in-line css: This is reference32-47 and underlined reference32-47 then reference32-47 and underlined reference32-47 but out of span again but blue font and ACRONYM text
+
+
+- Item 1
+- Item 232
+- Item 3
+- Praesent pharetra nulla in turpis. Sed ipsum nulla, sodales nec, vulputate in, scelerisque vitae, magna. Sed egestas justo nec ipsum. Nulla facilisi. Praesent sit amet pede quis metus aliquet vulputate. Donec luctus. Cras euismod tellus vel leo.
+
+- Praesent pharetra nulla in turpis. Sed ipsum nulla, sodales nec, vulputate in, scelerisque vitae, magna. Sed egestas justo nec ipsum. Nulla facilisi. Praesent sit amet pede quis metus aliquet vulputate. Donec luctus. Cras euismod tellus vel leo.
+- Subitem 2
+
+
+
+
+- Item 5
+
+
+Sed bibendum. Nunc eleifend ornare velit. Sed consectetuer urna in erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Mauris sodales semper metus. Maecenas justo libero, pretium at, malesuada eu, mollis et, arcu. Ut suscipit pede in nulla. Praesent elementum, dolor ac fringilla posuere, elit libero rutrum massa, vel tincidunt dui tellus a ante. Sed aliquet euismod dolor. Vestibulum sed dui. Duis lobortis hendrerit quam. Donec tempus orci ut libero. Pellentesque suscipit malesuada nisi.
+
+
+
+
+| Data |
+Data |
+Data |
+Data 2nd line |
+
+
+
+
+| More Data |
+More Data |
+More Data |
+Data 2nd line |
+
+
+| Data |
+Data |
+Data |
+Data 2nd line |
+
+
+| Data |
+Data |
+Data |
+Data 2nd line |
+
+
+
+
+This paragraph has border-radius and background-gradient set. Minimum padding is recommended as 1/3rd of the border-radius. Or can use $mpdf->autoPadding.
+Sed bibendum. Nunc eleifend ornare velit. Sed consectetuer urna in erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Mauris sodales semper metus. Maecenas justo libero, pretium at, malesuada eu, mollis et, arcu. Ut suscipit pede in nulla. Praesent elementum, dolor ac fringilla posuere, elit libero rutrum massa, vel tincidunt dui tellus a ante. Sed aliquet euismod dolor. Vestibulum sed dui. Duis lobortis hendrerit quam. Donec tempus orci ut libero. Pellentesque suscipit malesuada nisi.
+
+
+
+
+
+Hyphenation
+
+Little Women - Chapter One - Playing Pilgrims
+
+
+ Christmas won\'t be Christmas without any presents, grumbled Jo, lying on the rug. It\'s so dreadful to be poor! sighed Meg, looking down at her old dress. I don\'t think it\'s fair for some girls to have plenty of pretty things, and other girls nothing at all, added little Amy, with an injured sniff. We\'ve got Father and Mother, and each other, said Beth contentedly from her corner. The four young faces on which the firelight shone brightened at the cheerful words, but darkened again as Jo said sadly, We haven\'t got Father, and shall not have him for a long time. She didn\'t say perhaps never, but each silently added it, thinking of Father far away, where the fighting was. Nobody spoke for a minute; then Meg said in an altered tone, You know the reason Mother proposed not having any presents this Christmas was because it is going to be a hard winter for everyone; and she thinks we ought not to spend money for pleasure, when our men are suffering so in the army. We can\'t do much, but we can make our little sacrifices, and ought to do it gladly. But I am afraid I don\'t And Meg shook her head, as she thought regretfully of all the pretty things she wanted. But I don\'t think the little we should spend would do any good. We\'ve each got a dollar, and the army wouldn\'t be much helped by our giving that. I agree not to expect anything from Mother or you, but I do want to buy UNDINE AND SINTRAM for myself. I\'ve wanted it so long, said Jo, who was a bookworm. I planned to spend mine in new music, said Beth, with a little sigh, which no one heard but the hearth brush and kettle holder. I shall get a nice box of Faber\'s drawing pencils. I really need them, said Amy decidedly. Mother didn\'t say anything about our money, and she won\'t wish us to give up everything. Let\'s each buy what we want, and have a little fun. I\'m sure we work hard enough to earn it, cried Jo, examining the heels of her shoes in a gentlemanly manner. I know I do—teaching those tiresome children nearly all day, when I\'m longing to enjoy myself at home, began Meg, in the complaining tone again. You don\'t have half such a hard time as I do, said Jo. How would you like to be shut up for hours with a nervous, fussy old lady, who keeps you trotting, is never satisfied, and worries you till you you\'re ready to fly out the window or cry? It\'s naughty to fret, but I do think washing dishes and keeping things tidy is the worst work in the world. It makes me cross, and my hands get so stiff, I can\'t practice well at all. And Beth looked at her rough hands with a sigh that any one could hear that time. I don\'t believe any of you suffer as I do, cried Amy, for you don\'t have to go to school with impertinent girls, who plague you if you don\'t know your lessons, and laugh at your dresses, and label your father if he isn\'t rich, and insult you when your nose isn\'t nice. If you mean libel, I\'d say so, and not talk about labels, as if Papa was a pickle bottle, advised Jo, laughing. I know what I mean, and you needn\'t be satirical about it. It\'s proper to use good words, and improve your vocabulary, returned Amy, with dignity. Don\'t peck at one another, children. Don\'t you wish we had the money Papa lost when we were little, Jo? Dear me! How happy and good we\'d be, if we had no worries! said Meg, who could remember better times. You said the other day you thought we were a deal happier than the King children, for they were fighting and fretting all the time, in spite of their money. So I did, Beth. Well, I think we are. For though we do have to work, we make fun of ourselves, and are a pretty jolly set, as Jo would say. Jo does use such slang words! observed Amy, with a reproving look at the long figure stretched on the rug. Jo immediately sat up, put her hands in her pockets, and began to whistle. Don\'t, Jo. It\'s so boyish! That\'s why I do it. I detest rude, unladylike girls! I hate affected, niminy-piminy chits! Birds in their little nests agree, sang Beth, the peacemaker, with such a funny face that both sharp voices softened to a laugh, and the pecking ended for that time. Really, girls, you are both to be blamed, said Meg, beginning to lecture in her elder-sisterly fashion. You are old enough to leave off boyish tricks, and to behave better, Josephine. It didn\'t matter so much when you were a little girl, but now you are so tall, and turn up your hair, you should remember that you are a young lady. I\'m not! And if turning up my hair makes me one, I\'ll wear it in two tails till I\'m twenty, cried Jo, pulling off her net, and shaking down a chestnut mane. I hate to think I\'ve got to grow up, and be Miss March, and wear long gowns, and look as prim as a China Aster! It\'s bad enough to be a girl, anyway, when I like boy\'s games and work and manners! I can\'t get over my disappointment in not being a boy. And it\'s worse than ever now, for I\'m dying to go and fight with Papa. And I can only stay home and knit, like a poky old woman! And Jo shook the blue army sock till the needles rattled like castanets, and her ball bounded across the room. Poor Jo! It\'s too bad, but it can\'t be helped. So you must try to be contented with making your name boyish, and playing brother to us girls, said Beth, stroking the rough head with a hand that all the dish washing and dusting in the world could not make ungentle in its touch. As for you, Amy, continued Meg, you are altogether to particular and prim. Your airs are funny now, but you\'ll grow up an affected little goose, if you don\'t take care. I I like your nice manners and refined ways of speaking, when you don\'t try to be elegant. But your absurd words are as bad as Jo\'s slang. If Jo is a tomboy and Amy a goose, what am I, please? asked Beth, ready to share the lecture. You\'re a dear, and nothing else, answered Meg warmly, and no one contradicted her, for the \'Mouse\' was the pet of the family.
+
+
+
+
+
+
+
+
+
+
+Lists
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum. Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Big text indent 25mm: Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Big text indent 25mm: Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+- No class specified. Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+
+
+
+
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+- Text here lorem ipsum ibisque totum.
+
+
+
+
+
+Tables
+mPDF supports all in-line properties inside tables.
+
+| Row 1 | This is data | This is data |
+| Row 2 |
+
+ This is data p
+This is data out of p
+This is bold data p
+This is bold data out of p
+This is normal data after br
+Heading 3 inside a table
+Text here lorem ipsum ibisque totum.32
+This is data div
+This is data out of div
+This is data div (bold)
+This is data out of div
+ |
+
+Also data |
+
+
+This table has padding-top and -bottom set to 3mm i.e. padding within the cells. Also background-, border colour and style, font family and size are set by in-line CSS.
+
+| Row 1 | This is data | This is data |
+| Row 2 | This is data p | More data |
+Row 3 | This is long data | This is data |
+
+
+
+Tables
+The style sheet used for these examples shows some of the table styles I use on my website. The property \'topntail\' defined by a border-type definition e.g. "1px solid #880000" puts a border at the top and bottom of the table, and also below a header row (thead) if defined. Note also that <thead> will automatically turn on the header-repeat i.e. reproduce the header row at the top of each page.
+bpmTopic Class
+
+
+| Row 1 |
+This is data |
+This is data |
+
+
+| Row 2 |
+
+ This is data p
+ |
+
+ More data
+ |
+
+
+|
+ Row 3
+ |
+
+ This is long data
+ |
+This is data |
+
+
+|
+ Row 4 <td> cell
+ |
+This is data |
+
+ This is data
+ |
+
+
+| Row 5 |
+Also data |
+Also data |
+
+
+| Row 6 |
+Also data |
+Also data |
+
+
+| Row 7 |
+Also data |
+Also data |
+
+
+| Row 8 |
+Also data |
+Also data |
+
+
+
+
+
+bpmTopicC Class (centered) Odd and Even rows
+
+
+
+| Row header 1 |
+This is data |
+This is data |
+
+| Row header 2 |
+
+ This is data p
+ |
+
+ This is data
+ |
+
+|
+ Row header 3
+ |
+
+ This is long data
+ |
+This is data |
+
+|
+ Row header 4
+<th> cell acting as header
+ |
+This is data |
+
+ This is data
+ |
+
+| Row header 5 |
+Also data |
+Also data |
+
+| Row header 6 |
+Also data |
+Also data |
+
+| Row header 7 |
+Also data |
+Also data |
+
+| Row header 8 |
+Also data |
+Also data |
+
+
+
+
+
+bpmTopnTail Class
+
+
+| Row 1 |
+This is data |
+This is data |
+
+
+| Row 2 |
+
+ This is data p
+ |
+
+ This is data
+ |
+
+
+|
+ Row 3
+ |
+
+ This is long data
+ |
+This is data |
+
+
+|
+ Row 4 <td> cell
+ |
+This is data |
+
+ This is data
+ |
+
+
+| Row 5 |
+Also data |
+Also data |
+
+
+| Row 6 |
+Also data |
+Also data |
+
+
+| Row 7 |
+Also data |
+Also data |
+
+
+| Row 8 |
+Also data |
+Also data |
+
+
+
+bpmTopnTailC Class (centered) Odd and Even rows
+
+
+
+| Row header 1 |
+This is data |
+This is data |
+
+| Row header 2 |
+
+ This is data p
+ |
+
+ This is data
+ |
+
+|
+ Row header 3
+ |
+
+ This is long data
+ |
+This is data |
+
+|
+ Row header 4
+<th> cell acting as header
+ |
+This is data |
+
+ This is data
+ |
+
+| Row header 5 |
+Also data |
+Also data |
+
+| Row header 6 |
+Also data |
+Also data |
+
+| Row header 7 |
+Also data |
+Also data |
+
+| Row header 8 |
+Also data |
+Also data |
+
+
+
+
+
+TopnTail Class
+
+
+
+|
+ Row header 1 p
+ |
+This is data |
+This is data |
+
+| Row header 2 |
+Bottom right align |
+
+ This is data. Can use
+bold italic sub or sup text
+ |
+
+|
+ Bottom right align
+ |
+
+ This is data. This cell
+uses Cell Styles to set
+the borders.
+All borders are collapsible
+in mPDF.
+ |
+This is data |
+
+| Row header 4 |
+
+ This is data p
+ |
+More data |
+
+| Row header 5 |
+Also data merged and centered |
+
+
+
+
+
+Lists in a Table
+
+
+
+|
+ Row header 1 p
+ |
+This is data |
+This is data |
+
+| Row header 2 |
+
+
+- Item 1
+- Item 2
+
+- Subitem of ordered list
+- Subitem 2
+
+- Level 3 subitem
+- Level 3 subitem
+
+
+
+
+- Item 3
+- Another Item
+- Subitem
+
+- Level 3 subitem
+
+
+- Another Item
+
+ |
+
+Unordered list:
+
+- Item 1
+- Item 2
+
+- Subitem of unordered list
+- Subitem 2
+
+- Level 3 subitem
+- Level 3 subitem
+- Level 3 subitem
+
+
+
+
+- Item 3
+
+ |
+
+
+
+
+
+Automatic Column Width
+
+
+| Causes |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit.
+Ut a eros at ligula vehicula pretium; maecenas feugiat pede vel risus.
+Suspendisse potenti |
+
+
+| Mechanisms |
+Ut magna ipsum, tempus in, condimentum at, rutrum et, nisl. Vestibulum interdum luctus sapien. Quisque viverra. Etiam id libero at magna pellentesque aliquet. Nulla sit amet ipsum id enim tempus dictum. Maecenas consectetuer eros quis massa. Mauris semper velit vehicula purus. Duis lacus. Aenean pretium consectetuer mauris. Ut purus sem, consequat ut, fermentum sit amet, ornare sit amet, ipsum. Donec non nunc. Maecenas fringilla. Curabitur libero. In dui massa, malesuada sit amet, hendrerit vitae, viverra nec, tortor. Donec varius. Ut ut dolor et tellus adipiscing adipiscing. |
+
+
+
+
+Column span
+
+
+| Causes |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit.
+Ut a eros at ligula vehicula pretium; maecenas feugiat pede vel risus.
+Suspendisse potenti |
+
+
+| Mechanisms |
+Fusce eleifend neque sit amet erat.
+Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. |
+Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla.
+Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. |
+
+
+
+
+
+Header & Footer Rows
+A table using a header or footer row should repeat the header/footer row across pages:
+bpmTopicC Class
+
+
+
+
+
+
+
+
+| Row header 1 |
+This is data |
+This is data |
+
+| Row header 2 |
+This is data |
+
+ This is data
+ |
+
+|
+ Row header 3
+ |
+
+ This is data
+ |
+This is data |
+
+| Row header 4 |
+This is data |
+
+ This is data
+ |
+
+| Row header 5 |
+Also data |
+Also data |
+
+| Row header 6 |
+Also data |
+Also data |
+
+| Row header 7 |
+Also data |
+Also data |
+
+| Row header 8 |
+Also data |
+Also data |
+
+| Row header 9 |
+Also data |
+Also data |
+
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+| Another Row header | Also data | Also data |
+
+
+
+Autosizing Tables
+Periodic Table of elements. Tables are set by default to reduce font size if complete words will not fit inside each cell, to a maximum of 1/1.4 * the set font-size. This value can be changed by setting $mpdf->shrink_tables_to_fit=1.8 or using html attribute <table autosize="1.8">.
+
+Periodic Table
+
+
+| 1A | 2A | 3B | 4B | 5B | 6B | 7B | 8B | 8B | 8B | 1B | 2B | 3A | 4A | 5A | 6A | 7A | 8A |
+
+ |
+
+
+| H | | He |
+
+
+| Li | Be | | B | C | N | O | F | Ne |
+
+
+| Na | Mg | | Al | Si | P | S | Cl | Ar |
+
+
+| K | Ca | Sc | Ti | V | Cr | Mn | Fe | Co | Ni |
+Cu | Zn | Ga | Ge | As | Se | Br | Kr |
+
+
+| Rb | Sr | Y | Zr | Nb | Mo | Tc | Ru | Rh | Pd | Ag | Cd |
+In | Sn | Sb | Te | I | Xe |
+
+
+| Cs | Ba | La | Hf | Ta | W | Re | Os | Ir | Pt | Au |
+Hg | Tl | Pb | Bi | Po | At | Rn |
+
+
+| Fr | Ra | Ac | |
+
+
+ |
+
+ | Ce | Pr | Nd | Pm | Sm | Eu | Gd | Tb |
+Dy | Ho | Er | Tm | Yb | Lu | |
+
+
+ | Th | Pa | U | Np | Pu | Am | Cm | Bk | Cf |
+Es | Fm | Md | No | Lr | |
+
+
+
+
+
+Rotated Tables
+This is set to rotate -90 degrees (counterclockwise).
+
+Periodic Table
+
+
+| 1A | 2A | 3B | 4B | 5B | 6B | 7B | 8B | 8B | 8B | 1B | 2B | 3A | 4A | 5A | 6A | 7A | 8A |
+
+ |
+ |
+
+
+| H | | | He |
+
+
+| Li | Be | | B | C | N | O | F | Ne |
+
+
+| Na | Mg | | Al | Si | P | S | Cl | Ar |
+
+
+| K | Ca | Sc | Ti | V | Cr | Mn | Fe | Co | Ni | Cu |
+Zn | Ga | Ge | As | Se | Br | Kr |
+
+
+| Rb | Sr | Y | Zr | Nb | Mo | Tc | Ru | Rh | Pd |
+Ag | Cd | In | Sn | Sb | Te | I | Xe |
+
+
+| Cs | Ba | La | Hf | Ta | W | Re | Os | Ir | Pt | Au |
+Hg | Tl | Pb | Bi | Po | At | Rn |
+
+
+| Fr | Ra | Ac |
+
+
+ |
+ |
+
+
+ | Ce | Pr | Nd | Pm | Sm | Eu | Gd | Tb | Dy |
+Ho | Er | Tm | Yb | Lu | |
+
+
+ | Th | Pa | U | Np | Pu | Am | Cm | Bk |
+Cf | Es | Fm | Md | No | Lr | |
+
+
+
+
+
+Rotated text in Tables
+
+Periodic Table
+
+
+
+Element type 1A Second line | Element type longer 2A |
+Element type 3B | Element type 4B | Element type 5B | Element type 6B | 7B | 8B |
+Element type 8B R | 8B | Element type 1B | 2B |
+Element type 3A | Element type 4A | Element type 5A | Element type 6A | 7A | Element type 8A |
+
+
+
+
+
+| H | | | He |
+
+
+| Li | Be | | B | C | N | O | F | Ne |
+
+
+| Na | Mg | | Al | Si | P | S | Cl | Ar |
+
+
+| K | Ca | Sc | Ti | Va | Cr | Mn | Fe | Co | Ni |
+Cu | Zn | Ga | Ge | As | Se | Br | Kr |
+
+
+| Rb | Sr | Y | Zr | Nb | Mo | Tc | Ru |
+Rh | Pd | Ag | Cd | In | Sn |
+Sb | Te | I | Xe |
+
+
+| Cs | Ba | La | Hf | Ta | W | Re | Os | Ir |
+Pt | Au | Hg | Tl | Pb | Bi | Po | At | Rn |
+
+
+| Fr | Ra | Ac |
+
+
+ |
+Ce | Pr | Nd | Pm | Sm | Eu | Gd | Tb | Dy |
+Ho | Er | Tm | Yb | Lu | |
+
+
+ |
+Th | Pa | U | Np | Pu | Am | Cm | Bk | Cf | Es |
+Fm | Md | No | Lr | |
+
+
+
+
+
+
+
+
+Nested Tables
+
+
+Text before table
+
+
+
+
+
+
+| This is data |
+This is data |
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+| Row C |
+C2 |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+This is data |
+
+
+| This is data |
+This is data |
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+| Row C |
+C2 |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+This is data |
+
+
+| This is data |
+This is data |
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+| Row C |
+C2 |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+This is data |
+
+
+| This is data |
+This is data |
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+| Row C |
+C2 |
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci. |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+This is data |
+
+
+| This is data |
+This is data |
+This is data |
+This is data |
+
+
+| This is data |
+ |
+This is data |
+This is data |
+
+
+| This is data |
+This is data |
+This is data |
+This is data |
+
+
+
+
+
+
+
+ Text before table
+
+
+
+
+| Row 1 |
+This is data |
+
+Text before table
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+| Row C |
+C2 |
+C3 |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+Text after table
+ |
+This is data |
+
+
+| Row 2 |
+This is data |
+This is data |
+This is data |
+
+
+| Row 3 |
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+ |
+B4 |
+
+
+| Row C |
+C2 |
+
+
+
+
+| F1 |
+F2 |
+
+
+| Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec et nulla. Sed quis orci. |
+G2 |
+
+
+ |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+B3 |
+B4 |
+
+
+| Row C |
+C2 |
+C3 |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+This is data |
+
+
+| Row 4 |
+This is data |
+
+
+
+| Row A |
+A2 |
+A3 |
+A4 |
+
+
+| Row B |
+B2 |
+ |
+B4 |
+
+
+| Row C |
+C2 |
+
+
+
+
+| F1 |
+F2 |
+
+
+| Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec et nulla. Sed quis orci. |
+G2 |
+
+
+ |
+C4 |
+
+
+| Row D |
+D2 |
+D3 |
+D4 |
+
+
+ |
+This is data |
+
+
+
+
+
+
+
+
+
+Forms
+
+
+
+
+
+Annotations
+Praesent pharetra nulla in turpis. Sed ipsum nulla, sodales nec, vulputate in, scelerisque vitae, magna. Sed egestas justo nec ipsum. Nulla facilisi. Praesent sit amet pede quis metus aliquet vulputate. Donec luctus. Cras euismod tellus vel leo. Cras tellus. Fusce aliquet. Curabitur tincidunt viverra ligula. Fusce eget erat. Donec pede. Vestibulum id felis. Phasellus tincidunt ligula non pede. Morbi turpis. In vitae dui non erat placerat malesuada. Mauris adipiscing congue ante. Proin at erat. Aliquam mattis.
+P: Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+
+
+
+
+Full Images & Barcode
+On the first and last page of this document, an image is reproduced full page size by placing it inside a DIV element with CSS "position:absolute". In all other situations, images are constrained to the width and height of the printable page (i.e. inside the margins). The image on the back page has CSS "opacity:0.5".
+
+
+
+'. nl2br(htmlspecialchars('/* ALTERNATIVE PHP METHOD */
+$mpdf->SetAlpha(0.5);
+$mpdf->Image(\'clematis.jpg\',0,0,210,297,\'jpg\',\'\',true, false);
+// the last "false" allows a full page picture
+$mpdf->SetAlpha(1);
+')) .'
+
+
+The back cover also has an ISBN barcode
+
+
+'. nl2br(htmlspecialchars('/* ALTERNATIVE PHP METHOD */
+$mpdf->writeBarcode(\'978-0-9542246-0-8\', 1, 130, 230, 1,0, 3,3,4,4);
+')) .'
+
+
+But next is inserted the Index, which can also be done like this:
+
+
+'. nl2br(htmlspecialchars('/* ALTERNATIVE PHP METHOD */
+$mpdf->AddPage(\'\',NEXT-ODD\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',\'\',-1,-1,-1,-1);
+$mpdf->WriteHTML(\' Index\');
+$mpdf->WriteHTML(\'\');
+')) .'
+
+
+
+
+
+
+Index
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+
+include("../mpdf.php");
+
+$mpdf=new mPDF('','A4','','',25,15,21,22,10,10);
+
+$mpdf->progbar_heading = 'mPDF file progress (Advanced)';
+$mpdf->StartProgressBarOutput(2);
+
+$mpdf->mirrorMargins = 1;
+$mpdf->SetDisplayMode('fullpage','two');
+$mpdf->list_number_suffix = ')';
+
+$mpdf->debug = true;
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+
+exit;
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example52_lineheight.htm b/mpdf/examples/example52_lineheight.htm
new file mode 100644
index 0000000..73eca93
--- /dev/null
+++ b/mpdf/examples/example52_lineheight.htm
@@ -0,0 +1,36 @@
+
+
+
+
+
+Line-height & vertical alignment
+In these examples, top and bottom padding are set to 0, so the block height = line height.
+The inline text (set to a larger font-size) inherits the line-height as a factor of the largest font-size i.e. the line height will expand to reflect the largest font on the line.
+Line-height: "normal" (set in mPDF by default as 1.33).
+Normal text 16pt font-size  and normal again
+
+Line-height: 2.0 When using relative line-heights, the text is aligned vertically so that the centre-line of the line goes throught the middle of the largest font.
+Normal text 16pt font-size  and normal again
+
+Line-heights set as a percentages are computed on the base font-size, and are then inherited and treated the same as absolute lengths. This is also true for "em" values. The line-height of this line is set as 200% of the paragraph font-size (10pt).
+When using absolute line-heights, the text is aligned vertically so that the centre-line of the line goes throught the middle of the base font.
+This means that as far as possible, multiple lines will remain equally spaced
+Line-height: 200%
+Normal text 16pt font-size  and normal again
+
+If the line includes a font-size greater than 1.6 times the computed line-height, then the text baseline is dropped so that the text will approximately fit within the line-height.
+ Line-height: 2em
+Normal text 18pt font-size  and normal again
+
+If the line includes a font-size greater than 2 times the computed line-height, then the line-height is increased to accommodate the larger fontsize.
+Line-height: 2em
+Normal text 24pt font-size  and normal again
+
+
\ No newline at end of file
diff --git a/mpdf/examples/example52_new_mPDF_4-2_features.php b/mpdf/examples/example52_new_mPDF_4-2_features.php
new file mode 100644
index 0000000..6cf48c9
--- /dev/null
+++ b/mpdf/examples/example52_new_mPDF_4-2_features.php
@@ -0,0 +1,492 @@
+
+body {
+ font-family: \'DejaVu Sans Condensed\';
+}
+@page {
+ margin-top: 2.0cm;
+ margin-bottom: 2.0cm;
+ margin-left: 2.3cm;
+ margin-right: 1.7cm;
+ margin-header: 8mm;
+ margin-footer: 8mm;
+ footer: html_myHTMLFooter;
+ background-color:#ffffff;
+}
+
+@page :first {
+ margin-top: 6.5cm;
+ margin-bottom: 2cm;
+ header: html_myHTMLHeader;
+ footer: _blank;
+ resetpagenum: 1;
+ background-gradient: linear #FFFFFF #FFFF44 0 0.5 1 0.5;
+ background: #ccffff url(bgbarcode.png) repeat-y fixed left top;
+}
+@page letterhead {
+ margin-top: 2.0cm;
+ margin-bottom: 2.0cm;
+ margin-left: 2.3cm;
+ margin-right: 1.7cm;
+ margin-header: 8mm;
+ margin-footer: 8mm;
+ footer: html_myHTMLFooter;
+ background-color:#ffffff;
+}
+
+@page letterhead :first {
+ margin-top: 6.5cm;
+ margin-bottom: 2cm;
+ header: html_myHTMLHeader;
+ footer: _blank;
+ resetpagenum: 1;
+}
+.gradient {
+ border:0.1mm solid #220044;
+ background-color: #f0f2ff;
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+}
+.rounded {
+ border:0.1mm solid #220044;
+ background-color: #f0f2ff;
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+ border-radius: 2mm;
+ background-clip: border-box;
+}
+h4 {
+ font-weight: bold;
+ margin-top: 1em;
+ margin-bottom: 0.3em;
+}
+div.text {
+ padding:1em;
+ margin-bottom: 0.25em;
+ text-align:justify;
+}
+div.artificial {
+ font-family: arialuni; /* custom font using MS Arial Unicode */
+}
+p { margin-top: 0; }
+.code {
+ font-family: mono;
+ font-size: 9pt;
+ background-color: #d5d5d5;
+ margin: 1em 1cm;
+ padding: 0 0.3cm;
+}
+
+
+
+
+
+
+
+
+mPDF Version 4.2
+New Features
+
+
+
+- image handling improved
+- table layout - additional control over resizing
+- vertical-alignment of images - better support for all CSS types
+- top and bottom margins collapse between block elements
+- improved support for CSS line-height
+- display progress bar whilst generating file
+- CSS @page selector can be specified when adding a pagebreak
+- CSS @page selector allows different margins, backgrounds, headers/footers on :first :left and :right pages
+- PNG images with alpha channel fully supported
+- ability to generate italic and bold font variants from base font file
+- CJK fonts to embed as subsets
+- "double" border on block elements
+- character substitution for missing characters in UTF-8 fonts
+- direct passing of dynamically produced image data
+- background-gradient and background-image can now co-exist
+
+
+Note: automatic top- and bottom-margin to accomodate varying header/footer size was introduced in v4.0 but was not highlighted cf. AutoHeaderMargin in the Manual.
+
+
+
+
+
+ Page backgrounds
+Background images, gradients and/or colours can be used together on the same page. On this page, the bars on the left hand side are created using a background-image, whilst a background-gradient sets the background to the whole page.
+
+
+
+
+ CSS "double" border
+Block elements can now use the CSS property: border(style) = double. See also the tiger logo in the header of this page.
+
+
+
+
+ CJK fonts to embed as subsets
+When writing documents with Chinese, Japanese or Korean characters, mPDF has previously required the end-user to download Adobe\'s free CJK font pack.
+The ability to embed font subsets now makes it feasible to use open license CJK fonts. 2 fonts are now available to download as an additional font-pack:
+
+- zn_hannom_a - contains all characters in the SJIS, BIG-5, and GBK codepages; original file was Han Nom A font (Hi-res version) from http://vietunicode.sourceforge.net/fonts/fonts_hannom.html
+- unbatang - contains all the (Korean) characters in the UHC codepage; original file from from http://kldp.net/projects/unfonts/download
+
+The following characters only added an extra 15kB to the size of this PDF file, and approximately 0.15 seconds extra to compile:
+
+Chinese (traditional) '."\xe6\x86\x82\xe9\xac\xb1".' ; chinese (simplified) '."\xe6\x9d\xa5\xe8\x87\xaa".' ; japanese '."\xe3\x81\x9f\xe3\x82\x90".' ; korean '."\xed\x82\xa4\xec\x8a\xa4".'
+
+
+
+
+ Artificial Bold and Italic
+The text in this block is in ArialUnicodeMS font. Using embedded subsets it covers most characters you want to print - BUT it does not have bold, italic, or bold-italic forms.
+From version 4.2, mPDF will create "artificial" font styles if they are not available as separate font files:
+ The quick brown fox jumps over a lazy dog
+ The quick brown fox jumps over a lazy dog
+ The quick brown fox jumps over a lazy dog
+
+
+
+
+ Character substitution in UTF-8 files
+This paragraph has the font-family set to Trebuchet MS, and the document has the default font set as DejaVuSansCondensed.
+The following characters are not present in the Trebuchet font, and are substituted from the core Adobe Zapfdingbats font:
+
+✐ ✑ ✒ ✓ ✔ ✕ ✖ ✗ ✘ ✙ ✚ ✛ ✜ ✝ ✞ ✟
+The characters are not present in the Trebuchet font, and are substituted from the (default) DejaVuSansCondensed font:
+ʀ ʁ ʂ ʃ ʄ ʅ ʆ ʇ ʈ ʉ ʊ ʋ ʌ ʍ ʎ ʏ
+Character substitution in UTF-8 files is enabled by setting:
+
+$mpdf->useSubstitutionsMB = true;
+
+ NB In mPDF 5.0 this has changed to
+
+$mpdf->useSubstitutions = true;
+
+
+It is not recommended to enable this for regular use, as it will add to the processing time.
+
+
+
+
+
+
+Margin-collapse
+mPDF has always allowed margins to be collapsed at the top and bottom of pages. This is specified by the custom CSS property "margin-collapse: collapse"
+
+mPDF 4.2 also allows margins to collapse between block elements on the page. This is the default behaviour in browsers, and has been enabled in mPDF 4.2 by default.
+
+In the next 2 paragraphs, the first one has the margin-bottom set to 3em, and the second has the margin-top set to 0em. So the vertical-space between paragraphs is 3em:
+
+The quick brown fox jumps over a lazy dog
+The quick brown fox jumps over a lazy dog
+
+In the next 2 paragraphs, the first one has the margin-bottom set to 2em, and the second has the margin-top set to 1em. The margins collapse to the larger of the adjoining margins i.e. 2em:
+
+The quick brown fox jumps over a lazy dog
+The quick brown fox jumps over a lazy dog
+
+
+
+
+Images
+
+PNG Alpha channel
+PNG alpha channel transparency is now fully supported, and works against solid backgrounds, gradients or background images:
+
+
+
+
+Image Border and padding
+Image padding is now supported as well as border and margin:
+
+
+
+Vertical alignment
+From mPDF version 4.2 onwards, most of the values for "vertical-align" are supported: top, bottom, middle, baseline, text-top, and text-bottom.
+Note: The default value for vertical alignment has been changed to baseline, and the default padding to 0, consistent with most browsers.
+
+
+
+baseline: 
+text-bottom: 
+middle: 
+bottom: 
+text-top: 
+top: 
+
+
+
+
+Image Alignment
+From mPDF version 4.2 onwards, in-line images can be individually aligned (vertically).
+
+
+
+These images 
+are 
+ top 
+aligned 
+
+
+
+These images 
+are 
+ text-top 
+aligned 
+
+
+
+These images 
+are 
+ bottom 
+aligned 
+
+
+
+These images 
+are 
+ text-bottom 
+aligned 
+
+
+
+These images 
+are 
+ baseline 
+aligned 
+
+
+
+These images 
+are 
+ middle 
+aligned 
+
+
+
+These images 
+are 
+ middle 
+aligned 
+
+
+
+Images from PHP
+
+
+
+
+This image was created with the following code:
+
+
+ $img = imagecreatetruecolor(200, 200);
+ $white = imagecolorallocate($img, 255, 255, 255);
+ $red = imagecolorallocate($img, 255, 0, 0);
+ $green = imagecolorallocate($img, 0, 255, 0);
+ $blue = imagecolorallocate($img, 0, 0, 255);
+ imagearc($img, 100, 100, 200, 200, 0, 360, $white);
+ imagearc($img, 100, 100, 150, 150, 25, 155, $red);
+ imagearc($img, 60, 75, 50, 50, 0, 360, $green);
+ imagearc($img, 140, 75, 50, 50, 0, 360, $blue);
+ ob_start();
+ imagejpeg($img);
+ $mpdf->smileyface = ob_get_clean();
+ imagedestroy($img);
+
+and written to the document using:
+
+<img src="var:smileyface" />
+
+
+
+
+Line-height inheritance
+Line-height inheritance has been altered to follow the CSS2 recommendation:
+
+- normal is inherited as "normal"
+- 1.2 is inherited as a factor
+- 120% is converted to an actual value and then inherited as the computed value
+- em is converted to an actual value and then inherited as the computed value
+- px pt mm are inherited as fixed values
+
+
+Relative values (e.g. 1.3, normal)
+
+This DIV has the line-height set as "2.0" and font-size as 12pt. The line-height is therefore 24pt, but the factor of 2 is inherited...
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse...
+
+This DIV has the font-size set as 8pt. The line-height of 2 is inherited...
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci.
+
+This DIV has the font-size set as 18pt. The line-height of 2 is inherited...
+Nulla felis erat, imperdiet eu, ullamcorper non...
+
+
+
+
+Absolute values (e.g. 130%, 1.3em, 18pt)
+
+This DIV has the line-height set as "200%" and font-size as 12pt. The computed line-height of 24pt is inherited...
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse...
+
+This DIV has the font-size set as 8pt. The computed line-height of 24pt is inherited...
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci.
+
+This DIV has the font-size set as 18pt. The computed line-height of 24pt is inherited...
+Nulla felis erat, imperdiet eu, ullamcorper non...
+
+
+
+
+
+
+Line-height & vertical alignment
+In these examples, top and bottom padding are set to 0, so the block height = line height.
+The inline text (set to a larger font-size) inherits the line-height as a factor of the largest font-size i.e. the line height will expand to reflect the largest font on the line.
+Line-height: "normal" (set in mPDF by default as 1.33).
+Normal text 16pt font-size  and normal again
+
+Line-height: 2.0 When using relative line-heights, the text is aligned vertically so that the centre-line of the line goes throught the middle of the largest font.
+Normal text 16pt font-size  and normal again
+
+Line-heights set as a percentages are computed on the base font-size, and are then inherited and treated the same as absolute lengths. This is also true for "em" values. The line-height of this line is set as 200% of the paragraph font-size (10pt).
+When using absolute line-heights, the text is aligned vertically so that the centre-line of the line goes throught the middle of the base font.
+This means that as far as possible, multiple lines will remain equally spaced
+Line-height: 200%
+Normal text 16pt font-size  and normal again
+
+If the line includes a font-size greater than 1.6 times the computed line-height, then the text baseline is dropped so that the text will approximately fit within the line-height.
+ Line-height: 2em
+Normal text 18pt font-size  and normal again
+
+If the line includes a font-size greater than 2 times the computed line-height, then the line-height is increased to accommodate the larger fontsize.
+Line-height: 2em
+Normal text 24pt font-size  and normal again
+
+
+This broadly reflects the behaviour of IE and Firefox. Note that tall characters such as  may fall outside the computed line-heights. See the same in an HTML page.
+
+
+
+Extended use of CSS @page selectors
+The CSS @page selector, together with the pseudo-selectors :first :left :right have increased support in mPDF 4.2
+A named @page can be selected when forcing a new page, e.g. this page was started with:
+<pagebreak page-selector="letterhead" />
+
+The header and background on this page (and page 1 of the document) are set by the CSS selector: @page letterhead :first {} whilst subsequent pages have no header, a footer, and no background.
+
+CSS @page selectors allow different margins, backgrounds, headers/footers to be set on :first :left and :right pages. Only fixed or mirrored left- and right-margins are supported (i.e. cannot specify different margins for :left and :right).
+
+This layout can be used to produce company letters with only the first page on letterheaded paper.
+
+
+Table Layout control
+mPDF attempts to layout tables according to HTML and CSS specifications. However, because of the difference between screen and paged media, mPDF resizes tables when necessary to make them fit the page. This will happen if the minimum table-width is greater than the page-width. Minimum table-width is defined as the minimum width to accomodate the longest word in each column i.e. words will never be split.
+
+This resizing (minimum-width) can be disabled using a custom CSS property "overflow" on the TABLE tag. There are 4 options:
+<table style="overflow: auto"> (this is the default, using resizing)
+
+| Verylongwordwithnospacesinitatall |
+Verylongwordwithnospacesinitatall |
+Verylongwordwithnospacesinitatall |
+
+
+<table style="overflow: visible"> (disables resizing, but allows overflow to show)
+
+| Verylongwordwithnospacesinitatall |
+Verylongwordwithnospacesinitatall |
+Verylongwordwithnospacesinitatall |
+
+
+
+<table style="overflow: hidden"> (disables resizing, and hides/clips any overflow)
+
+| Verylongwordwithnospacesinitatall |
+Verylongwordwithnospacesinitatall |
+Verylongwordwithnospacesinitatall |
+
+
+
+<table style="overflow: wrap"> (forces words to break as necessary)
+
+| Verylongwordwithnospacesinitatall |
+Verylongwordwithnospacesinitatall |
+Verylongwordwithnospacesinitatall |
+
+
+
+
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+
+include("../mpdf.php");
+
+$mpdf=new mPDF('','A4','','',15,15,20,20,5,5);
+
+$mpdf->SetDisplayMode('fullpage');
+
+$mpdf->useSubstitutions = true;
+
+// Dynamically create image in var:smileyface
+ $img = imagecreatetruecolor(200, 200);
+ $white = imagecolorallocate($img, 255, 255, 255);
+ $red = imagecolorallocate($img, 255, 0, 0);
+ $green = imagecolorallocate($img, 0, 255, 0);
+ $blue = imagecolorallocate($img, 0, 0, 255);
+ imagearc($img, 100, 100, 200, 200, 0, 360, $white);
+ imagearc($img, 100, 100, 150, 150, 25, 155, $red);
+ imagearc($img, 60, 75, 50, 50, 0, 360, $green);
+ imagearc($img, 140, 75, 50, 50, 0, 360, $blue);
+ ob_start();
+ imagejpeg($img);
+ $mpdf->smileyface = ob_get_clean();
+ imagedestroy($img);
+
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+exit;
+
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example54_new_mPDF_v5-1_features_gradients_and_images.php b/mpdf/examples/example54_new_mPDF_v5-1_features_gradients_and_images.php
new file mode 100644
index 0000000..ec8f1b0
--- /dev/null
+++ b/mpdf/examples/example54_new_mPDF_v5-1_features_gradients_and_images.php
@@ -0,0 +1,479 @@
+
+body {
+ font-family: sans-serif;
+ font-size: 10pt;
+}
+h4 {
+ font-variant: small-caps;
+}
+h5 {
+ margin-bottom: 0;
+ color: #110044;
+}
+p { margin-top: 0; }
+dl {
+ margin: 0;
+}
+table {
+ border-spacing: 0.5em;
+ border: 7px dashed teal;
+}
+.table1 {
+ background-image: -moz-linear-gradient(left, #07cdde 20%, #00f200 );
+}
+.table1 tr.thisrow1 {
+ background-image-resolution: 300dpi;
+ background: transparent url(\'bayeux1.jpg\') repeat scroll left top;
+}
+.table1 tr.thisrow1 td {
+ height: 28mm;
+}
+.table1 tr.thisrow2 {
+ background-image: none;
+ background: -moz-linear-gradient(left, #c7Fdde 20%, #FF0000 );
+ background: -webkit-gradient(linear, left bottom, left top, color-stop(0.29, rgb(90,83,12)), color-stop(0.65, rgb(117,117,39)), color-stop(0.83, rgb(153,153,67)));
+}
+.table3 {
+ border-collapse: collapse;
+ /* background-gradient: linear #07cdde #00f200 1 0 0.5 1; */
+ background: -moz-linear-gradient(left, #07cdde 20%, #00f200 );
+}
+tr.thisrow {
+ border: 3px dashed red;
+ background: transparent url(\'bayeux1.jpg\') repeat scroll left top;
+}
+.table3 tr.thisrow {
+ border: 3px dashed orange;
+ background: transparent url(\'bgrock.jpg\') repeat scroll left top;
+}
+tfoot tr {
+ border: 5px dashed blue;
+ /* background-gradient: linear #c7Fdde #FF0000 1 0 0.5 0; */
+ background: -moz-linear-gradient(left, #c7Fdde 20%, #FF0000 );
+}
+.gradient {
+ border:0.1mm solid #220044;
+ background-color: #f0f2ff;
+ background: linear-gradient(top, #c7cdde, #f0f2ff);
+}
+.rounded {
+ border:0.1mm solid #220044;
+ background-color: #f0f2ff;
+ background: linear-gradient(top, #c7cdde, #f0f2ff);
+ border-radius: 2mm;
+ background-clip: border-box;
+}
+div.text {
+ padding:1em;
+ margin: 1em 0;
+ text-align:justify;
+}
+.code {
+ font-family: mono;
+ font-size: 9pt;
+ background-color: #d5d5d5;
+ margin: 1em 1cm;
+ padding: 0 0.3cm;
+}
+
+
+
+
+
+mPDF
+New features in mPDF Version 5.1
+
+
+
+- CSS background (images, colours or gradients) on <TR> and <TABLE>
+- CSS border on <TR> (only in border-collapsed mode)
+- support for Mozilla and CSS3 gradient syntax:
+
+- -moz-linear-gradient, linear-gradient
+- -moz-radial-gradient, radial-gradient
+- -moz-repeating-linear-gradient, linear-repeating-gradient
+- -moz-repeating-radial-gradient, radial-repeating-gradient
+
+
+- expanded support for gradients (including in SVG images):
+
+- multiple colour \'stops\'
+- opacity (transparency)
+- angle and/or position can be specified
+
+
+- gradient can be used as an image mask (custom mPDF styles: gradient-mask)
+- CSS3 image-orientation supported for <IMG> (similar to existing custom mPDF attribute: rotate)
+- CSS3 image-resolution supported for <IMG>
+- background-image-resolution (custom mPDF CSS-type style) to define resolution of background images
+- improved support for SVG images
+- SVG and WMF images supported in background-image
+- file attachments (embedded in PDF file) → → → → →
+
+
+
+Tables: borders, background images & gradients
+
+Background images or gradients can be set on whole tables or table rows (as well as individual table cells)
+
+
+| Row 1 | This is data | This is data |
+| This row has | a background-image | of the bayeux tapestry |
+Row 3 | This is long data | This is data |
+| This row has | a gradient set | which spans all 3 cells |
+| Row 5 | Also data | Also data |
+
+
+
+Border can be set on table rows (only when border-collapse is set to collapse)
+
+
+| Row 1 | This is data | This is data |
+| Row 2 | This is data This is data This is data This is data | Also data |
+Row 3 | This is long data | This is data |
+
+
+
+
+
+
+
+
+Mozilla and CSS3 gradient syntax
+
+
+Linear gradients
+ Angle set AND points e.g. -moz-linear-gradient(34% 84% 30deg, red, orange, yellow...
+
+
+| top right 210 degrees |
+ |
+ |
+
+
+| 30% 80% 60 degrees |
+ |
+ |
+
+
+| 10px 40px 325 degrees |
+ |
+ |
+
+
+| bottom left 135deg |
+ |
+ |
+
+
+
+
+ Points set only e.g. -moz-linear-gradient(bottom left, red, orange, yellow...
+
+
+
+| bottom right |
+ |
+ |
+
+
+| top |
+ |
+ |
+
+
+| 10px 40px |
+ |
+ |
+
+
+| 30% 10% |
+ |
+ |
+
+
+
+
+
+ Angle set but no points e.g. -moz-linear-gradient(30deg, red, orange, yellow...
+
+
+
+| 90 degrees |
+ |
+ |
+
+
+| 120 degrees |
+ |
+ |
+
+
+| 180 degrees |
+ |
+ |
+
+
+| 210 degrees |
+ |
+ |
+
+
+
+
+
+
+ Linear and radial gradients are not specified in the CSS2 specification. The CSS3 draft specification gives a way of outputting gradients, but currently this is not supported by any browser.
+ Mozilla (Firefox) has developed its own way of producing gradients, which approximates to the CSS3 draft specification:
+
+- -moz-linear-gradient
+- -moz-repeating-linear-gradient
+- -moz-radial-gradient and
+- -moz-repeating-radial-gradient
+
+ WebKit (Safari, Chrome etc.) have a separate way of defining gradients using -webkit-gradient
+ Microsoft (IE) does not support any such method of specifying gradients, but does have a function filter: progid:DXImageTransform.Microsoft.gradient()
+ When writing HTML for cross-browser compatibility, it is common to see something like this in a stylesheet:
+
+background: #999999; /* for non-css3 browsers */
+filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#cccccc\', endColorstr=\'#000000\'); /* for IE */
+background: -webkit-gradient(linear, left top, left bottom, from(#cccccc), to(#000000)); /* for webkit browsers */
+background: -moz-linear-gradient(top, #cccccc, #000000); /* for firefox 3.6+ */
+
+
+
+
+ mPDF versions <= 5.0 supported a custom style property background-gradient which accepted both linear and radial gradients. These continue to be supported (and both old and new forms can be used together); note the differences:
+
+- mPDF background-gradients are output underneath background-images, and both can be specified; whereas the new CSS3/Mozilla-type gradients are defined as a type of background-image
+- CSS3/Mozilla gradients support multiple colour-stops, opacity, repeating-gradients, and a greater number of options for defining the gradient axis (linear gradients) or shape and extent (radial gradients)
+
+
+ mPDF will attempt to parse a CSS stylesheet written for cross-browser compatibility:
+
+- parse and support -moz type gradients
+- parse and support CSS3 gradient syntax
+- ignore -webkit syntax gradients
+
+
+
+ More details can be found at:
+
+
+
+
+
+Repeating gradients
+
+
+background: repeating-linear-gradient(red, blue 20px, red 40px);
+
+background: -moz-repeating-linear-gradient(top left -45deg, red, red 10px, rgba(255,255,255,0) 10px, rgba(255,255,255,0) 20px);
+
+
+
+
+
+
+
+
+
+
+background: repeating-radial-gradient(20px 30px, circle farthest-side, red, yellow, green 10px, yellow 15px, red 20px);
+
+background: repeating-radial-gradient(red, blue 20px, red 40px);
+
+
+
+
+
+
+
+
+
+
+Radial gradients
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Gradient Image mask
+
+Gradients (linear or radial) can also be used to produce \'masks\' for images. The same syntax is used as for background gradients (e.g. -moz-linear-gradient) but is set using a custom mPDF style: gradient-mask. The rgba() method for defining colours is used: colours are ignored, but the opacity value is used to mask the image.
+
+<img src="windmill.jpg" style="gradient-mask: -moz-radial-gradient(center, ellipse closest-side, rgba(255,255,255,1), rgba(255,255,255,1) 30%, rgba(255,255,255,0) 90%, rgba(255,255,255,0));" />
+
<img src="windmill.jpg" style="gradient-mask: -moz-radial-gradient(center, ellipse closest-side, rgba(255,255,255,1), rgba(255,255,255,1) 70%, rgba(255,255,255,0) 90%, rgba(255,255,255,0));" />
+
<img src="windmill.jpg" style="gradient-mask: -moz-linear-gradient(left, rgba(0,0,0,0) , rgba(0,0,0,1) 50% , rgba(0,0,0,0) 100%);" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Image orientation
+
+Images can be rotated using a custom mPDF HTML attribute: rotate. mPDF now also supports the draft CSS3 property of image-orientation. Rotation can be expressed in degrees, radians or grad units; it is corrected if necessary to an orthogonal rotation i.e. 90, 180 or 270 degrees. NB This does not work on background-images.
+<img src="tiger2.png" style="image-orientation: -90deg" width="100" />
+
+<img src="tiger2.png" style="image-orientation: 3.14159rad" width="100" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Image resolution
+
+
+Image files (which do not have an output width or height specified) are displayed in mPDF at the default resolution set by the variable $mpdf->img_dpi. This can be overridden using the draft CSS3 property \'image-resolution\', which can be applied to <IMG> or background-images.
+
+The next 3 image files are identical (300px x 300px) but they have been saved with a different specified resolution: the first at 96dpi, the second at 300dpi.
+
+NB When used in combination with \'from-image\', a specified resolution is only used if the image does not have an intrinsic resolution. Only JPG, PNG and BMP files store a specified DPI resolution in the file.
+
+<img src="tiger300px300dpi.png" style="image-resolution: from-image;" />
+ <img src="tiger300px300dpi.png" style="image-resolution: 150dpi;" />
+ <img src="tiger300px96dpi.png" style="image-resolution: from-image;" />
+
+
+
+
+
+
+
+
+
+
+Image resolution can also be applied to a background-image. This can be used as an alternative to the custom mPDF style property - \'background-image-resize\'
+
+<div height="300px" width="300px" style="background: #FFCCEE url(tiger300px96dpi.png); background-image-resolution: from-image; border: 0.2mm solid black;">
+Hallo world
+
+
+
+
+<div height="300px" width="300px" style="background-image: url(tiger300px300dpi.png); background-image-resolution: from-image; border: 0.2mm solid black;">
+
+
+
+
+
+
+
+
+
+
+
+
+Mixed effects
+
+
+
+
+
+
+
+
+Hallo World
+
+
+Hallo World
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+';
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output(); exit;
+
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example55_new_mPDF_v5-1_color_and_other_features.php b/mpdf/examples/example55_new_mPDF_v5-1_color_and_other_features.php
new file mode 100644
index 0000000..0f3b70e
--- /dev/null
+++ b/mpdf/examples/example55_new_mPDF_v5-1_color_and_other_features.php
@@ -0,0 +1,421 @@
+useKerning=true;
+
+$mpdf->restrictColorSpace=3; // forces everything to convert to CMYK colors
+
+$mpdf->AddSpotColor('PANTONE 534 EC',85,65,47,9);
+
+//==============================================================
+$html = '
+
+
+
+
+
+mPDF
+Other new features in mPDF Version 5.1
+
+
+
+- Kerning
+- Letter- and word-spacing
+- Small-caps improved to work with justified text, and now with kerning, letter- and word-spacing
+- Bleed area on @page media
+- Colorspace and colour conversion (almost everything except BMP images)
+- Spot colours
+- PDF/X files
+- dir="rtl"
+- numeric list-styles for arabic and indic
+
+
+
+
+
+Kerning
+
+Font kerning is supported. This corrects the inter-character spacing between specific pairs of letters. It is dependent on kerning information being available in the original font file.
+
+You need to set $mpdf->useKerning=true; either in the config.php configuration file, or at runtime. This causes the kerning information to be loaded when fonts are accessed (and will therefore increase memory usage).
+
+You can then set kerning on or off using the draft CSS3 style property "font-kerning". Values of normal or auto will turn kerning on; "none" will turn kerning off.
+
+
+
+Off: AWAY To War.
+
+
+
+On: AWAY To War.
+
+
+
+
+Letter and word spacing & text justification
+
+Letter- and word-spacing can be set on almost all block and in-line style elements, using the CSS properties letter-spacing and word-spacing. Values of normal or a length can be specified (em or ex recommended).
+Note that setting the letter-spacing value (including setting it to zero) will prevent any additional letter-spacing to be added when full-justifying text. The word-spacing value, however, is a minimum value, and can be increased in order to justify text.
+
+
+Text-align: justify - no longer uses configurable variable $jSpacing= C | W | \'\'
+
+The default value is for mixed letter- and word-spacing, set by jSWord and jSmaxChar
+
+If a line contains a cursive script (RTL or Indic [devanagari, punjabi, bengali]) then it prevents letter-spacing
+for justification on that line - effectively the same as setting letter-spacing:0
+
+Spacing values have been removed from the config_cp.php configuration file, so the "lang" property
+(in config_cp) no longer determines justification behaviour (this includes the use of Autofont()).
+
+When using RTL or Indic [devanagari, punjabi, bengali] scripts, you should set CSS letter-spacing:0
+whenever you use text-align:justify.
+
+
+Nulla felis erat, imperdiet eu, ullamcorper non, nonummy quis, elit. Suspendisse potenti. Ut a eros at ligula vehicula pretium. Maecenas feugiat pede vel risus. Nulla et lectus. Letter spacing set at 0.2em. Fusce eleifend neque sit amet erat. Integer consectetuer nulla non orci. Morbi feugiat pulvinar dolor. Cras odio. Donec mattis, nisi id euismod auctor, neque metus pellentesque risus, at eleifend lacus sapien et risus. Word spacing set at 1em. Phasellus metus. Phasellus feugiat, lectus ac aliquam molestie, leo lacus tincidunt turpis, vel aliquam quam odio et sapien. Mauris ante pede, auctor ac, suscipit quis, malesuada sed, nulla. Integer sit amet odio sit amet lectus luctus euismod. Donec et nulla. Sed quis orci.
+
+
+
+
+Colours
+
+Whenever a colour can be specified in a style, additional formats are now supported: rgb(), rgba(), hsl(), hsla(), cmyk(), cmyka(), or spot().
+
+Spot colours need to be defined at the start of the script using e.g. $mpdf->AddSpotColor(\'PANTONE 534 EC\',85,65,47,9);
+
+The four values define the CMYK values used when the spot colour is not available. A tint % can be specified when using the spot colour in the document.
+
+
+background-color: rgba(150,150,255, 0.5); color: rgb(0,150,150);
+background-color: rgba(60%,60%,100%, 0.5); color: rgb(0,60%,60%);
+background-color: hsla(180,30%,25%, 0.5); color: hsl(360,100%,50%);
+background-color: cmyka(85,65,0,30, 0.3); color: spot(PANTONE 300 EC,80%);
+
+
+
+
+@page media
+
+When using @page to create a print publication with page-size less than sheet-size, the bleed margin is now configurable.
+Backgrounds/gradients/images now use the bleed box as their "container box", rather than the whole page. (See this document as an example.)
+
+Crop- and cross-marks can now both be used together, and are more configurable.
+Also, background-image-opacity and background-image-resize have been extended to work with @page CSS.
+
+The following values can be set in the configuration file, config.php:
+$this->bleedMargin
+$this->crossMarkMargin
+$this->cropMarkMargin
+$this->cropMarkLength
+$this->nonPrintMargin
+
+
+
+
+Colorspace and colour conversion
+
+PDF files can contain objects using different colorSpaces e.g. Grayscale, RGB and CMYK. By default,
+mPDF creates PDF files using the colours as they are specified: font colour may be set (e.g. #880000) as an RGB colour, and the
+file may contain JPG images in RGB or CMYK format.
+
+In some circumstances, you may wish to create a PDF file with restricted colorSpaces e.g. printers will often want files
+which contain only CMYK, spot colours, or grayscale, but not RGB.
+
+Additional methods for defining colours can be used (see above), but alternatively you can set mPDF to restrict the colorSpace by setting
+the value for $mpdf->restrictColorSpace:
+
+1 - allow GRAYSCALE only [converts CMYK/RGB->gray]
+
+2 - allow RGB / SPOT COLORS / Grayscale [converts CMYK->RGB]
+
+3 - allow CMYK / SPOT COLORS / Grayscale [converts RGB->CMYK]
+
+This will attempt to convert every colour value used in the document to the permitted colorSpace(s). Almost everything including images
+will be converted (except BMP images), and the conversion of images may take significant time.
+
+This example file is set to (3) CMYK; compare the appearance of the Tux penguin in this file and in the previous example file (RGB).
+
+
+
+
+
+PDF/A and PDF/X files
+
+mPDF can produce files which (attempt to) meet the PDF/A and PDF/X specifications. In addition to restricted colorSpace,
+PDF/A and /X files cannot contain images or colour values with "transparency".
+
+Please note that full compliance with the PDF/A or /X specification is not guaranteed.
+
+
+
+
+RTL (right-to-left) text
+
+Handling of RTL (right-to-left) languages has been significantly rewritten, and is likely to cause
+changes to the resulting files if you have previously been using mPDF. The changes have made mPDF
+act more like a browser, respecting the HTML/CSS rules.
+Changes include:
+
+- the document now has a baseline direction; this determines the
+
+ - behaviour of blocks for which text-align has not been specifically set
+ - layout of mirrored page-margins, columns, ToC and Indexes, headers / footers
+ - base direction can be set by any of:
+
+ - $mpdf->SetDirectionality(\'rtl\');
+ - <html dir="rtl" or style="direction: rtl;">
+ - <body dir="rtl" or style="direction: rtl;">
+
+ - base direction is an inherited CSS property, so will affect all content, unless...
+
+- direction can be set for all HTML block elements e.g. <DIV><P><TABLE><UL> etc using
+
+ - CSS property <style="direction: rtl;">
+ - direction can only be set on the top-level element of nested lists
+ - direction can only be set on <TABLE>, NOT on THEAD, TBODY, TD etc.
+ - nested tables CAN have different directions
+
+- NOTE that block/table margins/paddings are NOT reversed by direction
+- language (either CSS "lang", using Autofont, or through initial set-up e.g. $mpdf = new mPDF(\'ar\') )
+ no longer affects direction in any way.
+ NB config_cp.php has been changed as a result; any values of "dir" set here are now ineffective
+- default text-align is now as per CSS spec: "a nameless value which is dependent on direction"
+ NB default text-align removed in default stylesheet in config.php
+- once text-align is specified, it is respected and inherited
+ NB mPDF <5.1 reversed the text-align property for all blocks when RTL set.
+- the configurable value $rtlcss is depracated, as it is no longer required
+- improved algorithm for dtermining text direction
+
+ - english word blocks are handled in text reversal as one block i.e. dir="rtl"
+ [arabic text] this will not be reversed [arabic text]
+ - arabic numerals 0-9 handled correctly
+
+
+Although the control of direction for block elements is now more configurable, the control of
+text direction (RTL arabic characters) remains fully automatic and unconfigurable.
+<BDO> etc has no effect. Enclosing text in silent tags can sometimes help e.g.:
+ content<span>[arabic text]</span>content
+
+
+
+
+
+List styles
+Additional numerical list-styles are supported. All of these (except Tamil) are consistent with the draft CSS3 specification:
+list-style: arabic-indic | bengali | devanagari | gujarati | gurmukhi | kannada | malayalam | oriya | persian | telugu | thai | urdu | tamil
+
+
+
+
+
+
+
+
+- Arabic
+
+- One
+- Two
+- Three
+- Four
+- Five
+- Six
+
+
+- Persian
+
+- One
+- Two
+- Three
+- Four
+- Five
+- Six
+
+
+- Urdu
+
+- One
+- Two
+- Three
+- Four
+- Five
+- Six
+
+
+
+
+
+
+
+- Bengali
+
+- One
+- Two
+- Three
+- Four
+- Five
+
+
+- Devanagari
+
+- One
+- Two
+- Three
+- Four
+- Five
+
+
+- Gujarati
+
+- One
+- Two
+- Three
+- Four
+- Five
+
+
+- Gurmukhi
+
+- One
+- Two
+- Three
+- Four
+- Five
+
+
+- Tamil
+
+- One
+- Two
+- Three
+- Four
+- Five
+
+
+
+
+
+';
+
+//==============================================================
+
+
+$mpdf->WriteHTML($html);
+
+//==============================================================
+//==============================================================
+// OUTPUT
+$mpdf->Output(); exit;
+
+
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example56_new_mPDF_v5-1_features_grayscale.php b/mpdf/examples/example56_new_mPDF_v5-1_features_grayscale.php
new file mode 100644
index 0000000..00b64f4
--- /dev/null
+++ b/mpdf/examples/example56_new_mPDF_v5-1_features_grayscale.php
@@ -0,0 +1,483 @@
+restrictColorSpace = 1; // forces to grayscale
+//==============================================================
+$html = '
+
+
+
+
+
+mPDF
+New features in mPDF Version 5.1
+
+
+ This is a copy of Example 54, but all object colours are converted to grayscale using simply:
+ $mpdf->restrictColorSpace = 1;
+
+
+
+
+- CSS background (images, colours or gradients) on <TR> and <TABLE>
+- CSS border on <TR> (only in border-collapsed mode)
+- support for Mozilla and CSS3 gradient syntax:
+
+- -moz-linear-gradient, linear-gradient
+- -moz-radial-gradient, radial-gradient
+- -moz-repeating-linear-gradient, linear-repeating-gradient
+- -moz-repeating-radial-gradient, radial-repeating-gradient
+
+
+- expanded support for gradients (including in SVG images):
+
+- multiple colour \'stops\'
+- opacity (transparency)
+- angle and/or position can be specified
+
+
+- etc...
+
+
+
+Tables: borders, background images & gradients
+
+Background images or gradients can be set on whole tables or table rows (as well as individual table cells)
+
+
+| Row 1 | This is data | This is data |
+| This row has | a background-image | of the bayeux tapestry |
+Row 3 | This is long data | This is data |
+| This row has | a gradient set | which spans all 3 cells |
+| Row 5 | Also data | Also data |
+
+
+
+Border can be set on table rows (only when border-collapse is set to collapse)
+
+
+| Row 1 | This is data | This is data |
+| Row 2 | This is data This is data This is data This is data | Also data |
+Row 3 | This is long data | This is data |
+
+
+
+
+
+
+
+
+Mozilla and CSS3 gradient syntax
+
+
+Linear gradients
+ Angle set AND points e.g. -moz-linear-gradient(34% 84% 30deg, red, orange, yellow...
+
+
+| top right 210 degrees |
+ |
+ |
+
+
+| 30% 80% 60 degrees |
+ |
+ |
+
+
+| 10px 40px 325 degrees |
+ |
+ |
+
+
+| bottom left 135deg |
+ |
+ |
+
+
+
+
+ Points set only e.g. -moz-linear-gradient(bottom left, red, orange, yellow...
+
+
+
+| bottom right |
+ |
+ |
+
+
+| top |
+ |
+ |
+
+
+| 10px 40px |
+ |
+ |
+
+
+| 30% 10% |
+ |
+ |
+
+
+
+
+
+ Angle set but no points e.g. -moz-linear-gradient(30deg, red, orange, yellow...
+
+
+
+| 90 degrees |
+ |
+ |
+
+
+| 120 degrees |
+ |
+ |
+
+
+| 180 degrees |
+ |
+ |
+
+
+| 210 degrees |
+ |
+ |
+
+
+
+
+
+
+ Linear and radial gradients are not specified in the CSS2 specification. The CSS3 draft specification gives a way of outputting gradients, but currently this is not supported by any browser.
+ Mozilla (Firefox) has developed its own way of producing gradients, which approximates to the CSS3 draft specification:
+
+- -moz-linear-gradient
+- -moz-repeating-linear-gradient
+- -moz-radial-gradient and
+- -moz-repeating-radial-gradient
+
+ WebKit (Safari, Chrome etc.) have a separate way of defining gradients using -webkit-gradient
+ Microsoft (IE) does not support any such method of specifying gradients, but does have a function filter: progid:DXImageTransform.Microsoft.gradient()
+ When writing HTML for cross-browser compatibility, it is common to see something like this in a stylesheet:
+
+background: #999999; /* for non-css3 browsers */
+filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#cccccc\', endColorstr=\'#000000\'); /* for IE */
+background: -webkit-gradient(linear, left top, left bottom, from(#cccccc), to(#000000)); /* for webkit browsers */
+background: -moz-linear-gradient(top, #cccccc, #000000); /* for firefox 3.6+ */
+
+
+
+
+ mPDF versions <= 5.0 supported a custom style property background-gradient which accepted both linear and radial gradients. These continue to be supported (and both old and new forms can be used together); note the differences:
+
+- mPDF background-gradients are output underneath background-images, and both can be specified; whereas the new CSS3/Mozilla-type gradients are defined as a type of background-image
+- CSS3/Mozilla gradients support multiple colour-stops, opacity, repeating-gradients, and a greater number of options for defining the gradient axis (linear gradients) or shape and extent (radial gradients)
+
+
+ mPDF will attempt to parse a CSS stylesheet written for cross-browser compatibility:
+
+- parse and support -moz type gradients
+- parse and support CSS3 gradient syntax
+- ignore -webkit syntax gradients
+
+
+
+ More details can be found at:
+
+
+
+
+
+Repeating gradients
+
+
+background: repeating-linear-gradient(red, blue 20px, red 40px);
+
+background: -moz-repeating-linear-gradient(top left -45deg, red, red 10px, rgba(255,255,255,0) 10px, rgba(255,255,255,0) 20px);
+
+
+
+
+
+
+
+
+
+
+background: repeating-radial-gradient(20px 30px, circle farthest-side, red, yellow, green 10px, yellow 15px, red 20px);
+
+background: repeating-radial-gradient(red, blue 20px, red 40px);
+
+
+
+
+
+
+
+
+
+
+Radial gradients
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Gradient Image mask
+
+Gradients (linear or radial) can also be used to produce \'masks\' for images. The same syntax is used as for background gradients (e.g. -moz-linear-gradient) but is set using a custom mPDF style: gradient-mask. The rgba() method for defining colours is used: colours are ignored, but the opacity value is used to mask the image.
+
+<img src="windmill.jpg" style="gradient-mask: -moz-radial-gradient(center, ellipse closest-side, rgba(255,255,255,1), rgba(255,255,255,1) 30%, rgba(255,255,255,0) 90%, rgba(255,255,255,0));" />
+
<img src="windmill.jpg" style="gradient-mask: -moz-radial-gradient(center, ellipse closest-side, rgba(255,255,255,1), rgba(255,255,255,1) 70%, rgba(255,255,255,0) 90%, rgba(255,255,255,0));" />
+
<img src="windmill.jpg" style="gradient-mask: -moz-linear-gradient(left, rgba(0,0,0,0) , rgba(0,0,0,1) 50% , rgba(0,0,0,0) 100%);" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Image orientation
+
+Images can be rotated using a custom mPDF HTML attribute: rotate. mPDF now also supports the draft CSS3 property of image-orientation. Rotation can be expressed in degrees, radians or grad units; it is corrected if necessary to an orthogonal rotation i.e. 90, 180 or 270 degrees. NB This does not work on background-images.
+<img src="tiger2.png" style="image-orientation: -90deg" width="100" />
+
+<img src="tiger2.png" style="image-orientation: 3.14159rad" width="100" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Image resolution
+
+
+Image files (which do not have an output width or height specified) are displayed in mPDF at the default resolution set by the variable $mpdf->img_dpi. This can be overridden using the draft CSS3 property \'image-resolution\', which can be applied to <IMG> or background-images.
+
+The next 3 image files are identical (300px x 300px) but they have been saved with a different specified resolution: the first at 96dpi, the second at 300dpi.
+
+NB When used in combination with \'from-image\', a specified resolution is only used if the image does not have an intrinsic resolution. Only JPG, PNG and BMP files store a specified DPI resolution in the file.
+
+<img src="tiger300px300dpi.png" style="image-resolution: from-image;" />
+ <img src="tiger300px300dpi.png" style="image-resolution: 150dpi;" />
+ <img src="tiger300px96dpi.png" style="image-resolution: from-image;" />
+
+
+
+
+
+
+
+
+
+
+Image resolution can also be applied to a background-image. This can be used as an alternative to the custom mPDF style property - \'background-image-resize\'
+
+<div height="300px" width="300px" style="background: #FFCCEE url(tiger300px96dpi.png); background-image-resolution: from-image; border: 0.2mm solid black;">
+Hallo world
+
+
+
+
+<div height="300px" width="300px" style="background-image: url(tiger300px300dpi.png); background-image-resolution: from-image; border: 0.2mm solid black;">
+
+
+
+
+
+
+
+
+
+
+
+
+Mixed effects
+
+
+
+
+
+
+
+
+Hallo World
+
+
+Hallo World
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+';
+
+//==============================================================
+$mpdf->WriteHTML($html);
+
+$mpdf->Output(); exit;
+
+
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example57_new_mPDF_v5-3_active_forms.php b/mpdf/examples/example57_new_mPDF_v5-3_active_forms.php
new file mode 100644
index 0000000..5371f2d
--- /dev/null
+++ b/mpdf/examples/example57_new_mPDF_v5-3_active_forms.php
@@ -0,0 +1,224 @@
+
+textarea {
+}
+input {
+}
+select {
+ font-family: Arial
+}
+
+
+Active Forms
+
+
+';
+
+
+
+//==============================================================
+$mpdf->useActiveForms = true;
+$mpdf->formUseZapD = false;
+
+/*
+// Try playing around with these (these are also in config.php)
+$mpdf->formUseZapD = false;
+$mpdf->formSubmitNoValueFields = true;
+
+$mpdf->formExportType = 'xfdf'; // 'html' or 'xfdf'
+$mpdf->formSelectDefaultOption = true; // for Select drop down box; if no option is explicitly maked as selected,
+ // this determines whether to select 1st option (as per browser)
+ // - affects whether "required" attribute is relevant
+$mpdf->form_border_color = '0.0 0.820 0.0';
+$mpdf->form_background_color = '0.941 0.941 0.941';
+$mpdf->form_border_width = '1';
+$mpdf->form_border_style = 'S';
+
+$mpdf->form_radio_color = '0.0 0.820 0.0';
+$mpdf->form_radio_background_color = '0.941 0.5 0.5';
+
+$mpdf->form_button_border_color = '0.0 0.820 0.0';
+$mpdf->form_button_background_color = '0.941 0.941 0.941';
+$mpdf->form_button_border_width = '1';
+$mpdf->form_button_border_style = 'S';
+*/
+
+$mpdf->WriteHTML($html);
+
+//==============================================================
+// JAVASCRIPT FOR WHOLE DOCUMENT
+$mpdf->SetJS('
+var dialogTitle = "Enter details";
+var defaultAnswer = "";
+var reply = app.response("This is javascript set to run when the document opens. Enter value for first field", dialogTitle, defaultAnswer);
+if (reply != null) {
+this.getField("inputfield").value = reply;
+}
+');
+//==============================================================
+// OUTPUT
+$mpdf->Output(); exit;
+
+
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example58_new_mPDF_v5-4_features.php b/mpdf/examples/example58_new_mPDF_v5-4_features.php
new file mode 100644
index 0000000..d76cfb3
--- /dev/null
+++ b/mpdf/examples/example58_new_mPDF_v5-4_features.php
@@ -0,0 +1,535 @@
+
+.gradient {
+ border:0.1mm solid #220044;
+ background-color: #f0f2ff;
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+ box-shadow: 0.3em 0.3em #888888;
+}
+.rounded {
+ border:0.1mm solid #220044;
+ background-color: #f0f2ff;
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+ border-radius: 2mm;
+ background-clip: border-box;
+}
+h4 {
+ font-weight: bold;
+ margin-top: 1em;
+ margin-bottom: 0.3em;
+ margin-top: 0;
+}
+div.text {
+ padding:0.8em;
+ margin-bottom: 0.7em;
+}
+p { margin: 0.25em 0; }
+.code {
+ font-family: monospace;
+ font-size: 9pt;
+ background-color: #d5d5d5;
+ margin: 1em 1cm;
+ padding: 0 0.3cm;
+ border:0.2mm solid #000088;
+ box-shadow: 0.3em 0.3em #888888;
+}
+table {
+ overflow: visible;
+ empty-cells: hide;
+ border:1px solid #000000;
+ font-family: sans-serif;
+ font-size: 10pt;
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+}
+td, th {
+ border:1px solid #000000;
+ text-align: left;
+ font-weight: normal;
+}
+td.markedcell {
+ text-decoration: line-through;
+ color: #CC0000;
+}
+td.underlinedcell {
+ text-decoration: underline;
+ color: #CC0000;
+}
+td.rotatedcell {
+ text-decoration: line-through;
+ color: #CC0000;
+ text-rotate: 45;
+}
+td.cost { text-align: right; }
+caption.tablecaption {
+ font-family: sans-serif;
+ font-weight: bold;
+ border: none;
+ caption-side: top;
+ margin-bottom: 0;
+ text-align: center;
+}
+u.doubleu {
+ text-decoration: none;
+ border-bottom: 3px double #000088;
+}
+a.reddashed {
+ text-decoration: none;
+ border: 1px dashed #880000;
+}
+.shadowtitle {
+ height: 8mm;
+ background-color: #EEDDFF;
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+ padding: 0.8em;
+ padding-left: 3em;
+ font-family:sans;
+ font-size: 26pt;
+ font-weight: bold;
+ border: 0.2mm solid white;
+ border-radius: 0.2em;
+ box-shadow: 0 0 2em 0.5em rgba(0,0,255,0.9);
+ color: #AAAACC;
+ text-shadow: 0.03em 0.03em #666, 0.05em 0.05em rgba(127,127,127,0.5), -0.015em -0.015em white;
+}
+h3 {
+ margin: 3em 0 2em -15mm;
+ background-color: #EEDDFF;
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+ padding: 0.5em;
+ padding-left: 3em;
+ width: 50%;
+ font-family:sans;
+ font-size: 16pt;
+ font-weight: bold;
+ border-left: none;
+ border-radius: 0 2em 2em 0;
+ box-shadow: 0 0 2em 0.5em rgba(255,0,0,1);
+ text-shadow: 0.05em 0.04em rgba(127,127,127,0.5);
+}
+.css {
+ font-family: arial;
+ font-style: italic;
+ color: #000088;
+}
+table.zebra tbody tr:nth-child(2n+1) td { background-color: rgba(255,255,127,0.6); }
+table.zebra tbody tr:nth-child(2n+1) th { background-color: rgba(255,255,127,0.6); }
+table.zebra thead tr { background-color: #FFBBFF; }
+table.zebra tfoot tr { background-color: #BBFFFF; }
+
+
+
+
+
+
+New Features in mPDF v5.4
+
+
+Bookmark styles
+
+ Bookmarks can be styled by adding code as below to your script. You can define a colour (array of RGB) and/or a font-style (B, I, or BI) for each level (starting at 0). Results may depend on the PDF Reader you are using.
+
+$this->bookmarkStyles = array(
+ 0 => array(\'color\'=> array(0,64,128), \'style\'=>\'B\'),
+ 1 => array(\'color\'=> array(128,0,0), \'style\'=>\'\'),
+ 2 => array(\'color\'=> array(0,128,0), \'style\'=>\'I\'),
+);
+
+
+
+Embedded SVG code
+SVG Images can be embedded in your HTML code. This is formally part of the XHTML specification and is supported by IE9+ and most other browsers.
+
+
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 200 200" width="200" height="200">
+ <circle cx="100" cy="50" r="40" stroke="black" stroke-width="1" fill="red" />
+ <circle cx="130" cy="50" r="40" stroke="black" stroke-width="1" fill="blue" />
+</svg>
+
+
+
+Improved CSS support
+
+ border-radius is now supported on fixed/absolute-positioned block elements.
+ visibility can be set on any block-style element e.g. DIV,P or images IMG as: visible|hidden|printonly|screenonly
+ background-color now supports rgba() and cmyka() alpha transparency formats in tables.
+ Color, underline and strike-through are now supported in table cells, including with rotated text (see example below of spread table)
+ page-break-after: left|right|always is supported on all block-style elements and tables
+ text-transform: capitalize|uppercase|lowercase is supported in table cells
+
+
+
+
+ Zebra stripes in Tables
+
+ :nth-child() selector can be used in tables (on TR, TD or TH) to stripe rows or columns. Both the an+b and odd/even forms are supported e.g.
+
+
+tr:nth-child(2n+1) { background-color: rgba(255,255,127,0.6); } or
+tr:nth-child(odd) { background-color: rgba(255,255,127,0.6); }
+
+
+
+
+
+| Row 1 |
+This is data |
+167.00 |
+
+
+| Row 2 |
+
+ This is data p
+ |
+
+ 444.53
+ |
+
+
+|
+ Row 3
+ |
+
+ This is long data
+ |
+14.00 |
+
+
+|
+ Row 4
+ |
+This is data |
+
+ 0.88
+ |
+
+
+| Row 5 |
+Also data |
+144.00 |
+
+
+| Row 6 |
+Also data |
+8089.00 |
+
+
+
+ Note: mPDF does NOT correctly apply specificity to all CSS. The following stylesheet:
+
+table.zebra tbody tr:nth-child(2n+1) td { background-color: yellow; }
+table.zebra tbody td:nth-child(odd) { background-color: blue; }
+
+ should make every odd row yellow, and every odd column blue, but with the row/yellow overriding the column/blue.
+In mPDF the td:nth-child(odd) trumps the plain td, so the column colour wins out. You can force the effect you want by using:
+
+table.zebra tbody tr:nth-child(2n+1) td:nth-child(1n+0) { background-color: yellow; }
+
+ The :nth-child(1n+0) selector just selects every td cell.
+
+
+
+
+
+
+ border can now be defined on in-line elements eg SPAN
+
+ Note: Remember that in mPDF, inside table cells, properties set on block elements are set when possible as in-line properties - so a P element inside a table with border set, will appear with a border around the text line as though it had been set on SPAN
+
+
+
+
+
+
+ Shadows
+ box-shadow can be defined on any block-level element (P, DIV etc). It follows the CSS3 recommendation, but inset is not supported.
+ text-shadow can be defined on any element. It follows the CSS3 recommendation, but blur is not supported.
+
+<span style="text-shadow: 0.03em 0.03em #666, -0.015em -0.015em white;">
+<div style="box-shadow: 0.3em 0.3em #888888;">
+
+
+
+
+Other Enhancements
+
+Column Totals (Tables)
+{colsum} placed in the footer of a table will automatically display the sum of that column. If the table breaks across more than one page, the sum of the values on that page will be displayed. A number following the colsum e.g. {colsum2} will force that number of decimal places to be displayed.
+
+
+Table caption goes here
+
+
+| Header Row |
+Header Row |
+Header Row |
+
+
+
+
+ |
+Column total: (using colsum2 in {}) |
+{colsum2} |
+
+
+
+
+| Row 1 |
+This is data |
+167.00 |
+
+
+| Row 2 |
+
+ This is data p
+ |
+
+ 444.53
+ |
+
+
+|
+ Row 3
+ |
+
+ This is long data
+ |
+14.00 |
+
+
+|
+ Row 4
+ |
+This is data |
+
+ 0.88
+ |
+
+
+| Row 5 |
+Also data |
+144.00 |
+
+
+| Row 6 |
+Also data |
+8089.00 |
+
+
+| Row 7 |
+Also data |
+3.00 |
+
+
+| Row 8 |
+Also data |
+23.00 |
+
+
+
+
+Table caption
+The caption element for tables is partially supported (see example above).
+
+<caption align="top|bottom" style="caption-side: top|bottom">
+
+
+- The caption must come immediately after <table>.
+- The CSS caption-side or HTML align attribute of top|bottom supported
+- Left or right placement are not supported.
+- The caption is handled as a separate block element brought outside the table, so:
+
+ - CSS will not cascade correctly from the table
+ - the width of the caption block is that of page or of the block element containing the table
+ - text alignment will be to the page-width not the table width
+ - if table page-break-after: always, the caption will follow the pagebreak
+
+
+
+
+Core fonts in non-core font document
+
+Core fonts, which do not need to be embedded in a PDF, can now be included in a document which uses non-core fonts. The pseudo font-family names: chelvetica, ctimes and ccourier should be used.
+
+<div style="font-family: chelvetica">
+
+NB You could force mPDF to always use core fonts when Arial/Helvetica/Courier are specified, by editing $this->fonttrans in config_fonts.php:
+
+$this->fonttrans = array(
+ \'arial\' => \'chelvetica\',
+ \'helvetica\' => \'chelvetica\',
+ \'timesnewroman\' => \'ctimes\',
+ \'times\' => \'ctimes\',
+ \'couriernew\' => \'ccourier\',
+ \'courier\' => \'ccourier\',
+...
+
+
+
+Javascript in Forms
+
+Javascript used in (active) forms has been altered to reflect the Adobe Acrobat specification for Javascript in PDF documents.
+textarea and input (text-types) now accept javascript as: onKeystroke, onValidate, onCalculate and onFormat. onChange is depracated but is not ignored; it works as though for onCalculate. (PS Select still accepts onChange)
+
+
+
+
+
+
+Overlapping Rows in Tables
+ Support for overlapping rowspans in tables has been improved (although probably not foolproof!)
+
+
+
+
+
+
+Circular Text
+Circular Text can be included in a PDF document as a custom HTML tag (or a function)
+
+- top-text and/or bottom-text can be specified
+- Radius (r) and font-size (using CSS) are user-defined
+- Width and height are calculated from radius and font-size
+- Other CSS styles supported on Circular Text: border, margin, padding, color, background-color, font-family, font-size, font-weight, font-style, display, visibility, and opacity
+- space-width should be specified as an integer defining the letter-spacing as a percentage of normal (default 120)
+- char-width should be specified as an integer defining the width of each character as a percentage of normal (default 100)
+- Circular Text is displayed as though an in-line element
+
+NB If $mpdf->useKerning is true then automatic kerning will be used on Circular Text.
+
+
+<textcircle r="30mm" top-text="Circular Text Circular Text" style="color: blue; font-size: 34pt; font-style: italic" />
+<textcircle r="30mm" space-width="120" char-width="150" top-text="• Circular Text •" bottom-text="Circular Text" style="background-color: #FFAAAA; border:1px solid red; padding: 0.3em; margin: 0.3em; color: #000000; font-size: 21pt; font-weight:bold; font-family: Arial" />
+
+
+
+
+
+
+
+
+
+
+Spread tables
+
+Setting the CSS property "overflow: visible" on a table now has the effect of cancelling resizing, and allowing tables to split columns across multiple pages.
+The maximum width for a column (or group of columns set by colspan) is the page width. It is recommended to specify absolute values of width on each column (not percentages).
+
+
+
+
+
+
+
+
+
+Periodic Table (table caption)
+
+| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
+
+
+| H | | | | | | | | | | | | |
+ | | | | He |
+
+
+| Li | Be | | | | | | | | | | |
+B | C | N | O | F | Ne |
+
+
+| Na | Mg | | | | | | | | | | |
+Al | Si | P | S | Cl | Ar |
+
+
+| K | Ca | Sc | Ti | V | Cr | Mn | Fe | Co | Ni |
+Cu | Zn | Ga | Ge | As | Se | Br | Kr |
+
+
+| Rb | Sr | Y | Zr | Nb | Mo | Tc | Ru | Rh |
+Pd | Ag | Cd | In | Sn | Sb | Te | I | Xe |
+
+
+| Cs | Ba | Lu | Hf | Ta | W | Re | Os | Ir | Pt |
+Au | Hg | Tl | Pb | Bi | Po | At | Rn |
+
+
+| Fr | Ra | | | | | | | | | | | |
+ | | | | |
+
+
+
+
+
+
+ Limitations of Spread tables
+Spread tables cannot be used with: keep-headings-with-table ($mpdf->use_kwt), table rotate, table page-break-inside:avoid, columns,
+CJK (chinese-japanese-korean) or RTL (right-to-left) languages.
+They will also cause problems with $mpdf->forcePortraitHeaders or $mpdf->forcePortraitMargins.
+Warning: If a table row is too tall to fit on a page, mPDF will crash with an error message.
+If the width settings within the table cause conflicts, it will override some of these settings.
+
+
+
+
+';
+
+//==============================================================
+$mpdf->useActiveForms = true;
+
+$mpdf->bookmarkStyles = array(
+ 0 => array('color'=> array(0,64,128), 'style'=>'B'),
+ 1 => array('color'=> array(128,0,0), 'style'=>''),
+ 2 => array('color'=> array(0,128,0), 'style'=>'I'),
+);
+
+$mpdf->useKerning=true; // set this to improve appearance of Circular text
+ // must be set before the font is first loaded
+
+$mpdf->WriteHTML($html);
+
+// JAVASCRIPT FOR WHOLE DOCUMENT
+$mpdf->SetJS('
+function TwoPages() {
+ this.layout="TwoColumnRight";
+ this.zoomType = zoomtype.fitW;
+}
+function OnePage() {
+ this.layout="SinglePage";
+ this.zoom = 100;
+}
+');
+
+// OUTPUT
+$mpdf->Output(); exit;
+
+
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example59_new_mPDF_v5-6_features.php b/mpdf/examples/example59_new_mPDF_v5-6_features.php
new file mode 100644
index 0000000..4284c4f
--- /dev/null
+++ b/mpdf/examples/example59_new_mPDF_v5-6_features.php
@@ -0,0 +1,296 @@
+
+.gradient {
+ border:0.1mm solid #220044;
+ background-color: #f0f2ff;
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+ box-shadow: 0.3em 0.3em #888888;
+}
+.rounded {
+ border:0.1mm solid #220044;
+ background-color: #f0f2ff;
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+ border-radius: 2mm;
+ background-clip: border-box;
+}
+h4 {
+ font-weight: bold;
+ margin-top: 1em;
+ margin-bottom: 0.3em;
+ margin-top: 0;
+}
+div.text {
+ padding:0.8em;
+ margin-bottom: 0.7em;
+}
+p { margin: 0.25em 0; }
+.code {
+ font-family: monospace;
+ font-size: 9pt;
+ background-color: #d5d5d5;
+ margin: 1em 1cm;
+ padding: 0 0.3cm;
+ border:0.2mm solid #000088;
+ box-shadow: 0.3em 0.3em #888888;
+}
+table {
+ border:1px solid #000000;
+ font-family: sans-serif;
+ font-size: 10pt;
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+}
+td, th {
+ border:1px solid #000000;
+ text-align: left;
+ font-weight: normal;
+}
+.shadowtitle {
+ height: 8mm;
+ background-color: #EEDDFF;
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+ padding: 0.8em;
+ padding-left: 3em;
+ font-family:sans;
+ font-size: 26pt;
+ font-weight: bold;
+ border: 0.2mm solid white;
+ border-radius: 0.2em;
+ box-shadow: 0 0 2em 0.5em rgba(0,0,255,0.9);
+ color: #AAAACC;
+ text-shadow: 0.03em 0.03em #666, 0.05em 0.05em rgba(127,127,127,0.5), -0.015em -0.015em white;
+}
+h3 {
+ margin: 3em 0 2em -15mm;
+ background-color: #EEDDFF;
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+ padding: 0.5em;
+ padding-left: 3em;
+ width: 50%;
+ font-family:sans;
+ font-size: 16pt;
+ font-weight: bold;
+ border-left: none;
+ border-radius: 0 2em 2em 0;
+ box-shadow: 0 0 2em 0.5em rgba(255,0,0,1);
+ text-shadow: 0.05em 0.04em rgba(127,127,127,0.5);
+}
+.css {
+ font-family: arial;
+ font-style: italic;
+ color: #000088;
+}
+table.pop {
+ border-collapse: collapse;
+}
+table.pop td {
+ font-family: arial;
+ font-size: 10px;
+ border: 1px solid #888888;
+}
+meter.pop {
+ margin: 3px;
+}
+fieldset { border: 1px solid #000000; border-radius: 5px; padding: 10px; }
+div.folder {
+ background: url(data:image/gif;base64,R0lGODlhEAAOALMAAOazToeHh0tLS/7LZv/0jvb29t/f3//Ub//ge8WSLf/rhf/3kdbW1mxsbP//mf///yH5BAAAAAAALAAAAAAQAA4AAARe8L1Ekyky67QZ1hLnjM5UUde0ECwLJoExKcppV0aCcGCmTIHEIUEqjgaORCMxIC6e0CcguWw6aFjsVMkkIr7g77ZKPJjPZqIyd7sJAgVGoEGv2xsBxqNgYPj/gAwXEQA7) no-repeat 4px center;
+ padding: 5px 0 5px 25px;
+ border: 1px solid #000000;
+}
+
+
+
+
+New Features in mPDF v5.6
+
+HTML5 tags
+
+ New tags introduced in HTML5 now have basic support in mPDF, and will thus support CSS style references.
+ The following are treated as block elements similar to <div>:
+ <article> <aside> <details> <figure> <figcaption> <footer> <header> <hgroup> <nav> <section> <summary>
+ The following are treated as in-line elements:
+ <time> <mark>
+ Mark is set by default to highlight in yellow in config.php using $defaultCSS e.g. mark
+ Progress and meter are discussed below:
+
+
+<progress>
+
+ Progress: accepts the attributes value and max. A progress element without a value is called an indeterminate progress bar.
+Text between the opening and closing tags is not displayed.
+ CSS styles properties can be applied: display, visibility, margin, padding, border, vertical-align, width, height and opacity.
+HTML attributes width and height are supported, although not officially part of the spec.
+ Example:
+ <progress value="5" max="10">50%</progress>
+
+
+ -
+
+
+
+ -
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+
+<meter>
+
+ Meter: accepts the attributes min, max, value, optimum, low, and high.
+Text between the opening and closing tags is not displayed.
+ CSS styles properties can be applied: display, visibility, margin, padding, border, vertical-align, width, height and opacity.
+HTML attributes width and height are supported, although not officially part of the spec.
+ Example:
+ <meter value="5" max="10" min="1" low="2" high="8" optimum="5.6">5</meter>
+
+
+
+
+ -
+
+
+
+ -
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+
+
+ Custom appearances for <meter> and <progress>
+ Meter (and to a lesser extent progress) can be used with custom appearances e.g. by using optimum to display the average, and low/high to indicate 90th centiles
+
+ Custom appearances can be written by editing the script in classes/meter.php - Use a custom attribute of type="anyname" which is passed to the class as a variable e.g.
+ <meter type="2" value="612.7" optimum="580.4" min="517.0 " max="642.7" low="542" high="600">612.7</meter>
+
+
+
+
+
+
+Domain |
+Indicator |
+LHB number |
+LHB Indicator
+value
+ |
+Wales average
+ |
+Wales range |
+Comparison |
+
+
+
+Deaths |
+Death Rates per 100,000 population |
+3046 |
+612.7 |
+580.4 |
+517.0 - 642.7 |
+612.7 |
+
+
+
+Death Rates per 100,000 from cancer |
+789 |
+178.2 |
+172.7 |
+159.5 - 182.2 |
+178.2 |
+
+
+
+Death Rates per 100,000 from respiratory disease |
+505 |
+60.5 |
+72.11 |
+54.41 - 95.5 |
+60.5 |
+
+
+
+Death Rates per 100,000 from cardiovascular disease |
+913 |
+178.2 |
+165.0 |
+151.8 - 179.9 |
+160.2 |
+
+
+
+
+
+
+Fieldset and Legend
+
+
+
+CSS styles
+
+
+ min-height, min-width, max-height and max-width are now supported in CSS style sheets for <img> (only).
+ background: url(data:image/gif;base64,...) is now supported in CSS style sheets (gif, png and jpeg).
+
+
+This <div> has the folder icon set as an embedded image in the CSS
+div.folder {
+ background: url(data:image/gif;base64,R0lGODlhEAAOALMAAOazToeHh0tLS/7LZv/0jvb29t/f3//Ub//ge8WSLf/rhf/3kdbW1mxsbP//mf///yH5BAAAAAAALAAAAAAQAA4AAARe8L1Ekyky67QZ1hLnjM5UUde0ECwLJoExKcppV0aCcGCmTIHEIUEqjgaORCMxIC6e0CcguWw6aFjsVMkkIr7g77ZKPJjPZqIyd7sJAgVGoEGv2xsBxqNgYPj/gAwXEQA7) no-repeat 4px center;
+ padding: 5px 0 5px 25px;
+ border: 1px solid #000000;
+}
+
+
+
+';
+
+
+//==============================================================
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output(); exit;
+
+
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example60_new_mPDF_v5-7_features.php b/mpdf/examples/example60_new_mPDF_v5-7_features.php
new file mode 100644
index 0000000..afe5d0f
--- /dev/null
+++ b/mpdf/examples/example60_new_mPDF_v5-7_features.php
@@ -0,0 +1,584 @@
+
+.gradient {
+ border:0.1mm solid #220044;
+ background-color: #f0f2ff;
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+ box-shadow: 0.3em 0.3em #888888;
+}
+h4 {
+ font-weight: bold;
+ margin-top: 1em;
+ margin-bottom: 0.3em;
+ margin-top: 0;
+}
+div.text {
+ padding:0.8em;
+ margin-bottom: 0.7em;
+}
+p { margin: 0.25em 0; }
+p.code {
+ background-color: #d5d5d5;
+ margin: 1em 1cm;
+ padding: 0 0.3cm;
+ border:0.2mm solid #000088;
+ box-shadow: 0.3em 0.3em #888888;
+}
+.code {
+ font-family: monospace;
+ font-size: 9pt;
+}
+.shadowtitle {
+ height: 8mm;
+ background-color: #EEDDFF;
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+ padding: 0.8em;
+ padding-left: 3em;
+ font-family:sans;
+ font-size: 26pt;
+ font-weight: bold;
+ border: 0.2mm solid white;
+ border-radius: 0.2em;
+ box-shadow: 0 0 1em 0.5em rgba(0,0,255,0.5);
+ color: #AAAACC;
+ text-shadow: 0.03em 0.03em #666, 0.05em 0.05em rgba(127,127,127,0.5), -0.015em -0.015em white;
+}
+h3 {
+ margin: 3em 0 2em -15mm;
+ background-color: #EEDDFF;
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+ padding: 0.5em;
+ padding-left: 3em;
+ width: 50%;
+ font-family:sans;
+ font-size: 16pt;
+ font-weight: bold;
+ border-left: none;
+ border-radius: 0 2em 2em 0;
+ box-shadow: 0 0 2em 0.5em rgba(255,0,0,1);
+ text-shadow: 0.05em 0.04em rgba(127,127,127,0.5);
+}
+.css {
+ font-family: arial;
+ font-style: italic;
+ color: #000088;
+}
+
+.aBDP { text-align: "." center; }
+.arBDP { text-align: "\66B" center; }
+.middot { text-align: "\B7" center ; }
+
+p.menu {
+ text-align: justify;
+ padding-right: 4em;
+}
+dottab.menu {
+ outdent: 4em;
+}
+
+
+.outlined {
+ text-outline: 0.1mm 0.1mm #FF0000;
+ font-weight: bold;
+ font-size: 20pt;
+ color: #FFFFFF;
+}
+
+/* For background-clip and -origin */
+.divclip {
+ border: 10px dashed #000000;
+ border-radius: 3em;
+ padding: 20px;
+ background:yellow;
+ background-image: -moz-linear-gradient(top right 210deg, red, orange, yellow, green, blue, indigo, violet);
+ width: 300px;
+ height: 50px;
+ margin-bottom: 1em;
+ background-repeat: no-repeat ;
+ background-size: 100% 100%;
+}
+.divpic {
+ background:yellow;
+ background: yellow url("bayeux1.jpg") no-repeat scroll left top;
+ background-size: 100% 100%;
+}
+.div1 {
+ background-clip: content-box;
+ background-origin: content-box;
+}
+.div2 {
+ background-clip: padding-box;
+ background-origin: padding-box;
+}
+.div3 {
+ background-clip: border-box;
+ background-origin: border-box;
+}
+.div4 {
+ background-clip: content-box;
+ background-origin: border-box;
+}
+.div5 {
+ background-clip: border-box;
+ background-origin: content-box;
+}
+
+
+/* For Table of Contents */
+div.mpdf_toc {
+ font-family: sans-serif;
+ font-size: 11pt;
+}
+a.mpdf_toc_a {
+ text-decoration: none;
+ color: black;
+}
+div.mpdf_toc_level_0 { /* Whole line level 0 */
+ line-height: 1.5;
+ margin-left: 0;
+ padding-right: 2em; /* should match e.g 0 is default */
+}
+span.mpdf_toc_t_level_0 { /* Title level 0 - may be inside */
+ font-weight: bold;
+}
+span.mpdf_toc_p_level_0 { /* Page no. level 0 - may be inside */
+}
+div.mpdf_toc_level_1 { /* Whole line level 1 */
+ margin-left: 2em;
+ text-indent: -2em;
+ padding-right: 2em; /* should match 2em is default */
+}
+span.mpdf_toc_t_level_1 { /* Title level 1 */
+ font-style: italic;
+ font-weight: bold;
+}
+span.mpdf_toc_p_level_1 { /* Page no. level 1 - may be inside */
+}
+div.mpdf_toc_level_2 { /* Whole line level 2 */
+ margin-left: 4em;
+ text-indent: -2em;
+ padding-right: 2em; /* should match 2em is default */
+}
+span.mpdf_toc_t_level_2 { /* Title level 2 */
+}
+span.mpdf_toc_p_level_2 { /* Page no. level 2 - may be inside */
+}
+
+
+
+
+
+
+
+ToC Layout and styling
+
+ Table of Contents styling
+ When a Table of Contents is generated by mPDF using e.g. <tocpagebreak>, mPDF 5.7 will generate the ToC as HTML. This means that a CSS stylesheet can be used to format its appearance.
+
+
+
+ Example table of contents:
+
+
+
+
+ This will result in the following HTML code generated (internally):
+
+<div class="mpdf_toc" id="mpdf_toc_0">
+ <div class="mpdf_toc_level_0">
+ <a class="mpdf_toc_a" href="#__mpdfinternallink_1">
+ <span class="mpdf_toc_t_level_0">Section 1</span>
+ </a>
+ <dottab outdent="2em" />
+ <a class="mpdf_toc_a" href="#__mpdfinternallink_1">
+ <span class="mpdf_toc_p_level_0">5</span>
+ </a>
+ </div>
+ <div class="mpdf_toc_level_1">
+ <a class="mpdf_toc_a" href="#__mpdfinternallink_2">
+ <span class="mpdf_toc_t_level_1">Chapter 1</span>
+ </a>
+ <dottab outdent="2em" />
+ <a class="mpdf_toc_a" href="#__mpdfinternallink_2">
+ <span class="mpdf_toc_p_level_1">6</span>
+ </a>
+ </div>
+ <div class="mpdf_toc_level_2">
+ <a class="mpdf_toc_a" href="#__mpdfinternallink_3">
+ <span class="mpdf_toc_t_level_2">Topic 1</span>
+ </a>
+ <dottab outdent="2em" />
+ <a class="mpdf_toc_a" href="#__mpdfinternallink_3">
+ <span class="mpdf_toc_p_level_2">7</span>
+ </a>
+ </div>
+</div>
+
+
+ NB The id is "0" (mpdf_toc_0) for root/un-named ToC; otherwise it is lowercase of the name="" used for the ToC
+
+
+
+
+ Example Styling using CSS
+ The following CSSwill format the ToC as it appears in this document:
+
+/* For Table of Contents */
+div.mpdf_toc {
+ font-family: sans-serif;
+ font-size: 11pt;
+}
+a.mpdf_toc_a {
+ text-decoration: none;
+ color: black;
+}
+/* Whole line level 0 */
+div.mpdf_toc_level_0 {
+ line-height: 1.5;
+ margin-left: 0;
+ padding-right: 2em;
+}
+/* Title level 0 - may be inside <a> */
+span.mpdf_toc_t_level_0 {
+ font-weight: bold;
+}
+/* Page no. level 0 - may be inside <a> */
+span.mpdf_toc_p_level_0 { }
+/* Whole line level 1 */
+div.mpdf_toc_level_1 {
+ margin-left: 2em;
+ padding-right: 2em;
+}
+/* Title level 1 */
+span.mpdf_toc_t_level_1 {
+ font-style: italic;
+ font-weight: bold;
+}
+/* Page no. level 1 - may be inside <a> */
+span.mpdf_toc_p_level_1 { }
+/* Whole line level 2 */
+div.mpdf_toc_level_2 {
+ margin-left: 4em;
+ padding-right: 2em;
+}
+/* Title level 2 */
+span.mpdf_toc_t_level_2 { }
+/* Page no. level 2 - may be inside <a> */
+span.mpdf_toc_p_level_2 { }
+
+ NB padding-right should match <dottab> "outdent" (0 is default). See <dottab> for more details
+
+
+
+ The functions TOCpagebreakByArray() and TOCpagebreak() have a new final parameter, and HTML tags <TOC> and <TOCpagebreak> have a new attribute "tocoutdent". This should be blank or a valid CSS length e.g. "2em". See <dottab> for more details.
+
+
+
+
+
+
+Text-align on decimal point
+
+ Text inside a table column can be aligned on a decimal point (or any other character) by using either HTML attribute or CSS.
+ This example table uses the following CSS stylesheet:
+
+<style>
+.aBDP { text-align: "." center; }
+.arBDP { text-align: "\66B" center; }
+.middot { text-align: "\B7" center ; }
+</style>
+
+
+
+
+
+ | <TD> element | Column |
+ | align="left" | Left text |
+ | align="right" | Right text |
+ | align="center" | Center text |
+ | align="char" | 1000.0001 |
+ | align="char" char="," | 1000,0001 |
+ | align="char" char="·" | 1000·0001 |
+ | align="char" char="·" | 1000·0001 |
+ | style="text-align: \'.\' center" | 100.001 |
+ | style="text-align: \'.\' center" | DP aligned text |
+ | style="text-align: \',\' center" | 1.000,0001 |
+ | class="aBDP" | 10.01 |
+ | class="aBDP" | 1000 |
+ | class="aBDP" | 1000.0001 |
+ | class="middot" | 1 000·0001 |
+ | class="aBDP" | 1,000,000.00001 |
+ | class="aBDP" | 1.000000001 |
+ | class="aBDP" | 1.000.000.001 |
+ | class="arBDP" | ١٬٥٦٧٬٢٣٤٫٢٣٤٧ |
+ | class="aBDP" | (GBP) 1,000,000.00001 1,000,000.00001 (EUR) 1,000,000.00001 |
+
+
+
+
+
+
+
+
+
+Automatic ToC and Bookmarks
+
+ A Table of Contents and/or Bookmarks can be generated automatically from any of the heading tags H1 - H6. This example will generate ToC and bookmarks from all <h3> tags (top level) and <h4> tags (next level)
+
+ $mpdf->h2toc = array(\'H3\'=>0, \'H4\'=>1);
+ $mpdf->h2bookmarks = array(\'H3\'=>0, \'H4\'=>1);
+
+
+
+
+
+
+
+
+Improved line-breaking
+mPDF will now avoid line-breaks in the middle of words even between <tags>
+
+
+<b>Na<sub>2</sub>HCO<sub>3</sub></b>
+
+ Pellentesque purus feugiat semper. Donec nunc odio, et vitae pellentesque. Pellentesque Na2HCO3 velit lacus.
+
+
+
+CSS hyphens
+
+ The CSS property hyphens is now supported on all block elements
+
+hyphens: manual | auto | none
+
+ In the following example, the word interdependent contains no soft hyphen or similar characters, and is moved to the next line.
+
+ Cum velit lacus pena sociis natoque penatibus et magnis disa montes, nascetur ridicuus interdependent (no characters suggesting line-break).
+
+ manual (default)
+ Words are only broken at line breaks where there are characters inside the word that suggest line break opportunities. Characters can be explicit ("-" hard hyphen) or conditional (­ ­ <wbr>).
+ Cum velit lacus pena sociis natoque penatibus et magnis disa montes, nascetur ridicuus interdependent (uses soft hyphen ­).
+
+ none - Words are not broken at line breaks, even if characters inside the word suggest line break points.
+ Cum velit lacus pena sociis natoque penatibus et magnis disa montes, nascetur ridicuus inter-dependent (hard hyphen).
+
+ auto
+ Words can be broken at appropriate hyphenation points, as determined by characters inside the word.
+ Cum velit lacus pena sociis natoque penatibus et magnis disa montes, nascetur ridicuus interdependent (No characters suggesting line-break).
+ SHY inside the word take priority over hyphenation points determined by other resources.
+ Cum velit lacus pena sociis natoque penatibus et magnis disa montes, nascetur ridicuus interdependent (uses soft hyphen ­).
+
+ The configurable variables $this->hyphenate and $this->hyphenateTables are henceforth redundant and have no effect.
+ NB Support for <wbr> is new in mPDF 5.7
+
+
+
+
+
+
+Text circle
+
+ Added in mPDF 5.6 but not included in New Features example - transparent background and Divider were new. Now also added support for font-size:auto
+
+<textcircle r="30mm" top-text="Text Circular Text Circular" bottom-text="Text Circular Text Circular" divider="•" style="font-size: auto" />
+
+
+
+
+
+
+List numbering
+
+ This list is set to start numbering at 5
+ <ol start="5">
+
+- List item number 1
+- List item number 2
+- List item number 3
+
+
+
+
+
+
+<dottab> and outdent
+
+ <dottab> now supports a custom CSS property "outdent", which can also be used as an HTML attribute i.e. <dottab outdent="2em">
+ The first item uses <dottab outdent="4em"> whereas the following items have <dottab class="menu"> (with CSS dottab.menu{outdent: 4em;} ) and all have padding-right="4em" on the <div> element
+
+
+
+
+
+
+
+
+
+
+
+
+
+p.menu { text-align: justify; padding-right: 4em; }
+dottab.menu { outdent: 4em; }
+
+ NB It is recommended to use after the dottab if a space is required before the following content.
+ NB This (outdent) is also used in the Table of Contents (see earlier in this document).
+
+
+
+
+Layers
+
+ mPDF 5.7 will create layers in the document using the CSS property z-index. All layers are visible by default.
+ This demonstrates layers in a PDF document. Select the layers named "Correct Answers" or "Wrong Answers" in your PDF viewer (the layers pane should be open already in Adobe Acrobat)
+ What is the name of the Prime Minister of Britain?
+ David Cameron
+ Rupert Murdoch
+ What is the name of the David Beckham\'s bulldog?
+ Scarlet
+ Victoria
+ To open/close/select layers in Adobe Reader (10):
+
+ The layer names and initial state can be set (optionally) e.g.
+
+ $mpdf->layerDetails[1][\'state\']=\'hidden\'; // Set initial state of layer - "hidden" or ""
+ $mpdf->layerDetails[1][\'name\']=\'Correct Answers\';
+ $mpdf->layerDetails[2][\'state\']=\'hidden\';
+ $mpdf->layerDetails[2][\'name\']=\'Wrong Answers\';
+
+ This is the code used in the example above:
+
+ <div style="z-index:1;color: green;float: left; width:30%;">Scarlet</div>
+ <div style="z-index:2;color: red;">Victoria</div>
+
+ To force the PDF reader to open with the layers tab open, set:
+ $mpdf->open_layer_pane = true;
+
+
+
+
+
+
+CSS visibility on <span>
+CSS visibility:hidden is now supported on inline elements e.g. <span>
+
+ This next bit of text is hidden - Hidden text - and this isn\'t.
+ style="visibility:hidden;"
+ This next bit of text is only visible in print - Hidden text - and this isn\'t.
+ style="visibility:printonly;"
+ This next bit of text is only visible on screen - Hidden text - and this isn\'t.
+ style="visibility:screenonly;"
+ You can show or hide these elements as for layers (above).
+
+
+
+
+CSS "rem" unit
+
+
+ This line has the font-size set as 1rem
+ This line has the font-size set as 0.5rem
+ This line has the font-size set as 1.5rem
+
+
+
+ This line has the font-size set as 1em
+ This line has the font-size set as 0.5em
+ This line has the font-size set as 1.5em
+
+
+
+
+
+
+
+
+
+CSS outline
+
+ This is text with an outline set by CSS
+
+.outlined { text-outline: 0.1mm 0.1mm #FF0000; }
+
+
+
+
+
+
+
+CSS background-clip, background-origin & background-size
+
+ CSS background-clip, background-origin & background-size are now supported for most block level elements. (Not supported in tables, nor on page/body backgrounds).
+
+
+ background-clip: border-box[default value] background-origin: padding-box[default value]
+ background-clip: content-box; background-origin: content-box
+ background-clip: padding-box; background-origin: padding-box
+ background-clip: border-box; background-origin: border-box
+ background-clip: content-box; background-origin: border-box
+ background-clip: border-box; background-origin: content-box
+
+ background-clip: border-box[default value] background-origin: padding-box[default value]
+ background-clip: content-box; background-origin: content-box
+ background-clip: padding-box; background-origin: padding-box
+ background-clip: border-box; background-origin: border-box
+ background-clip: content-box; background-origin: border-box
+ background-clip: border-box; background-origin: content-box
+
+
+
+
+
+';
+
+$mpdf->h2toc = array('H3'=>0, 'H4'=>1);
+$mpdf->h2bookmarks = array('H3'=>0, 'H4'=>1);
+
+$mpdf->open_layer_pane = false;
+$mpdf->layerDetails[1]['state']='hidden'; // Set initial state of layer - "hidden" or nothing
+$mpdf->layerDetails[1]['name']='Correct Answers';
+$mpdf->layerDetails[2]['state']='hidden'; // Set initial state of layer - "hidden" or nothing
+$mpdf->layerDetails[2]['name']='Wrong Answers';
+
+
+//==============================================================
+$mpdf->autoLangToFont = true;
+
+$mpdf->WriteHTML($html);
+
+// OUTPUT
+$mpdf->Output(); exit;
+
+
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example61_new_mPDF_v6-0_features.php b/mpdf/examples/example61_new_mPDF_v6-0_features.php
new file mode 100644
index 0000000..3404e92
--- /dev/null
+++ b/mpdf/examples/example61_new_mPDF_v6-0_features.php
@@ -0,0 +1,2046 @@
+list_auto_mode = 'mpdf'; // Used for demonstration of lists
+//==============================================================
+
+$html = '
+
+
+
+
+
+ |
+Page {PAGENO} of {nbpg} |
+الصفحة {PAGENO} من {nbpg} |
+
+
+
+
+
+ |
+Page {PAGENO} of {nbpg} |
+{nbpg} পাতা থেকে পাতা {PAGENO} |
+
+
+
+
+
+ |
+Page {PAGENO} of {nbpg} |
+עמוד {PAGENO} או {nbpg} |
+
+
+
+
+
+
+
+New Features in mPDF v6.0
+
+Advanced Typography
+Many TrueType fonts contain OpenType Layout (OTL) tables. These Advanced Typographic tables contain additional information that extend the capabilities of the fonts to support high-quality international typography:
+
+
+- OTL fonts support ligatures, positional forms, alternates, and other substitutions.
+- OTL fonts include information to support features for two-dimensional positioning and glyph attachment.
+- OTL fonts contain explicit script and language information, so a text-processing application can adjust its behavior accordingly.
+
+
+mPDF 6 introduces the power and flexibility of the OpenType Layout font model into PDF.
+mPDF 6 supports GSUB, GPOS and GDEF tables for now. mPDF 6 does not support BASE and JSTF at present.
+
+Other mPDF 6 features to enhance complex scripts:
+
+- improved Bidirectional (Bidi) algorithm for right-to-left (RTL) text
+- support for Kashida for justification of arabic scripts
+- partial support for CSS3 optional font features e.g. font-feature-settings, font-variant
+- improved "autofont" capability to select fonts automatically for any script
+- support for CSS :lang selector
+- dictionary-based line-breaking for Lao, Thai and Khmer (U+200B is also supported)
+- separate algorithm for Tibetan line-breaking
+
+
+Note: There are other smart-font technologies around to deal with complex scripts, namely Graphite fonts (SIL International) and Apple Advanced Typography (AAT by Apple/Mac). mPDF 6 does not support these.
+
+What can OTL Fonts do?
+
+Support for OTL fonts allows the faithful display of almost all complex scripts:
+
+- Arabic (السلام عليكم), Hebrew (שלום), Syriac (ܐܣܛܪܢܓܠܐ)
+- Indic - Bengali (স্লামালিকুম), Devanagari (नमस्ते), Gujarati (નમસ્તે), Punjabi (ਸਤਿ ਸ੍ਰੀ ਅਕਾਲ),
+Kannada (ನಮಸ್ತೆ), Malayalam (നമസ്തെ), Oriya (ନମସ୍କର), Tamil (வணக்கம்), Telugu (నమస్కారం)
+- Sinhala (ආයුඛෝවන්),
+Thai (สวัสดี),
+Lao (ສະບາຍດີ),
+Khmer (ជំរាបសួរ),
+Myanmar (မဂႆလာပၝ),
+Tibetan (བཀྲ་ཤིས་བདེ་ལེགས།)
+
+
+Joining and Reordering
+
+র + ্ + খ + ্ + ম + ্ + ক + ্ + ষ + ্ + র + ি + ু =
+র্খ্ম্ক্ষ্রিু
+
+cf. http://www.microsoft.com/typography/OpenTypeDev/bengali/intro.htm
+
+Ligatures
+
+ffi ffl fi
+
+ffi ffl fi
+
+
+Language-dependent substitutions
+
+ Arabic: ۴ ۶ ٧ Urdu: ۴ ۶ ٧ Arabic: ه ۈ ۑ ە Kurdish: ه ۈ ۑ ە
+
+
+Font features - Optional substitutions
+Stylistic Alternatives (salt)
+
+ Arabic: ئ ع ک ـه ـهـ ـۀ Farsi: ئ ع ک ـه ـهـ ـۀ Arabic: گ Turkish: گ
+
+
+
+
+CSS control of discretionary OTL features
+
+
+salt: (off) all
+ (on)
+all
+
+
+
+
+frac: (off) 1/4 3/10
+ (on)
+1/4 3/10
+
+
+
+zero: (off) 1,000
+ (on)
+1,000
+
+
+
+onum: (off) 0123456789
+ (on)
+0123456789
+
+
+
+sups: (off) (32)
+ (on)
+(32)
+
+
+
+Stylistic Alternatives (ss03,ss04): (off) अ झ ण झ ९
+ (on)
+अ झ ण झ ९
+
+
+
+A full list of feature tags is at http://www.microsoft.com/typography/otspec/featurelist.htm
+In mPDF, the following features are on by default:
+
+- GSUB features: locl ccmp pref blwf abvf pstf pres abvs blws psts haln rlig calt liga clig mset (all scripts)
+- GSUB features: isol fina fin2 fin3 medi med2 init nukt akhn rphf rkrf half vatu cjct cfar (for appropriate scripts e.g. Indic, Arabic)
+
+- GPOS features: abvm blwm mark mkmk curs cpsp dist requ [kern]
+
+
+NB \'requ\' is not listed in the Microsoft registry of Feature tags; however it is found in the Arial Unicode MS font (it repositions the baseline for punctuation in Kannada script).
+
+
+Kern is used in some fonts to reposition marks etc. and is essential for correct display, so in mPDF kern is on by default when any non-Latin script is used.
+
+
+
+
+
+Mark repositioning (and diacritics)
+
+זֵּ יְּ ךָ
+
+זֵּ יְּ ךָ
+
+
+
+Mark repositioning (and Contextual substitution)
+
+Á á ï
+
+Á á ï
+
+
+
+
+Complex syllables
+Note that the text displayed is dependent on the font\'s design/capabilities. These are both "correct" representations of the same string, using:
+FreeSerif: र्द्मि
+and FreeSans font:
+र्द्मि
+
+cf. http://www.microsoft.com/typography/OpenTypeDev/devanagari/intro.htm
+
+
+ Complex Typography
+An example which utilises many different GSUB and GPOS features together - first without GSUB and GPOS:
+
+تَسْـَٔمُوٓا۟ أَوْ كَبِيرًا إِلَىٰٓ ٱللَّهِ وَأَدْنَىٰٓ أَلَّا إِلَّآ بَيْنَكُمْ عَلَيْكُمْ أَلَّا يَعْتُمْ ۚ
+
+With GSUB and GPOS:
+
+تَسْـَٔمُوٓا۟ أَوْ كَبِيرًا إِلَىٰٓ ٱللَّهِ وَأَدْنَىٰٓ أَلَّا إِلَّآ بَيْنَكُمْ عَلَيْكُمْ أَلَّا يَعْتُمْ ۚ
+
+
+
+
+Text Justification using Kashida
+
+
+يَـٰٓأَيُّهَا ٱلَّذِينَ ءَامَنُوٓا۟ إِذَا
+تَدَايَنتُم بِدَيْنٍ
+إِلَىٰٓ أَجَلٍۢ مُّسَمًّۭى فَٱكْتُبُوهُ ۚ
+
+
+يَـٰٓأَيُّهَا ٱلَّذِينَ ءَامَنُوٓا۟ إِذَا
+تَدَايَنتُم بِدَيْنٍ
+إِلَىٰٓ أَجَلٍۢ مُّسَمًّۭى فَٱكْتُبُوهُ ۚ
+
+
+
+
+
+What is "correct"?
+There are a number of factors which determine how the input text is displayed in an application.
+The font\'s capabilities/design (this example shows the same text input shown in 2 fonts):
+
+FreeSerif: र्द्मि
+and FreeSans font:
+र्द्मि
+
+
+Complex scripts require a "shaping engine" to re-order glyphs and apply the OTL features by syllable. MS Word and Wordpad run on the Windows platform use "Uniscribe", whereas some browsers such as FireFox and OpenOffice use Pango/HarfBuzz. The different shaping engines (and indeed different versions of them) can produce different results.
+
+Different applications have different defaults (on/off) for some of the features e.g. kerning.
+
+When testing mPDF 6, if text does not appear as you expect, ensure that the font is installed on your computer, and view the HTML in a browser. Also try copying/pasting the text into Wordpad/Word/OpenOffice and ensure that the correct font has been applied.
+
+Note that Wordpad sometimes substitutes a different font if it does not like the one you have chosen, and does not even indicate that the substitution has occurred.
+
+
+
+
+
+CSS control of font features
+See http://www.w3.org/TR/css3-fonts/#font-rend-props for information about CSS3 and font-features.
+
+
+The following are supported in mPDF 6:
+
+- font-variant-position
+- font-variant-caps
+- font-variant-ligatures
+- font-variant-numeric
+- font-variant-alternates - Only [normal | historical-forms] supported (i.e. most are NOT supported)
+e.g. stylistic, styleset, character-variant, swash, ornaments, annotation (use font-feature-settings for these)
+- font-variant - as above, and except for: east-asian-variant-values, east-asian-width-values, ruby
+- font-language-override
+- font-feature-settings
+
+
+font-variant-east-asian is NOT supported
+NB @font-face is NOT supported
+NB @font-feature-values is NOT supported
+
+Note that font-variant specifies a single property in CSS2, whereas in CSS3 it has become a shorthand for all the other font-variant-* properties. font-variant: small-caps was the only one supported in mPDF <v6, and will still work in mPDF 6.
+
+See notes later about font kerning.
+
+Some examples
+
+/* use small-cap alternate glyphs */
+.smallcaps { font-feature-settings: "smcp" on; }
+
+/* convert both upper and lowercase to small caps (affects punctuation also) */
+.allsmallcaps { font-feature-settings: "c2sc", "smcp"; }
+
+/* enable historical forms */
+.hist { font-feature-settings: "hist"; }
+
+/* disable common ligatures, usually on by default */
+.noligs { font-feature-settings: "liga" 0; }
+
+/* enable tabular (monospaced) figures */
+td.tabular { font-feature-settings: "tnum"; }
+
+/* enable automatic fractions */
+.fractions { font-feature-settings: "frac"; }
+
+/* use the second available swash character */
+.swash { font-feature-settings: "swsh" 2; }
+
+/* enable stylistic set 7 */
+.fancystyle {
+ font-family: Gabriola; /* available on Windows 7, and on Mac OS */
+ font-feature-settings: "ss07";
+}
+
+
+
+
+
+
+More Examples
+Note the automatic line breaking used in Lao, Thai, Khmer and Tibetan text.
+SYRIAC - Estrangelo Edessa
+
+ ܘܬܘܒ ܐܬܟܢܝܬ ܗܕܐ ܕܝܪܐ ܩܕܝܫܬܐ ܒܫܡ ܩܕܝܫܐ ܥܢܘܝܐ ܡܪܝ ܐܘܓܝܢ ܕܐܬܐ ܗ̱ܘܐ ܡܢ ܡܨܪܝܢ ܆ ܥܠ ܒܙܒܢ ܩܪܒܐ ܐܝܬܝܘ ܕܝܪ̈ܝܐ (ܐܝܟ ܬܫܥܝܬܐ ܬܘܕܝܬܢܝܬܐ) ܚܕܟܡܐ ܓܪ̈ܡܐ ܕܩܕܝܫܐ ܡܢ ܕܝܪܐ ܕܡܪܝ ܐܘܓܝܢ ܒܛܘܪܐ ܕ ܐܝܙܠܐ ܕܢܦܠ ܒܡܕܒܪܐ ܕ ܢܨܝܒܝܢ ܥܠ ܬܚܘܡܐ ܕ ܩܡܫܠܝ. ܘܬܘܒ ܐܬܟܢܝܬ ܕܝܪܐ ܕ ܙܥܦܪܐܢ ܐܘ ܟܘܪܟܡܐ ܒܫܡ ܡܪܝ (ܫܠܝܡܘܢ) ܕܝܪܝܐ ܕܫܬܐܣ ܠܕܝܪܐ ܒܫܢܬ 473 ܡ.
+
+
+
+MYANMAR (Burmese)
+Padauk Book (SIL Font)
+
+မြန်မာအခေါ် တရားဝင်အားဖြင့် ပြည်ထောင်စု သမ္မတ မြန်မာနိုင်ငံတော်သည် အရှေ့တောင်အာရှတွင် ဧရိယာအားဖြင့် ဒုတိယ အကျယ်ဝန်းဆုံး[၁] တိုင်းပြည် ဖြစ်သည်။ ၁၉၄၈ ခုနှစ် ဇန်နဝါရီ ၄ ရက်တွင် ဂရိတ်ဗြိတိန်နိုင်ငံထံမှ (အင်္ဂလိပ်လို "Myanmar" အဖြစ်နှင့်) ပြည်ထောင်စုမြန်မာနိုင်ငံတော်အဖြစ် လွတ်လပ်ရေးကို ရရှိခဲ့သည်။ နောက်ပိုင်းတွင် ပြည်ထောင်စု ဆိုရှယ်လစ် သမ္မတမြန်မာနိုင်ငံတော်အဖြစ် ၁၉၇၄ ခုနှစ် ဇန်နဝါရီ ၄ ရက်တွင်လည်းကောင်း၊ ပြည်ထောင်စု မြန်မာနိုင်ငံတော်အဖြစ် ၁၉၈၈ခုနှစ် စက်တင်ဘာ ၂၃ ရက်တွင်လည်းကောင်း၊ ပြည်ထောင်စု မြန်မာနိုင်ငံတော်အဖြစ် ၁၉၈၉ ခုနှစ် ဇွန် ၁၈ ရက်တွင် လည်းကောင်း အမည်များပြောင်းလဲခဲ့သည်။ အာဏာရစစ်အစိုးရအား အသိအမှတ် မပြုသော အဖွဲ့အစည်းများက ဘားမား ("Burma") ဟုသာ အသိအမှတ်ပြု သုံးစွဲခဲ့သည်။ နိုင်ငံတော်အလံကိုလည်း ယခင် နိုင်ငံတော် အေးချမ်းသာယာရေးနှင့် ဖွံ့ဖြိုးရေးကောင်စီအစိုးရလက်ထက် ၂၀၀၈ ခုနှစ် ဖွဲ့စည်းပုံ အခြေခံ ဥပဒေတွင် ပြဋ္ဌာန်းထားသည့် ပြည်ထောင်စု သမ္မတ မြန်မာနိုင်ငံတော်အလံ ဖြင့် ၂၀၁၀ ခုနှစ် အောက်တိုဘာလ ၂၁ ရက်နေ့တွင် အလံစတင်လွှင့်ထူခြင်း အခမ်းအနားများကို နိုင်ငံတဝှမ်း ကျင်းပကာ အစားထိုး၍ ပြောင်းလဲ အသုံးခဲ့ပြုသည်။
+
+
+KHMER
+
+ង្គ្រ
+ន្រ្តី
+ង្គ្រោះ
+
+
+យុវជនម្នាក់បានស្លាប់ដោយគ្រាប់កាំភ្លើងរបស់ប៉ូលិស និងបីនាក់ផ្សេងទៀតរងរបួស នៅក្នុងការប្រឈមមុខដាក់គ្នាដាច់ដោយឡែកគ្នាមួយ រវាងក្រុមយុវជនមួយក្រុម ជាមួយប៉ូលិស នៅម្តុំស្ពានក្បាលថ្នល់។ នេះបើតាមព័ត៌មានពីលោក ចាន់ សាវ៉េត មន្រ្តីស៊ើបអង្កេតរបស់អង្គការសិទ្ធិមនុស្សអាដហុក ដែលវត្តមាននៅកន្លែងកន្លែងកើតហេតុ នៅយប់ថ្ងៃអាទិត្យទី ១៥ កញ្ញានេះ។
+
+
+
+HEBREW - with Niqud and T\'amim (cantillation)
+
+לָכֵ֤ן חַכּוּ־לִי֙ נְאֻם־יְהוָ֔ה לְי֖וֹם קוּמִ֣י לְעַ֑ד כִּ֣י מִשְׁפָּטִי֩ לֶאֱסֹ֨ף גּוֹיִ֜ם לְקָבְצִ֣י מַמְלָכ֗וֹת לִשְׁפֹּ֨ךְ עֲלֵיהֶ֤ם זַעְמִי֙ כֹּ֚ל חֲר֣וֹן אַפִּ֔י כִּ֚י בְּאֵ֣שׁ קִנְאָתִ֔י תֵּאָכֵ֖ל כָּל־הָאָֽרֶץ׃
+
+
+
+NKo
+
+ߟߐ߬ߝߋ߲ ߓߍ߯ ߟߊߝߋ߲ ߊߡߋߙߌߞ ߒߞߏ ߘߌ߲ߞߏ ߓߍ߮ ߛߎ߬ߣߎ߲ߣߌ߲ ߠߋ ߊ߲ ߞߊ߬ߙߊ߲߬ߡߐ߯ ߓߎߓߊߞߊ߯ߙߌ߫ ߖߊ߬ߞߌ߬ߕߋ߫ ߝߊ߬ ߟߊ߫ ߛߏߡߊߦߟߍߡߊ߲ ߠߊ߫ ߑ ߫ߊ߲ ߓߍ߮ ߡߊ߬ߙߌ ߫ ߘߊߟߌߟߊ߫ ߊ߬ ߦߊߝߊ ߞߍ߫ ߊ߬ ߡߊ߬ ߸ ߞ߬߭ ߊ߬ ߟߊߦߙߐ ߛߎߡߊ ߊ߲ ߠߊ߫ ߘߎߓߊ ߦߋ ߕߊߓߊ߯ߕߐ߫ ߓߍ߯ ߦߋ ߫ ߊߟߊ߬ߡߊ ߤߌߣߊ߫ ߘ߭ߵߊߟߎ ߓߍ߯ ߟߊ߬
+
+
+
+
+THAANA
+
+ދިވެހި ވިކިޕީޑިއާ ގައި ބޭނުންކުރެވޭ ބަސްތައް އެއްގޮތަށް ދެމެހެއްޓޭތޯ މަސައްކަތް ކުރުން
+
+މިސާލަކަށް ޗައިނާ އަށް ސީނުކަރަ އިންޑިޔާ އަށް ހިންދުސްތާން، އަދި ސްރީލަންކާ އަށް އޮޅުދޫކަރަ ކިޔާކިޔުން ދާއިމީ ގޮތެއްގައި ހިފެހެއްޓުމަށް މަސައްކަތްކުރުން! މާނައަކީ އެއްތަނެއްގައި ސީނުކަރަ އަނެއް ތަނެއްގައި ޗައިނާ މިގޮތަށް ބޭނުން ނުކުރުން، އަދި މިނޫން މިފަދަ ބަސްތައް ވެސް މިއުޞޫލާ ޚިލާފުނުވާނޭ ގޮތަށް ބޭނުންކުރުން!
+ދިވެހި ވިކިޕީޑިއާގެ ތެރެއިން ދިވެހި ބަސް ކުރިއެރުވުމަށް މަސައްކަތް ކުރުން
+
+
+
+LAO
+
+ສາທາລະນະລັດ ປະຊາທິປະໄຕ ປະຊາຊົນລາວ (ຄຳເຄົ້າ: ສາທາຣນຣັຖປຊາທິປຕັຍປຊາຊົນລາວ[໑]) ຫຼື ສປປ ລາວ ຕັ້ງຢູ່ທິດຕາເວັນອອກສຽງໃຕ້ຂອງທະວີບອາຊີ, ຢູ່ໃຈກາງຂອງແຫຼມອິນດູຈີນລະຫວ່າງເສັ້ນຂະໜານທີ 14 - 23 ອົງສາເໜືອ ແລະ ເສັ້ນແວງທີ 100-108 ອົງສາ ສປປ ລາວມີເນື້ອທີ່ທັງໝົດ 236.800 ຕາລາງກິໂລແມັດ ເປັນປະເທດທີ່ບໍ່ມີທາງອອກສູ່ທະເລ, ມີຊາຍແດນຕິດກັບ ສາທາລະນະລັດປະຊາຊົນຈີນ (505 ກິໂລແມັດ), ທິດໃຕ້ຕິດກັບລາຊະອານາຈັກກຳປູເຈຍ (435 ກິໂລແມັດ), ທິດຕາເວັນອອກຕິດກັບ ສາທາລະນະລັດສັງຄົມນິຍົມຫວຽດນາມ ( 2.069 ກິໂລແມັດ ), ທິດຕາເວັນຕົກຕິດກັບລາຊະອານາຈັກໄທ ( 1.385 ກິໂລແມັດ ), ແລະ ທິດຕາເວັນຕົກສຽງເໜືອຕິດກັບ ສາທາລະນະລັດແຫ່ງສະຫະພາບມຽນມາ ( 236 ກິໂລແມັດ ), ສ.ປ.ປ.ລາວ ເປັນປະເທດດຽວໃນພາກພື້ນນີ້ທີ່ບໍ່ມີຊາຍແດນຕິດກັບທະເລ.
+
+
+THAI
+
+"ซัมติง" เป็นเพลงของวงเดอะบีตเทิลส์ ในปี ค.ศ. 1969 เป็นเพลงที่บรรจุอยู่ในอัลบั้มชุด แอบบีโรด เพลงนี้เป็นเพลงแรกที่ซิงเกิลหน้าเอที่จอร์จ แฮร์ริสันเขียน และถือเป็นซิงเกิลแรกของเดอะบีตเทิลส์ที่มีเพลงที่มีอยู่แล้วในอัลบั้มบรรจุอยู่ด้วย ทั้งเพลง "ซัมติง" และเพลง "คัมทูเกตเตอร์" ที่อยู่ในอัลบั้ม แอบบีโรด และเพลง "ซัมติง" ถือเป็นเพลงเดียวที่แฮร์ริสันแต่งแล้วขึ้นอันดับ 1 บนชาร์ตอเมริกันขณะที่ยังอยู่ในวงเดอะบีตเทิลส์
+
+
+
+
+SINHALA
+
+නඩත්තු කාර්යයන් විකිපීඩියාව ප්රශස්ත මට්ටමකින් පවත්වා ගැනීම සදහා අත්යවශ්ය අංගයකි. උපදෙස් රූරාව මගින් තවත් අලුත් නඩත්තු කාර්යයන් තැනීමේදී පරිස්සම් විය යුතුය. ඔබට හැකි විට සංවිධානාත්මක වන්න, එහෙත් සෑමවිටම විශාල පින්තූරය ඇතුලතින් තබා ගන්න: අප මෙතැනට පැමිණ සිටින්නේ විශ්වකෝෂයක් තැනීම සදහායි. ඔබ සිතන්නේ නඩත්තු කිරීම්වලට වඩා අනෙකුත් පැතිවලින් විකිපීඩියාවට දායක වීමට නම්, කරැණාකර විකිපීඩියා:විකිපීඩියාවට දායක වීම බලන්න. ඉක්මනින් අවශ්ය සහ ඉතා වැදගත් වන කාර්යයන් විකිපීඩියා:අතපසු වූ වැඩ හීදි සොයාගැනීමට අවස්ථාව ඇත.
+
+
+
+TIBETAN
+
+༄།ཏདྱཐཱ།ཨོཾགཏེགཏེཔཱརགཏེཔཱརསཾགཏེབོདྷིསྭཱཧཱ།
+ཨོཾམུནིམུནིམཧཱམུནིཡེསྭཱཧཱ།ཨོཾཨཱམིདྷེཝཱཧྲཱི།ཨོཾམཎིཔདྨེཧཱུཾ།ཨོཾཨཱཿཧཱུཾ་
+བཛྲགུརུཔདྨསིདྡྷིཧཱུཾ།ཨོཾཨཱམརཱཎིཛྲིཝནཏིཡེསྭཱཧཱ།ཨོཾཝགིཤཱརིམུཾ།ཨོཾ་
+མཎིཔདྨེཧཱུཾ།ཨོཾབཛྲཔཱནིཧཱུཾ།ཨོཾཏཱརེཏུཏྟཱརེཏུརེསྭཱཧཱ།ཨོཾབྷྲཱུཾ་
+སྭཱཧཱ།ཨོཾཨཱམྲིཏཱཨཱཡུརྡདེསྭཱཧཱ།ཨོཾམརིཙྱེམཾསྭཱཧཱ།
+
+
+TAI THAM
+
+ᨢ᩶ᩣᨧᩮᩢ᩶ᩣᨸᩮᩢ᩠ᨶᩈᩣ᩠ᩅᨩ᩠ᨿᨦᩉ᩠ᨾᩲ᩵ ᩉ᩠ᨾᩯᨷᩴ᩵ᩬᨴᩮᩢ᩵ᩣᨯᩲᨠᩴ᩶ᩬᨧᩡᨸᩮᩢ᩠ᨶᩈᩣ᩠ᩅᩃᩯ᩠᩶ᩅ ᨲᩧ᩠ᨦᩅᩢ᩠ᨶᨾᩦᨷ᩵ᩤ᩠ᩅᨾᩣᩋᩯ᩠᩵ᩅ
+ᨾᩣᩋᩪ᩶ᨾᩣᨪᩯ᩠ᩅ ᨸᩮᩢ᩠ᨶᨤᩫ᩠ᨶᩃᨻᩪᩁ ᨢ᩶ᩣᨧᩮᩢ᩶ᩣᨧᩡᩮᩃᩥᩬᨠᩋᩮᩢᩣᨹᩱ ᩋ᩶ᩣ᩠ᨿᨷ᩵ᩤ᩠ᩅᨩ᩠ᨿᨦᩁᩣ᩠ᨿᨩᩨ᩵ᨠᩯ᩠᩶ᩅᨾᩣᩃᩪᩁ ᩋ᩶ᩣ᩠ᨿᨠᩬᨦᨤᩫ᩠ᨶᨻᩯ᩵ᨢ᩠ᨿᩅᨨᩩᨶ ᩋ᩶ᩣ᩠ᨿᨤᩴᩣᩋ᩶ᩣ᩠ᨿᨾᩪᩁ ᩋ᩶ᩣ᩠ᨿᩈᩫ᩠ᨾᩋ᩶ᩣ᩠ᨿᨾᩦ ᨻᩮᩥ᩠᩵ᨶᨷᩬᨠᩅ᩵ᩤᨧᩡᨾᩣᨢᩴᩬᨢ᩶ᩣᨧᩮᩢ᩶ᩣᨠᩴᩬᩁᩴᩬᨾᩣᩃᩯ᩠᩶ᩅᨸᩮᩢ᩠ᨶᨸᩦ
+
+
+
+
+Dictionary Line breaking
+Lao, Thai and Khmer text does not have space between words. By default, mPDF 6 uses word dictionaries to determine appropriate opportunites for line-breaks. Users may turn this function off using the configurable variable useDictionaryLBR.
+
+Alternatively users can insert the character U+200B (zero-width space) in the text to mark line-breaking opportunities manually.
+
+Similarly for Tibetan script, mPDF 6 uses a simple algorithm to identify line-breaking opportunities after the characters U+0F0B (Tsheg) or U+0F0D. This can be overriden using the configurable variable useTibetanLBR.
+
+
+
+
+
+Myanmar Fonts
+
+Myanmar (Burmese) on the web is quite frequently written for fonts which are not strictly unicode-compliant. This includes common applications such as WordPress and a number of official Burmese government websites.
+Ayar fonts (http://www.ayarunicodegroup.org) are based on text input where the vowel preceeds the consonant (which is contrary to Unicode specification).
+
+ZawGyi-One is another very common font in use. This font has some characters incorrectly coded e.g. U+103A as U+1039.
+There are also fonts available which are fully unicode compliant, such as Padauk, Tharlon, Myanmar3, and Microsoft\'s Myanmar Text.
+As long as you select the right font for the input text, all of them work fine in mPDF:
+
+
+Tharlon: ဒီရက်ပိုင်းမှာ ဧရာဖောင့်ကို ယူနီကုဒ်အဖြစ် ရည်ညွှန်းပြောဆိုနေကြတာ တွေ့ရလို့ ဧရာဟာ ယူနီကုဒ် မဖြစ်ကြောင်းနဲ့ ဘာလို့မဖြစ်ရတာလဲဆိုတာ အတိုပဲ ရှင်းပါမယ်။ ယူနီကုဒ်ဖြစ်ဖို့ - ၁။ ယူနီကုဒ် ကုဒ်ပွိုင့်နဲ့ ကိုက်ညီရပါမယ်။
+၂။ ယူနီကုဒ် စာလုံးစီပုံ (Encoding) နဲ့ ကိုက်ညီရပါမယ်။
+
+from http://www.myanmarlanguage.org/unicode
+
+Zawgyi-one: စီးပြားေရးနွင့္ကူးသန္းေရာင္းဝယ္ေရးဝန္ၾကီးဌာန ျပည္ေထာင္စုဝန္ၾကီး မႏၱေလးတုိင္းေဒသၾကီး ေက်းလက္ေဒသ အေသးစား ကုန္ထုတ္လုပ္ငန္းမ်ား ၾကည့္ရွဳအားေပး
+
+from http://www.commerce.gov.mm/
+
+
+Ayar: WordPress တရားဝင် ြမန်မာဘာသာ စာမျက်နှာမှ ြကိုဆိုပါတယ်။ !
+ရာနှုန်းြပည့် ဘာသာြပန်ထားသည့် WordPress ြမန်မာ ဘာသာြပန်မူကို ဗားရှင်း ၃.၁ ြဖင့် စတင် ြဖန့်ချိလိုက်ြပီးသည့်ေနာက် ဆက်လက်၍ အဆင့်ြမှင့်တင်မှု ဗားရှင်းများကို အချိန်နှင့်တစ်ေြပးညီ
+
+from https://mya.wordpress.org/
+
+
+
+lang selector
+mPDF 6 supports use of the lang selector in CSS. All of the following are supported:
+
+- :lang(fr)
+- p:lang(fr)
+- span:lang("syr")
+- [lang="fr"]
+- [lang=\'fr\']
+- p[lang=fr]
+- p[lang="zh-TW"]
+
+
+Note: [lang=zh] will match lang="zh-TW" and lang="zh-HK"
+
+Limitation: class selectors and attribute selectors should be of equal specificity in CSS specification e.g.
+
+:lang(syr) { color: blue; }
+.syriac { color: red; }
+
+should be of equal specificity, and thus apply whichever comes later in the CSS stylesheet. mPDF 6 however gives :lang priority over .class
+
+The use of the lang attribute and CSS selector is now the recommended method for handling multi-lingual documents in mPDF 6.
+
+lang HTML attribute
+The HTML lang attribute has a number of uses:
+
+- when OTL tables are being used for a font, the language from the lang attribute is used to select which OTL features are applied;
+- used in conjunction with CSS lang selector to allow CSS styles to be applied;
+- can be used in conjunction with autoLangToFont and autoScriptToLang (see below)
+
+IETF tags should be used for lang which comply with the following:
+
+- a 2 or 3 letter Language code, followed optionally by
+- a hyphen and a 4 letter Script code, and or
+- a hyphen and a 2 letter Region code
+
+- i.e. [xx|xxx]{-Xxxx}{-XX}
+- mPDF deals with IETF tags as case insensitive
+
+
+
+
+
+Automatic font selection
+
+Note: This functionality of mPDF has changed considerably in mPDF v6 and is not backwards compatible.
+
+mPDF 6 has two functions which can be used together or separately:
+
+autoScriptToLang - marks up HTML text using the lang attribute, based on the Unicode script block in question, and configurable values in config_script2lang.php.
+autoLangToFont - selects the font to use, based on the HTML lang attribute, using configurable values in config_lang2font.php.
+
+For automatic font selection, ideally we would choose the font based on the language in use. However it is actually impossible to determine the language used from a string of HTML text. The Unicode script block can be ascertained, and sometimes this tells us the language e.g. Telugu. However, Cyrillic script is used for example in many different languages. So the best we can do is base it on the script used. However, mPDF 6 does this in two stages via the "lang" attribute, because this allows the options of using either of the stages alone or together:
+
+
+ <p>English ру́сский язы́к پښتو</p>
+ ↓ autoScriptToLang (config_script2lang.php) ↓
+
+ <p>English <span lang="und-Cyrl">ру́сский язы́к</span>
+<span lang="ps">پښتو</span></p>
+ ↓ autoLangToFont (config_lang2fonts.php) ↓
+
+ Uses "lang" to select font, and to determine OTL features applied
+
+
+autoScriptToLang
+
+
+$mpdf->autoScriptToLang = true;
+$mpdf->baseScript = 1;
+$mpdf->autoVietnamese = true;
+$mpdf->autoArabic = true;
+
+
+$mpdf->baseScript = 1; tells mPDF which Script to ignore. It is set by default to "1" which is for Latin script. In this mode, all scripts except Latin script are marked up with "lang" attribute. To select other scripts as the base, see the file /classes/ucdn.php
+
+Using autoScriptToLang, mPDF detects text runs based on Unicode script block; using the values in config_script2lang.php it then encloses the text run within a span tag with the appropriate language attribute. For many scripts, the language cannot be determined: see the example above which recognises Cyrillic script and marks it up using und-Cyrl, which is a valid IETF tag, coding for language="undetermined", script="Cyrillic".
+
+Two optional refinements are added: Vietnamese text can often be recognised by the presence of certain characters which do not appear in other Latin script langauges, and similarly analysis of the text can attempt to distinguish Arabic, Farsi, Pashto, Urdu and Sindhi. If active, the text will then be marked with a specific language tag e.g. "vi", "pa", "ur", "fa" etc.
+
+These features can be disabled or enabled (default) using the variables $mpdf->autoVietnamese
+$mpdf->autoArabic, either in config.php or at runtime.
+
+
+
+autoLangToFont
+
+$mpdf->autoLangToFont = true;
+
+You can edit the values in config_lang2font.php to specify which fonts are used for which "lang".
+
+
+Using text with multiple languages
+Recommended ways to use multiple languages in mPDF:
+
+- If you have full control over the HTML, mark-up the text with the "lang" atribute and use CSS (:lang selector preferably); this method means that the language information can also be used by OTL for language dependent substitutions.
+- If you have no control over (user) HTML input and want to output faithfully, use both autoScriptToLang and autoLangToFont
+
+
+It is preferable not to use autoScriptToLang and autoLangToFont unless they are necessary: they will result in increased processing time, and OTL tables will not be able to use language dependent substitutions when undefined languages are set e.g "und-Cyrl".
+
+
+Updating from previous mPDF versions
+As a brief summary, to update from previous versions of mPDF:
+Use $this->autoScriptToLang=true instead of $this->SetAutoFont()
+Use $this->autoLangToFont instead of $this->useLang
+
+
+
+Bidi Bidirectional text
+
+The algorithm to handle bi-directional text (right to left) has been completely rewritten. Text is now processed across the whole paragraph ignoring inline tags. There is also full support for the methods to control/override the display.
+
+
+1) The following Unicode characters are supported, and can be inserted directly in the text as HTML entities:
+
+
+| LRE | U+202A | LEFT-TO-RIGHT EMBEDDING | ‪ |
+
+
+| RLE | U+202B | RIGHT-TO-LEFT EMBEDDING | ‫ |
+
+
+| LRO | U+202D | LEFT-TO-RIGHT OVERRIDE | ‭ |
+
+
+| RLO | U+202E | RIGHT-TO-LEFT OVERRIDE | ‮ |
+
+
+| PDF | U+202C | POP DIRECTIONAL FORMATTING | ‬ |
+
+
+ | | | |
+
+
+| LRI | U+2066 | LEFT-TO-RIGHT ISOLATE | ⁦ |
+
+
+| RLI | U+2067 | RIGHT-TO-LEFT ISOLATE | ⁧ |
+
+
+| FSI | U+2068 | FIRST STRONG ISOLATE | ⁨ |
+
+
+| PDI | U+2069 | POP DIRECTIONAL ISOLATE | ⁩ |
+
+
+ | | | |
+
+
+| LRM | U+200E | LEFT-TO-RIGHT MARK | ‎ |
+
+
+| RLM | U+200F | RIGHT-TO-LEFT MARK | ‏ |
+
+
+
+2) The following HTML tags are supported:
+
+- <bdo> (NB the "dir" attribute is mandatory on <bdo>)
+- <bdi> (HTML5)
+
+
+
+
+3) The CSS property "unicode-bidi" is supported with the following (CSS3) values: normal | embed | isolate | bidi-override | isolate-override | plaintext.
+
+See http://www.w3.org/TR/css3-writing-modes/#unicode-bidi
+for more details.
+
+"unicode-bidi" is supported on block level elements as well as in-line elements, but note that:
+ - the value is not inherited to child blocks
+- using "embed" or "isolate" has no effect on block level boxes
+- "isolate-override" is equivalent to "bidi-override" on block level boxes
+
+
+
+NB dir="auto" is not supported generally, but it is supported for <bdi> (has the same effect as if omitted) to use First Strong Isolate (FSI).
+
+Directionality can now be set on individual table cells <td style="direction:rtl;unicode-bidi:embed;"> or <td dir="rtl">
+
+
+Equivalent methods
+The following are equivalent methods:
+
+
+|
+EMBED
+ |
+
+<span dir="rtl">...</span>
+‫...‬
+<span style="direction: rtl; unicode-bidi: embed">...</span>
+ |
+|
+OVERRIDE
+ |
+
+<bdo dir="rtl">...</bdo>
+‮...‬
+<span dir="rtl" style="unicode-bidi: bidi-override">...</span>
+<span style="direction: rtl; unicode-bidi: bidi-override">...</span>
+ |
+|
+ISOLATE
+ |
+
+<bdi dir="ltr">...</bdi>
+⁧...⁩
+<span dir="rtl" style="unicode-bidi: isolate">...</span>
+<span style="direction: rtl; unicode-bidi: isolate">...</span>
+ |
+|
+First Strong Isolate (FSI)
+ |
+
+<bdi>...</bdi>
+<bdi dir="auto">...</bdi>
+⁨...⁩
+<span dir="rtl" style="unicode-bidi: plaintext">...</span>
+<span style="direction: rtl; unicode-bidi: plaintext">...</span>
+ |
+
+
+
+First strong isolate (FSI)
+FSI is useful when including text within a paragraph where the directionality of the text is unknown. For example, if you are printing out a catalogue from a database of book titles and the number of readers, when some book titles are in right-to-left script, you may use this template:
+
+
+<li>Title: {TITLE} - {READERS} readers</li>
+
+
+This would result in the following:
+
+
+- Title: Alice in Wonderland - 12390 readers
+- Title: עליסה בארץ הפלאות, סיפור-ילדים מאת לואיס קרול - 17890 readers
+
+
+
+<li>Title: <bdi>{TITLE}</bdi> - {READERS} readers</li>
+
+
+Using BDI will result in the following:
+
+
+- Title: Alice in Wonderland - 12390 readers
+- Title: עליסה בארץ הפלאות, סיפור-ילדים מאת לואיס קרול - 17890 readers
+
+
+
+
+
+Kerning
+Kerning is a bit complicated! CSS3 allows for 2 methods of specifying kerning. In mPDF 6, these 2 methods have exactly the same effect:
+
+- font-kerning: normal;
+- font-feature-settings: \'kern\' on;
+
+
+TrueType fonts allow for 2 possible ways of including kerning data:
+
+- OTL GPOS table may contain kerning information
+- A separate kern table
+
+Most fonts contain both or none, but they may exist independently.
+
+If kerning is set to be active (by either of the CSS methods):
+
+- if the useOTL value means that OTL GPOS tables are applied, then this method will be used;
+- if not, then the separate kern table will be used - if it exists.
+
+
+
+
+In Latin script, kerning will only be applied if specified by CSS. The configurable variable useKerning determines behaviour if font-kerning: auto is used (the default).
+
+When using OTL tables, kerning is set to be on by default for non-LATIN script; this is because a number of fonts use information in the kern feature to reposition glyphs which are essential for correct display in complex scripts.
+
+Limitation: if useOTL is set, but not for Latin script (e.g. = 0x02), and the text string contains more than one script, then kerning will not be applied to the Latin script text e.g. [Cyrillic text][Latin text][Cyrillic text]. This is because mPDF uses the presence of any repositioning applied to determine if kerning has been applied, otherwise using the alternative kern tables.
+
+
+Small-Caps
+Small Caps should be selected using:
+
+<p style="font-variant-caps:small-caps">This is in small caps</p>
+
+and will appear as: This is in small caps
+
+Note: font-variant:small-caps will also be recognised as font-variant is now considered the shorthand version cf. above.
+
+If the font has useOTL enabled (to any value), and the font OTL tables contain the "smcp" feature, then the OTL feature will be used to substitute purpose-designed glyphs from the font. Otherwise, mPDF generates small capitals as in previous version.
+
+
+
+Superscript and Subscript
+
+
+<p>This is in <span style="font-variant-position:super">superscript</span></p>
+
+will appear as superscript (only) if the font is OTL-capable and contains specific glyphs for superscript.
+
+ Note that font-variant:super will also be recognised as font-variant is now considered the shorthand version cf. above.
+
+If the font has useOTL enabled (to any value), and the font OTL tables contain the "sups" feature, then the OTL feature will be used to substitute purpose-designed glyphs from the font.
+
+The same for subscript using font-variant-position:sub.
+
+If you wish to use a superscript/subscript which will work with any font, continue to use the tags <sup> and <sub> which (through the default CSS in config.php) will generate superscript using CSS vertical-align=super and font-size=55%.
+
+
+
+How to use OTL in mPDF
+In config_fonts.php there are 2 new variables which affect OTL features e.g.:
+
+
+ "dejavusanscondensed" => array(
+ \'R\' => "DejaVuSansCondensed.ttf",
+ \'B\' => "DejaVuSansCondensed-Bold.ttf",
+ \'I\' => "DejaVuSansCondensed-Oblique.ttf",
+ \'BI\' => "DejaVuSansCondensed-BoldOblique.ttf",
+ \'useOTL\' => 0xFF,
+ \'useKashida\' => 75,
+ ),
+
+
+mPDF is published with a large collection of fonts, and all configured to use their full OTL capabilities.
+
+useOTL
+useOTL should be set to an integer between 0 and 255. Each bit will enable OTL features for a different group of scripts:
+
+| Bit | dec | hex | Enabled |
+| 1 | 1 | 0x01 | GSUB/GPOS - Latin script |
+| 2 | 2 | 0x02 | GSUB/GPOS - Cyrillic script |
+| 3 | 4 | 0x04 | GSUB/GPOS - Greek script |
+| 4 | 8 | 0x08 | GSUB/GPOS - CJK scripts (excluding Hangul-Jamo) |
+| 5 | 16 | 0x10 | (Reserved) |
+| 6 | 32 | 0x20 | (Reserved) |
+| 7 | 64 | 0x40 | (Reserved) |
+| 8 | 128 | 0x80 | GSUB/GPOS - All other scripts (including all RTL scripts, complex scripts etc) |
+
+
+Setting useOTL to 0 (or omitting it) will disable all OTL features. Setting useOTL to 255 or 0xFF will enable OTL for all scripts. Setting useOTL to 0x82 will enable OTL features for Cyrillic and complex scripts.
+
+In a font like Free Serif, it may be useful to enable OTL features for complex scripts, but disable OTL for Latin scripts (to save processing time). However, see above - this may disable kerning in Latin scripts in certain circumstances.
+
+
+useKashida
+useKashida should be set for arabic fonts if you wish to enable text justification using kashida. The value should be an integer between 0 and 100 and represents the percentage of additional space required to justify the text on a line as a ratio of kashida/inter-word spacing.
+
+
+
+Choosing fonts to add to mPDF 6
+Fonts with OTL need to have GDEF, GSUB and GPOS tables in the font file. Although TrueType font files are binary files, the table names and script/feature tags are written as ASCII characters; open the .ttf or .otf file in a text editor such as Windows Notepad, and you will see GDEF, GSUB and GPOS in the first few lines if they are present. You can also search the file to see if the script tags are present for your desired scripts cf. http://www.microsoft.com/typography/otspec/scripttags.htm.
+
+Note: The OTL specification for Indic fonts was updated in 2005 to version 2. The v2 script tag for Bengali is "bng2" whereas prior to this it was "beng". Many open-source font files are still written for the old specification. This is supported by mPDF, although v2 fonts give better results.
+
+Note: mPDF does not support Graphite or AAT font features.
+
+
+Configuring new fonts for mPDF 6
+To add a font, first copy the font file to the /ttfonts/ folder.
+Then edit config_fonts.php to add. See the manual for details if you are not already familiar with this.
+If you wish to use this font with autoLangToFont, you also need to edit config_lang2fonts.php
+
+
+Setting OTL use at runtime
+mPDF caches some font information in the /ttfontdata/ folder to improve performance. This is regenerated if you change the value of useOTL for a font.
+There may be circumstances when you wish to use OTL features with different scripts depending on the document e.g. for everyday use you may want to disable OTL for FreeSerif to save processing time, but on occasions use OTL for Indic and/or Arabic scripts. The recommended way to do this is to create 2 instances of the font e.g. in config_fonts.php:
+
+ "freeserif" => array(
+ \'R\' => "FreeSerif.ttf",
+ \'B\' => "FreeSerifBold.ttf",
+ \'I\' => "FreeSerifItalic.ttf",
+ \'BI\' => "FreeSerifBoldItalic.ttf",
+ \'useOTL\' => 0x00,
+ ),
+ "freeserif2" => array(
+ \'R\' => "FreeSerif.ttf",
+ \'B\' => "FreeSerifBold.ttf",
+ \'I\' => "FreeSerifItalic.ttf",
+ \'BI\' => "FreeSerifBoldItalic.ttf",
+ \'useOTL\' => 0xFF, /* Uses OTL for all scripts */
+ \'useKashida\' => 75,
+ ),
+
+You could then either use this second font name in your stylesheets e.g.
+
+<p style="font-family:freeserif2;">Hallo World (in Arabic)</p>
+
+
+or, you could use font translation e.g.
+
+$mpdf->fonttrans[\'freeserif\'] = \'freeserif2\';
+
+
+
+
+
+Page breaking
+
+Types of page break
+
+The handling of borders and padding at page breaks has been updated. mPDF has three types of page breaks:
+1) "slice" - no border and no padding are inserted at a break. The effect is as though the element were rendered with no breaks present, and then sliced by the breaks afterward
+
+2) "cloneall" - each page fragment is independently wrapped with the borders and padding of all open elements.
+
+3) "clonebycss" - open elements which have the (custom) CSS property "box-decoration-break" set to "clone" are independently wrapped with their border and padding.
+
+The difference between 2) and 3) is illustrated by this example:
+
+
+<style>
+div { border: 1px solid black; padding: 1em; }
+.level1 { box-decoration-break: slice; }
+.level2 { box-decoration-break: clone; }
+.level3 { box-decoration-break: clone; }
+</style>
+
+
+<div class="level1">
+ <div class="level2">
+ <div class="level3">
+ <p style="page-break-after:always">...</p>
+ <p>....</p>
+ </div>
+ </div>
+</div>
+
+
+At the forced pagebreak which occurs after the P element:
+
+If the page break type is "cloneall" - the three DIV elements will all be closed, by drawing the border and padding for each at the end of the page; the three DIV elements will be re-opened, drawing the borders and padding, at the top of the next page.
+
+If the page break type is "clonebycss" - starting from the innermost element (div.level3) the DIV elements will have a border and padding at the end of the page if "box-decoration-break" is clone. In this case level2 and level 3 will be closed/cloned and level 1 will be sliced; the opposite will occur at the top of the next page.
+
+Control of page breaks
+
+
+
+| Automatic page breaks (in flow of text) |
+Always "slice" |
+
+
+
+| <tocpagebreak> |
+Always "cloneall" |
+
+
+
+| <formfeed> |
+Always "slice" |
+
+
+
+| If using columns |
+Always "cloneall" |
+
+
+
+| Page break forced by change of @page selector |
+Always "cloneall" |
+
+
+
+| <pagebreak> |
+Always "cloneall" if a change in page size or margins is specified.
+Otherwise page break type is determined by value of configurable variable: $this->defaultPagebreakType. Default is "cloneall".
+Default can be overridden by attribute "page-break-type" e.g. <pagebreak page-break-type="clonebycss" />
+ |
+
+
+
+Page breaks forced by:
+page-break-before or page-break-after
+ |
+
+Page break type determined by value of configurable variable: $this->defaultPagebreakType. Default is "cloneall".
+ |
+
+
+
+
+
+Notes on page breaking
+"box-decoration-break: slice | clone" was proposed for CSS3 in http://www.w3.org/TR/2012/CR-css3-background-20120417/#the-box-decoration-break but it appears that it may be withdrawn. Default is "slice"; it is not inherited.
+"page-break-before" is not supported on <table>.
+"page-break-before|after" is ignored if set on block elements inside a table.
+mPDF functions e.g. AddPage() are not affected by the changes in mPDF 6.
+Background images and gradients are not sliced.
+$this->restoreBlockPagebreaks in config.php is now redundant.
+
+
+
+
+Line breaking
+The algorithm for determining automatic line breaks has been completely rewritten, ignoring inline tags (except for some cases of CJK line-breaking, and autohyphenation).
+
+Line breaks will be allowed at:
+
+- Spaces U+0020
+- Word break U+200B
+- Hyphen-minus U+002D when CSS hyphens set to "manual" or "auto", except when in a URL, or when following character is a > or numeral
+- Hard hyphen U+2010 when CSS hyphens set to "manual" or "auto"
+- Soft hyphen U+00AD "" when CSS hyphens set to "manual" or "auto"
+- Automatic hyphenation when CSS hyphens set to "auto"
+- Between CJK characters, except CJK numerals, before "CJK-following" or after "CJK-leading" characters
+
+
+See also "Dictionary Line breaking" above.
+
+
+
+
+
+Line-height and Text Baseline
+
+Using font metrics
+
+mPDF 6 can (optionally) use font metrics derived from each font file to:
+
+- Determine the height of a line when line-height is set to \'normal\'
+- Determine the glyph baseline (previously a fixed value)
+
+
+Options are set by configurable variables in the config.php file:
+
+Default settings in mPDF versions 6 - recommended especially for complex scripts with marks used above or below characters:
+
+- $this->useFixedNormalLineHeight = false;
+- $this->useFixedTextBaseline = false;
+- $this->adjustFontDescLineheight = 1.14;
+
+
+
+Settings to be backwards compatible with mPDF versions < 6:
+
+- $this->useFixedNormalLineHeight = true;
+- $this->useFixedTextBaseline = true;
+- $this->normalLineheight = 1.33;
+
+
+Examples
+
+Using the font metrics will give approximately the same result as the fixed value for many standard Latin script fonts e.g. DejaVu Sans Condensed:
+
+line-height: normal; based on font metrics
+
+line-height: normal; using fixed value
+
+However, for some fonts the normal line-height using font metrics will be significantly taller, to account for the design of the font glyphs e.g. Khmer font:
+
+line-height: normal; based on font metrics;
+ង្រ្គ ង្គ្រ ន្រ្តី ន្រ្តី ង្គ្រោះ យុវជន
+
+line-height: normal; using fixed value;
+ង្រ្គ ង្គ្រ ន្រ្តី ន្រ្តី ង្គ្រោះ យុវជន
+
+
+For more information on how complex normal lineheights are, see Eric Meyers\' website: http://meyerweb.com/eric/thoughts/2008/05/06/line-height-abnormal/ and
+http://typophile.com/node/13081
+
+
+CSS control of line-height
+
+There are also new controls for line-height using draft CSS3 properties. These can be set on all block level elements (P, DIV etc) and tables (TABLE/TD/TH).
+line-stacking-strategy = inline-line-height | block-line-height | max-height | grid-height
+
+- inline-line-height - [default] lineheight is initially calculated from the block-level font[-size]; the height is expanded by any inline content, including the calculated lineheight of that inline content;
+- block-line-height - lineheight is fixed as the lineheight of the block-level font[-size];
+- max-height - lineheight is initially calculated from the block-level font; the height is expanded by any inline content, EXCLUDING the calculated lineheight of that inline content;
+- grid-height - lineheight is initially calculated from the block-level font; the height is expanded - AS MULTIPLES OF INITIAL LINEHEIGHT - by any inline content, EXCLUDING the calculated lineheight of that inline content;
+
+Note: XSL has a similar property with the same name, which uses different but equivalent values: line-height instead of inline-line-height, font-height instead of block-line-height. It also uses max-height. The value grid-height is new to the CSS3 property.
+
+Examples
+
+line-height: normal; DejaVu Sans Condensed
+
+line-height: normal; 16pt font-size  with line-stacking-strategy: inline-line-height
+
+line-height: normal; 16pt font-size  with line-stacking-strategy: block-line-height
+
+line-height: normal; 16pt font-size  with line-stacking-strategy: max-height
+
+line-height: normal; 16pt font-size  with line-stacking-strategy: grid-height
+
+
+
+
+line-stacking-shift = consider-shifts | disregard-shifts
+This property determines whether to include or disregard the adjusted top- and bottom-edge of any characters that have a baseline-shift (e.g. superscript) when calculating lineheight.
+Note: XSL has a similar property with a different name: line-height-shift-adjustment which uses the same values.
+
+Examples
+
+In the table below, the line-height is set to 1em throughout the table; line-stacking-shift is set as \'disregard-shifts\' in the first row, and has default setting (consider-shifts) in the second row.
+
+
+
+Normal text DejaVu Sans[53] Condensed
+Normal text DejaVu Sans[53] Condensed
+Normal text DejaVu Sans[53] Condensed
+Normal text DejaVu Sans[53] Condensed
+Normal text DejaVu Sans[53] Condensed
+Normal text DejaVu Sans[53] Condensed
+ |
+
+Normal text DejaVu Sans Condensed
+Normal text DejaVu Sans Condensed
+Normal text DejaVu Sans Condensed
+Normal text DejaVu Sans Condensed
+Normal text DejaVu Sans Condensed
+Normal text DejaVu Sans Condensed
+ |
+
+
+
+Normal text DejaVu Sans[53] Condensed
+Normal text DejaVu Sans[53] Condensed
+Normal text DejaVu Sans[53] Condensed
+Normal text DejaVu Sans[53] Condensed
+Normal text DejaVu Sans[53] Condensed
+Normal text DejaVu Sans[53] Condensed
+ |
+
+Normal text DejaVu Sans Condensed
+Normal text DejaVu Sans Condensed
+Normal text DejaVu Sans Condensed
+Normal text DejaVu Sans Condensed
+Normal text DejaVu Sans Condensed
+Normal text DejaVu Sans Condensed
+ |
+
+
+
+
+
+For more details see the CSS3 draft specification.
+
+Note for Advanced users
+
+There are actually three possible metrics that can be used in a TrueType font file. The differences are summed up quite well in this article at http://typophile.com/node/13081. mPDF will by default use the usWinAscent and usWinDescent values to determine a \'normal\' line-height, with two variations:
+
+
+- if either the usWinAscent or usWinDescent are greater than the font bounding box (yMin yMax), then the values are reduced to equal the yMin/yMax values.
+NB this works as a fix with Myanmar Text (Windows 8 version) to give a line-height normal that is equivalent to that produced in browsers.
+- if the USE_TYPO_METRICS bit is set on fsSelection (OS/2 table), this is telling the font to use the sTypo values and not the usWinAscent values.
+NB this works as a fix with Cambria Math font to give a normal line-height; at present, this is the only font I have found with this bit set;
+although note that MS WordPad and Windows FireFox browser use the big line-height from usWinAscent, whilst MS Word 2007 observes the fSelection value.
+
+
+You can change the font metrics used by mPDF, by editing the defined constant (_FONT_DESCRIPTOR) at the top of the mpdf.php file:
+
+- \'winTypo\' uses sTypoAscender etc from the OS/2 table and is the one officially recommended - BUT
+- \'win\' use usWinAscent etc from OS/2 and in practice seems to be used most commonly in Windows environment; this is the default in mPDF;
+- \'mac\' uses Ascender etc from hhea table, and may be used to give results consistent with a Mac/OSX environment.
+
+
+Finally, you can override values for Ascent, Descent and Leading for any specific font, by setting values in config_font.php e.g.
+
+ "cambriamath" => array(
+ \'R\' => "cambria.ttc",
+ \'useOTL\' => 0xFF,
+ \'TTCfontID\' => array(
+ \'R\' => 2,
+ ),
+ \'Ascent\' => 950,
+ \'Descent\' => -222,
+ \'Leading\' => 0,
+ ),
+
+
+Note - The same values are used for all styles of the font-family. Descent values should be negative. All values should be given using a 1000 units per em scale, regardless of the UnitsPerEm used in the font design.
+
+Notes
+Remember that line-height for a TABLE has a default value (1.2) set in the config.php default CSS. This is left in for backwards compatability. You can change this value to \'normal\' for results consistent with most browsers.
+Line-height in a <textarea> is fixed and defined in classes/mpdfform.php (= 1.2)
+Details of the font metrics can be seen by inspecting the temporary font files e.g. /ttfontdata/[fontname].mtx.php.
+
+
+
+
+
+ Indexes
+Index style and layout
+Indexes have been completely rewritten for mPDF 6, and are not backwards compatible:
+
+- Reference() is now removed - use IndexEntry() instead.
+- CreateReference() and CreateIndex() are both removed - replaced by: InsertIndex() [or recommend <indexinsert>] cf. below.
+- <indexinsert> and InsertIndex() no longer set styles - appearance must be controlled using CSS, even if using function InsertIndex().
+- <indexinsert> and InsertIndex() no longer control columns - these must be specified separately.
+
+
+When an Index is inserted in the PDF document, the Index is now generated (internally) as HTML code in the following format:
+
+
+<div class="mpdf_index_main">
+<div class="mpdf_index_letter">A</div>
+<div class="mpdf_index_entry">Aardvark<a class="mpdf_index_link" href="#page37">37</a>
+</div>
+...
+</div>
+
+
+CSS stylesheets can thus be used to control the layout of the Index e.g.:
+
+/* For Index */
+div.mpdf_index_main {
+ line-height: normal;
+ font-family: sans-serif;
+}
+div.mpdf_index_letter {
+ line-height: normal;
+ font-family: sans-serif;
+ font-size: 1.8em;
+ font-weight: bold;
+ text-transform: uppercase;
+ page-break-after: avoid;
+ margin-top: 0.3em;
+ margin-collapse: collapse;
+}
+div.mpdf_index_entry {
+ line-height: normal;
+ font-family: sans-serif;
+ text-indent: -1.5em;
+}
+a.mpdf_index_link {
+ color: #000000;
+ text-decoration: none;
+}
+
+
+A default stylesheet for Indexes is included in mpdf.css (see note later for more information).
+
+
+
+Index Collation
+In order to generate an Index with non-ASCII characters, entries need to be sorted accordingly (collation), and non-ASCII characters should map to the appropriate Dividing letter e.g.:
+
+ A
+ Alonso, Fernando
+ Ãlvarez, Isaac
+ Arroyo Molino, David
+ B
+ BenÃtez, Carlos
+
+
+Entries in an Index can now be sorted using any of the Locale values available on your system. Set it using the "collation" property/parameter e.g.:
+
+<indexinsert usedivletters="on" links="off" collation="es_ES.utf8" collation-group="Spanish_Spain" />
+- or -
+$mpdf->InsertIndex(true, false, "es_ES.utf8", "Spanish_Spain");
+
+
+NB You should always choose a UTF-8 collation, even when you are using Core fonts or e.g. charset-in=win-1252, because mPDF handles all text internally as UTF-8 encoded.
+
+You can see which Locales are available on your (Unix) system: <?php system(\'locale -a\') ?>
+
+Note: Index collation will probably not work on Windows servers because of the problems setting Locales under Windows.
+
+If you have set your index to use Dividing letters, you can also determine how letters are grouped under
+a dividing letter. In the example index above, we want à to be grouped under the letter a/A. Set the "collation-group" using:
+
+<indexinsert usedivletters="on" links="off" collation="es_ES.utf8" collation-group="Spanish_Spain" />
+- or -
+$mpdf->InsertIndex(true, false, "es_ES.utf8", "Spanish_Spain");
+
+Values should be selected from the available file names in folder /collations/.
+
+Note: This will not affect the overall order of entries, which is determined by the value of "collation".
+
+Note: The groupings do not always match the order set by locale. This is because the data for collations has come from different sources. The files in /collations/ can be edited.
+The array consists of [index]: unicode decimal value of character => unicode decimal value of character to group under:
+e.g. Ã [A tilde] (U+00C3) (decimal 195) => a (U+0061) (decimal 97). The target character should always be the lowercase form.
+
+Non-ASCII chcracters in Index entries
+Note: htmlspecials_encode should be used to encode the text of content in <indexentry> - although not when using $mpdf->IndexEntry().
+
+Columns
+Columns are no longer specified as part of the <indexinsert>, so a typical 2-column index might be produced by:
+
+<pagebreak type="next-odd" />
+<h2>Index</h2>
+<columns column-count="2" column-gap="5" />
+<indexinsert usedivletters="on" links="on" collation="en_US.utf8" collationgroup="English_United_States" />
+<columns column-count="1" />
+
+
+Index Sub-entries
+Index entries can contain sub-entries, separated by colons e.g.
+<indexentry content="Mammals:elephants" />
+
+A shorthand way of displaying subentries is set by default, which suppresses the main entry if > 1 subEntry. It can be disabled/enabled using the configurable variable $this->indexUseSubentries in config.php.
+
+This is the default appearance, with $this->indexUseSubentries = false; -
+
+Mammals 73
+- elephants 142
+- humans 173
+Marsupials
+- kangaroos 75
+- wombats 86
+
+
+Index entries can also include simple mark-up tags and/or more than one colon e.g:
+<indexentry content="Mammals:<b>elephants</b>: breeding" />
+which appears as:
+
+Mammals
+- elephants: breeding 15
+
+
+This is the appearance with $this->indexUseSubentries = false; -
+
+Mammals 73
+Mammals, elephants 142
+Mammals, elephants: breeding 15
+Mammals, humans 173
+Marsupials, kangaroos 75
+Marsupials, wombats 86
+
+
+Customised appearance
+Several variables set at beginning of function InsertIndex() in mpdf.php which could be changed to alter appearance of Index.
+ e.g. spacer, and joiner characters.
+
+
+
+
+Lists
+
+Lists are now handled as for other block level tags, so you can apply any CSS properties usable on blocks (e.g. border, background, padding) to UL/OL and LI tags.
+
+CSS property "list-style" is now handled properly as a shorthand, and there is full support for "list-style-image", "list-style-type", and "list-style-position".
+
+
+There are two modes for lists in mPDF 6: "mpdf" mode and "browser" mode. Mode is set using the configurable variable $this->list_auto_mode in config.php
+
+1) Browser mode gives the same display as most browsers. In this mode, the default list indentation is set by padding "0 auto" in the default CSS in config.php. "auto" equates to the value of $this->list_indent_default in config.php - this is a "magic" value for padding, which is applied to either left or right depending on directionality of the list (rtl/ltr).
+
+
+2) mPDF mode gives results compatible with previous versions of mPDF. In this mode, the indentation is calculated differently: the outside edge of the list item is considered to be the outside edge of the bullet or number. For numbered lists, mPDF calculates the width of the largest number and this width is used to set the outside edge. The default list indentation of "auto" in mPDF mode is set by $this->list_indent_default_mpdf. This value is added to the automatic calculated indentation. For backwards compatibility, $this->list_indent_first_level = 0; can be used to prevent any indentation of the first list level.
+
+The automatic indentation only works for bullets or numbered lists, and is ignored if "list-style-position: inside" is set, or images are used for markers.
+
+Browser mode is set as the default - for backwards compatibility, change this to "mpdf".
+
+List top & bottom margins
+The default in browsers is to add a top and bottom margin to the outermost list only. This can be defined using CSS as:
+
+ul, ol { margin-top: 0.83em; margin-bottom: 0.83em; }
+ul ul, ul ol, ol ul, ol ol { margin-top: 0; margin-bottom: 0; }
+
+This style is included in file mpdf.css (see later).
+Previous versions of mPDF always added a top and bottom margin to the outermost list, (but no variation from this was possible). mPDF 6 is therefore backwards compatible re. the margins.
+[NB The CSS styles are included in mpdf.css, because the defaultCSS values set in config.php only works on basic elements, and cannot use selectors such as "ol ol".]
+
+Other new configurable variables
+
+
+Configurable variables are used to define size and offset for list bullets (i.e. disc, circle or square).
+The values can be any valid CSS size.
+To specify a fixed bullet size and offset to give a similar appearance to most browsers, the default is set as:
+
+- $this->list_marker_offset = \'5.5pt\';
+- $this->list_symbol_size = \'3.6pt\';
+
+To specify size and offset proportional to the list item\'s font size (compatible with previous versions of mPDF), use:
+
+- $this->list_marker_offset = \'0.45em\';
+- $this->list_symbol_size = \'0.31em\';
+
+
+
+Notes on Lists
+The attribute type="" is case sensitive (whereas it is case insensitive in CSS). This allows the use of shorthand versions e.g. type="A" for uppercase alpha-numeric.
+"list-style-type" is only inherited to child LI (not to child UL/OL); list-style-image and -position are fully inherited.
+Lists in tables remain basic, as block-level elements are not supported inside tables.
+Properties like text-align:justify will now be inherited from surrounding elements, which will change the appearance of lists designed with earlier versions of mPDF.
+The attribute start="3" (integer) works for "OL"; it is an official (though depracated) HTML attribute.
+List bullets (type = disc, circle or square) are now drawn rather than using font glyphs, for better consistency.
+
+
+
+List examples
+
+This demonstrates the appearance when list_auto_mode is set to \'mpdf\', compatible with previous mPDF versions. Indentation is set to zero (list_indent_default_mpdf). Note the top and bottom margin on the first list level only.
+
+- First item
+- Second item
+
+- Next list level
+- Second item
+
+
+
+
+
+This demonstrates the same default settings, but list numbering is set to start at 32. Note how the indentation is adjusted to fit the maximum width of the numbering.
+
+- First item
+- Second item
+
+- Next list level
+- Second item
+
+
+
+
+
+This demonstrates the appearance when list_auto_mode is set to \'browser\', compatible with browsers. Indentation is set to 40px (list_indent_default)
+
+- First item
+- Second item
+
+- Next list level
+- Second item
+
+
+
+
+
+This demonstrates the same as the previous example, but list numbering is set to start at 32. Note that the default indentation remains fixed at 40px (list_indent_default)
+
+- First item
+- Second item
+
+- Next list level
+- Second item
+
+
+
+
+
+This demonstrates control of the list-style-type, list-style-position and list-style-image.
+
+- First item in list
+- Second item
+- List style set as \'disc\'
+- List style set as \'none\'
+- Using an image.
+- List-style-position: inside.
+- User defined list bullet
+
+
+
+
+Image transform
+
+The CSS property "transform" is supported on images (only). All transform functions are supported except matrix() i.e. translate(), translateX(), translateY(), skew(), skewX(), skewY(), scale(), scaleX(), scaleY(), and rotate()
+
+Transforms cannot be used when using columns or Keep-with-table (use_kwt).
+The CSS property background-color is now supported on images.
+
+In the following examples, note the difference between transform (which is applied after layout) and image-orientation (which is applied before layout):
+
+Hallo world
+ 
+Hallo world
+
+
+Hallo world
+ 
+Hallo world
+
+
+Hallo world
+ 
+Hallo world
+
+
+Hallo world
+ 
+Hallo world (image-orientation)
+
+
+
+CSS overline
+The CSS property "text-decoration: overline" is supported. Note that since mPDF 5.7.3 text-decoration use the parent inline block baseline/fontsize/color for child inline elements, and allows nested use of these values and superscript/subscript.
+1st place
+ and compare with
+1st
+
+He won 1st place
+
+
+
+
+Headers and Footers
+Headers and Footers are all now written internally as HTMLheaders/footers. The use of non-HTML headers and footers is depracated, but remains supported. Non-HTML headers and footers are converted in mPDF to HTML equivalents.
+
+Layout: This may mean that there will be a change in the resulting PDF. The main change is that an HTML table is created with three cells for left, right and middle; if you had a very long Left header item, it will not overwrite the center item, but it may wrap center onto 2 lines.
+
+Naming: Default non-HTML headers will not clash with HTML headers, but named non-HTML headers WILL clash with (and overwrite) HTML headers of the same (equivalent) name e.g. html_MyFooter == MyFooter (non-HTML).
+
+Aliases: {nb} or {nbpg} now only work in Headers or Footers, and not in the main text. {PAGENO} and {DATE ...} continue to only work in Headers or Footers.
+
+ToC: Can now set the pagenumbering/style/reset/suppress for the ToC separately (see section on ToC).
+
+The following are all depracated (but still supported) in favour of HTMLheader/footers:
+
+- SetHeader()
+- SetFooter()
+- <pageheader>
+- <pagefooter>
+- DefHeaderByName()
+- DefFooterByName()
+- <setpageheader>
+- <setpagefooter>
+- SetHeaderByName()
+- SetFooterByName()
+
+
+If document direction is RTL (body dir=rtl, html dir=rtl), then you need to set directionality before setting non-HTML headers e.g.
+
+ $mpdf = new mPDF();
+ $mpdf->SetDirectionality(\'rtl\'); // i.e. add this in
+ $mpdf->SetHeader($h);
+ $mpdf->SetFooter($f);
+ $mpdf->WriteHTML(\'<body dir="rtl">...\');
+
+
+
+
+
+Table of Contents (ToC)
+Page numbering can now be applied and controlled for the pages containing a ToC.
+
+There are three new parameters to control pagenumbering in the ToC: toc-resetpagenum, toc-pagenumstyle, and toc-suppress.
+These are set as attributes in <tocpagebreak> or as the last 3 parameters in TOCpagebreak();
+they set the pagenumbering and pagenumbering style for the ToC, and whether to suppress pagenumbers in ToC.
+
+The default setting for all is to continue pagenumbering and pagenumstyle (and suppression) from pages preceding the ToC.
+
+Note: Page numbering will always reset following a ToC. By default it will set it to 1, unless a value for resetpagenum is specified in TOCpagebreak or <tocpagebreak>.
+
+Backwards compatibility: page numbers are no longer suppressed by default in ToC.
+
+Although "suppress" and "toc-suppress" are supported, the recommended way to control whether page numbering appears is by using different headers and footers for each section.
+
+Note: If you have 2 ToCs immediately following each other, and wish to use pagenumstyle or suppress to control the following text, then you need to set those values on both of the <tocpagebreak> elements.
+
+The default CSS styles for ToCs and Indexes are now set in mpdf.css (see later).
+
+See notes later on page numbering.
+
+
+
+
+Other changes from mPDF 5
+
+Setting up mPDF 6
+mPDF 6 has changed significantly from earlier version and it is recommended that a fresh install is used. You may wish to copy your previous config_* files and use them to update the new config files.
+
+config_fonts.php - values of "indic" and "unAglyphs" from previous versions are now redundant.
+
+config_lang2fonts.php - this is similar to the previous config_cp.php file; note however that $unifont (NOT $unifonts) must be only one font (not a comma-separated list as before).
+
+Included fonts - the Indic fonts e.g. ind_bn_001.ttf are no longer required (nor do they work properly with mPDF 6).
+
+useLang - this configurable variable, which used to be true by default, is now redundant. You may need to set: $mpdf->autoLangToFont = true; for the same results.
+
+SetAutoFont() - is now redundant. You may need to set: $mpdf->autoScriptToLang = true; for the same results.
+
+Indexes - have been largely redefined. See the section above.
+
+Lists - have been rewritten. See the section above.
+
+Headers and Footers - have been rewritten. See the section above.
+
+
+A number of old depracated aliases will no longer be supported. Warning errors have been added to prompt you to change to the updated form:
+
+- $mpdf->useOddEven - should now use - $mpdf->mirrorMargins
+- $mpdf->useSubstitutionsMB - should now use - $mpdf->useSubstitutions
+- $mpdf->AliasNbPg - should now use - $mpdf->aliasNbPg
+- $mpdf->AliasNbPgGp - should now use - $mpdf->aliasNbPgGp
+- $mpdf->BiDirectional - should now use - $mpdf->biDirectional
+- $mpdf->Anchor2Bookmark - should now use - $mpdf->anchor2Bookmark
+- $mpdf->KeepColumns - should now use - $mpdf->keepColumns
+- $mpdf->UnvalidatedText - should now use - $mpdf->watermarkText
+- $mpdf->TopicIsUnvalidated - should now use - $mpdf->showWatermarkText
+- $mpdf->Reference - should now use - $mpdf->IndexEntry
+
+
+The following functions have been removed:
+
+- setUnvalidatedText - should now use - SetWatermarkText()
+- AddPages - should now use - AddPage() or HTML code methods
+- startPageNums
+- CreateReference and CreateIndex - cf. Index section above
+
+
+Default style sheet
+A new mpdf.css file includes defaults for LISTS top/bottom margins, and also examples for Indexes and ToCs. This now acts like a normal CSS file, including cascading selectors i.e. not just main tags. This is always read (if present), so acts as a secondary default CSS, but one which allows selectors. Styles added to this act like a user stylesheet when considering precedence e.g. cellSpacing and border-spacing.
+
+
+Direct writing methods and OTL
+WriteText() WriteCell() Watermark() AutoSizeText() and ShadedBox() DO support complex scripts and right-to-left text (RTL).
+Write() does NOT support complex scripts or RTL (NB this is a change - Write() used to support RTL).
+CircularText() does NOT support complex scripts or RTL.
+MultiCell() DOES support complex scripts and RTL, but complex-script line-breaking MAY NOT be accurate.
+MultiCell() does not support kerning and justification. NB This includes <textarea> in forms which uses MultiCell() internally.
+<select> form objects also do NOT support kerning.
+
+
+Page numbering
+Page numbering i.e. by including {PAGENO} or {nbpg} in a header/footer, can use any of the number types as used for list-style e.g.
+
+<pagebreak pagenumstyle="arabic-indic">
+Short codes are recognised for the 5 most common:
+
+- "1" - decimal
+- "A" = upper-latin or upper-alpha
+- "a" = lower-latin or lower-alpha
+- "I" = upper-roman
+- "i" = lower-roman
+
+or any of the following:
+arabic-indic, hebrew, bengali, devanagari, gujarati, gurmukhi, kannada, malayalam, oriya, persian, tamil, telugu, thai, urdu, cambodian, khmer, lao, cjk-decimal
+
+
+Note: A suitable font must be used in the header/footer in order to display the numbers in the selected script.
+
+You can now set the pagenumberstyle from the beginning of the document by changing the configurable variable:
+
+$this->defaultPageNumStyle = "arabic-indic"; // in config.php
+$mpdf->defaultPageNumStyle = "arabic-indic"; // at runtime
+
+
+Other Minor changes in mPDF 6
+\'hebrew\', \'khmer\', \'cambodian\', \'lao\', and \'cjk-decimal\' are recognised as values for "list-style-type" in numbered lists.
+
+CSS "text-outline" is now supported on TD/TH tags
+
+Text wrapping in tables has been improved when using CJK scripts (chinese-japanese-korean).
+
+Text underline and strikethrough can be used together: Hallo world. Either <u><s>...</s></u> or <span style="text-decoration:underline line-through;">...</span> can be used
+
+Added support for style="opacity:0.6;" in SVG - equivalent to: style="fill-opacity:0.6; stroke-opacity: 0.6;"
+Added support for opacity="0.6" (as attribute) in SVG - previously only supported fill-opacity="0.6" stroke-opacity="0.6"
+
+CSS position:absolute or fixed - rotate extended now to include rotate: 180; (previously just 90 or -90)
+
+The default value of $this->keep_table_proportions = true; in config.php has been changed (see effect on Example 6 - nested table in top right cell).
+
+Limited support has been added for SVG fonts embedded in SVG images (but not using @font-face rules) - see the separate Images demo file.
+
+When using columns, the top margin is now collapsed at top of every column (not just first column of page).
+
+The way mPDF handles optional end tags has been updated to be consistent with the HTML5 specification - previously not well defined for HTML4.
+
+Changes to the way lists are handled means that text-align:justify may be inherited by lists from surrounding block elements (which did not happen previously). See LISTS above for more information.
+
+
+
+Backwards Compatibility
+For maximum backwards comaptibility with older versions of mPDF, change the following configurable variables in the config.php file:
+
+
+
+
|
+mPDF 6.0 Default (Browser compatible)
|
+Backwards Compatible |
+
+
+
+
+| Normal Line-height |
+
+ $this->useFixedNormalLineHeight = false; $this->useFixedTextBaseline = false; $this->adjustFontDescLineheight = 1.14;
+ |
+$this->useFixedNormalLineHeight = true; $this->useFixedTextBaseline = true; $this->normalLineheight = 1.33; |
+
+
+| Lists |
+
+ $this->list_auto_mode = \'browser\';
+$this->list_marker_offset = \'5.5pt\'; $this->list_symbol_size = \'3.6pt\'; |
+
+ $this->list_auto_mode = \'mpdf\';
+$this->list_marker_offset = \'0.45em\'; $this->list_symbol_size = \'0.31em\';
+ |
+
+
+
+
+
+
+More Information
+For more information, see:
+
+
+
+
+Font Information
+
+The following fonts are included with mPDF 6:
+
+
+
+
+| Font(s) |
+Download URL |
+Copyright / License
|
+Coverage |
+
+
+
+
+|
+ DejaVuSans
+DejaVuSansCondensed
+DejaVuSerif
+DejaVuSerifCondensed
+DejaVuSansMono
+ |
+http://dejavu-fonts.org |
+
+ © Bitstream
+http://dejavu-fonts.org/wiki/License
+ |
+[Numerous] |
+
+
+|
+ FreeSans
+FreeSerif
+FreeMono
+ |
+http://www.gnu.org/software/freefont/ |
+
+ GNU GPL v3
+ |
+
+ [Numerous incl. Indic]
+ |
+
+
+| Quivira |
+http://www.quivira-font.com/ |
+
+ free for any use
+ |
+
+ Coptic
+Buhid
+Tagalog
+Tagbanwa
+Lisu
+ |
+
+
+| Abyssinica SIL |
+http://www.sil.org/resources/software_fonts/abyssinica-sil |
+SIL Open Font License |
+Ethiopic |
+
+
+| XBRiyaz |
+
+ http://www.redlers.com/downloadfont.html
+(XW Zar fonts)
+http://wiki.irmug.org/index.php/XWZar
+ |
+SIL Open Font License |
+Arabic |
+
+
+Taamey David CLM
|
+http://opensiddur.org/tools/fonts/ |
+GNU GPL 2
|
+Hebrew |
+
+
+|
+ Estrangelo Edessa
+ |
+
+ http://www.bethmardutho.org/index.php/resources/fonts.html
+(SyrCOMEdessa.otf)
+ |
+Adapted licence (free to use/share)
|
+Syriac |
+
+
+| Aegean |
+http://users.teilar.gr/~g1951d/ |
+free for any use |
+
+ Carian
+Lycian
+Lydian
+Phoenecian
+Ugaritic
+Linear B
+Old Italic
+ |
+
+
+| Jomolhari |
+https://sites.google.com/site/chrisfynn2/home/fonts/jomolhari |
+SIL Open Font License |
+Tibetan |
+
+
+| Lohitkannada |
+https://fedorahosted.org/lohit/
|
+SIL Open Font License
|
+Kannada |
+
+
+| Kaputaunicode |
+
+ http://www.kaputa.com/slword/kaputaunicode.htm
+http://www.locallanguages.lk/sinhala_unicode_converters
+ |
+
+ Free
+Sri Lanka Web Community Center
+ |
+Sinhala |
+
+
+| Pothana2000 |
+https://fedoraproject.org/wiki/Pothana2000_fonts |
+GNU GPL v2+ |
+Telugu |
+
+
+| Lateef |
+http://www.sil.org/resources/software_fonts/lateef |
+SIL Open Font License |
+Sindhi |
+
+
+| Khmeros |
+
+ http://www.khmeros.info/en/fonts
+(http://www.cambodia.org/fonts/)
+ |
+LGPL Licence
|
+Khmer |
+
+
+| Dhyana |
+
+ Google Fonts
+http://www.google.com/fonts/earlyaccess
+ |
+SIL Open Font License
|
+Lao |
+
+
+| Tharlon |
+
+ Google Fonts
+http://code.google.com/p/tharlon-font/ |
+SIL Open Font License |
+
+ Myanmar
+Tai Le
+ |
+
+
+Padauk Book
|
+http://www.sil.org/resources/software_fonts/padauk |
+SIL Open Font License |
+
+ Myanmar
+ |
+
+
+| Ayar fonts |
+http://eng.ayarunicodegroup.org/ |
+SIL Open Font License
|
+Myanmar |
+
+
+| ZawgyiOne |
+http://code.google.com/p/zawgyi/wiki/MyanmarFontDownload |
+
+ Freely available.
+No licence information available
+ |
+
+ Myanmar
+ |
+
+
+|
+ Garuda
+ |
+http://www.hawaii.edu/thai/thaifonts/ |
+
+ Freely available.
+No licence information available |
+Thai |
+
+
+| Sundanese Unicode |
+http://sabilulungan.org/aksara/ |
+GNU GPL
|
+Sundanese |
+
+
+| Tai Heritage Pro |
+http://www.sil.org/resources/software_fonts/tai-heritage-pro |
+SIL Open Font License |
+Tai Viet |
+
+
+|
+ Sun-ExtA
+Sun-ExtB
+ |
+http://www.alanwood.net/downloads/index.html |
+Freeware (Beijing ZhongYi Electronics Co) |
+
+ Chinese
+Japanese
+Runic
+ |
+
+
+| Unbatang |
+http://kldp.net/projects/unfonts/download |
+GNU GPL
|
+Korean |
+
+
+|
+ Aboriginal Sans
+ |
+http://www.languagegeek.com/font/fontdownload.html
|
+
+ GNU GPL 3
+
+ |
+
+ Cree
+Canadian Aboriginal
+Inuktuit
+ |
+
+
+| MPH 2B Damase |
+http://www.alanwood.net/downloads/index.html |
+(Public domain)
|
+
+ Glagolitic
+Shavian
+Osmanya
+Kharoshthi
+Deseret
+ |
+
+
+| Aegyptus |
+http://users.teilar.gr/~g1951d/ |
+free for any use |
+Egyptian Hieroglyphs |
+
+
+| Akkadian |
+http://users.teilar.gr/~g1951d/ |
+free for any use |
+Cuneiforn |
+
+
+| Eeyek Unicode |
+http://tabish.freeshell.org/eeyek/download.html |
+Freeware |
+Meetei Mayek |
+
+
+| Lannaalif |
+http://www.geocities.jp/simsheart_alif/taithamunicode.html |
+(Unclear) |
+Tai Tham |
+
+
+| Daibanna SIL Book |
+http://www.sil.org/resources/software_fonts/dai-banna-sil |
+SIL Open Font License |
+New Tai Lue |
+
+
+KFGQPC Uthman Taha Naskh
|
+http://fonts.qurancomplex.gov.sa/?page_id=42 |
+https://www.ohloh.net/licenses/KFGQPC |
+
+ Arabic
+(Koran/Quran)
+ |
+
+
+
+
+';
+//==============================================================
+$mpdf->h2bookmarks = array('H3'=>0, 'H4'=>1);
+$mpdf->defaultPageNumStyle = 'arabic-indic';
+
+$mpdf->autoLangToFont = true;
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+
+exit;
+
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example62_new_mPDF_v6-0_features Multilingual.php b/mpdf/examples/example62_new_mPDF_v6-0_features Multilingual.php
new file mode 100644
index 0000000..40d2bd2
--- /dev/null
+++ b/mpdf/examples/example62_new_mPDF_v6-0_features Multilingual.php
@@ -0,0 +1,156 @@
+
+
+
+
+- Assamese:
+ভালে আছো ধন্যবাদ৷ আৰু আপুনি?
+
+
- Bangla / Bengali:
+আমি কাঁচ খেতে পারি, তাতে আমার কোনো ক্ষতি হয় না।
+
+
- Gujarati:
+આ ભાઈ તેના રૂપિયા આપી દેશે
+
+
- Kannada:
+ನನಗೆ ಹಾನಿ ಆಗದೆ, ನಾನು ಗಜನ್ನು ತಿನಬಹುದು
+
+
- Hindi: मैं काँच खा सकता हूँ और मुझे उससे कोई चोट नहीं पहुंचती.
+
+
- Malayalam:
+എന്റെ പറക്കും-പേടകം നിറയെ വ്ളാങ്കുകളാണ്
+
+
- Marathi: मी काच खाऊ शकतो, मला ते दुखत नाही.
+
+
- Nepali: म काँच खान सक्छू र मलाई केहि नी हुन्न् ।
+
+
- Oriya:
+ଆପଣ ଇଂରାଜୀ କୁହନ୍ତି କି?
+
+
- Punjabi:
+ਮੇਰਾ ਹਵਰਕ੍ਰਾਫ਼ਤ ਨਾਂਗਾਂ ਨਾਲ਼ ਭਰਿਆ ਪਿਆ।
+
+
- Sanskrit: काचं शक्नोम्यत्तुम् । नोपहिनस्ति माम् ॥
+
+
- Sinhalese: මට වීදුරු කෑමට හැකියි. එයින් මට කිසි හානියක් සිදු නොවේ.
+
+
- Tamil: நான் கண்ணாடி சாப்பிடுவேன், அதனால் எனக்கு ஒரு கேடும் வராது.
+
+
- Telugu: నేను గాజు తినగలను మరియు అలా చేసినా నాకు ఏమి ఇబ్బంది లేదు
+
+
+
+
+- Arabic: أنا قادر على أكل الزجاج و هذا لا يؤلمني.
+
+
- Farsi / Persian: من می توانم بدونِ احساس درد شيشه بخورم.
+
+
- Urdu:
+میں کانچ کھا سکتا ہوں اور مجھے تکلیف نہیں ہوتی ۔
+
+
- Pashto: زه شيشه خوړلې شم، هغه ما نه خوږوي
+
+
- Turkish (Ottoman): جام ييه بلورم بڭا ضررى طوقونمز
+
+
- Sindhi (Arabic script):
+سنڌي ٻولي انڊو يورپي خاندان سان تعلق رکندڙ آريائي ٻولي آھي، جنھن تي ڪجھه دراوڙي اھڃاڻ پڻ موجود آهن
+
+
- Sindhi (Devanagari):
+सिन्धी ॿोली इण्डो यूरपी ख़ान्दान सां ताल्लुक़ु रखन्दड़ आर्याई ॿोली आहे
+
+
- Hausa (Ajami):
+إِنا إِىَ تَونَر غِلَاشِ كُمَ إِن غَمَا لَافِىَا
+
+
- Hebrew: אני יכול לאכול זכוכית וזה לא מזיק לי.
+
+
- Yiddish: איך קען עסן גלאָז און עס טוט מיר נישט װײ.
+
+
+
+
+
+- Vietnamese (quốc ngữ): Tôi có thể ăn thủy tinh mà không hại gì.
+
+
- Thai: ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ
+
+
- Khmer:
+ខ្ញុំអាចញុំកញ្ចក់បាន
+ដោយគ្មានបញ្ហារ
+
+
- Lao:
+ຂອ້ຍກິນແກ້ວໄດ້ໂດຍທີ່ມັນບໍ່ໄດ້ເຮັດໃຫ້ຂອ້ຍເຈັບ.
+
+
- Burmese:
+မီးမြေခွေးအား ဗမာ ဘာသာသို့ ပြန်ဆိုနေသည်မှာ နှစ်နှစ်ကျော်ကြာပြီ ဖြစ်ပါတယ
+
+
- Tibetan: ཤེལ་སྒོ་ཟ་ནས་ང་ན་གི་མ་རེད།
+
+
+
+
+
+- Anglo-Saxon (Runes):
+ᛁᚳ᛫ᛗᚨᚷ᛫ᚷᛚᚨᛋ᛫ᛖᚩᛏᚪᚾ᛫ᚩᚾᛞ᛫ᚻᛁᛏ᛫ᚾᛖ᛫ᚻᛖᚪᚱᛗᛁᚪᚧ᛫ᛗᛖ᛬
+
- Old Norse (Runes):
+ᛖᚴ ᚷᛖᛏ
+ᚷᛖᛏ ᛖᛏᛁ
+ᚧ ᚷᛚᛖᚱ ᛘᚾ
+ᚦᛖᛋᛋ ᚨᚧ ᚡᛖ
+ᚱᚧᚨ ᛋᚨᚱ
+
+
- Old Irish (Ogham): ᚛᚛ᚉᚑᚅᚔᚉᚉᚔᚋ ᚔᚈᚔ ᚍᚂᚐᚅᚑ ᚅᚔᚋᚌᚓᚅᚐ᚜
+
+
- English (Braille): ⠊⠀⠉⠁⠝⠀⠑⠁⠞⠀⠛⠇⠁⠎⠎⠀⠁⠝⠙⠀⠊⠞⠀⠙⠕⠑⠎⠝⠞⠀⠓⠥⠗⠞⠀⠍⠑
+
- Gothic: 𐌼𐌰𐌲 𐌲𐌰𐌴𐍃 𐌹̈𐍄𐌰𐌽, 𐌽𐌹 𐌼𐌹𐍃 𐍅𐌿 𐌽𐌳𐌰𐌽 𐌱𐍂𐌹𐌲𐌲𐌹𐌸
+
- Georgian: მინას ვჭამ და არა მტკივა.
+
- Armenian: Կրնամ ապակի ուտել և ինծի անհանգիստ չըներ։
+
- Inuktitut: ᐊᓕᒍᖅ ᓂᕆᔭᕌᖓᒃᑯ ᓱᕋᙱᑦᑐᓐᓇᖅᑐᖓ
+
+
+
+
- Amharic: የሰው ፡ ልጅ ፡ ሁሉ ፡ ሲወለድ ፡ ነጻና ፡ በክብርና ፡ በመብትም ፡ እኩልነት ፡ ያለው ፡ ነው ...
+
+
- Somali (Osmanya alphabet): 𐒛𐒆𐒖𐒒𐒖𐒔𐒖 𐒊𐒖𐒑𐒑𐒛𐒒𐒂𐒕𐒈 𐒓𐒚𐒄𐒓 𐒊𐒖𐒉𐒛 𐒘𐒈𐒖𐒌𐒝 𐒄𐒙𐒇 𐒖𐒔 𐒏𐒖𐒒𐒖 𐒈𐒘𐒑𐒖𐒒 𐒄𐒖𐒌𐒌𐒖 𐒉𐒖𐒇𐒖𐒍𐒂𐒖 ...
+
+
- Tamazight (Neo-Tifinagh alphabet): ⵉⵎⴷⴰⵏⴻⵏ, ⴰⴽⴽⴻⵏ ⵎⴰ ⵍⵍⴰⵏ ⵜⵜⵍⴰⵍⴻⵏ ⴷ ⵉⵍⴻⵍⵍⵉⵢⴻⵏ ...
+
+
- Tigrinya: ብመንፅር ክብርን መሰልን ኩሎም ሰባት እንትውለጹ ነፃን ማዕረን እዮም። ምስትውዓልን ...
+
+
+
- Vai: ꕉꕜꕮ ꔔꘋ ꖸ ꔰ ꗋꘋ ꕮꕨ ꔔꘋ ꖸ ꕎ ꕉꖸꕊ ꕴꖃ ꕃꔤꘂ ꗱ, ꕉꖷ ꗪꗡ ꔻꔤ ꗏꗒꗡ ꕎ ꗪ ꕉꖸꕊ ꖏꕎ. ꕉꕡ ꖏ ꗳꕮꕊ ꗏ ꕪ ...
+
+
+';
+
+
+
+//==============================================================
+$mpdf->autoScriptToLang = true;
+$mpdf->baseScript = 1; // Use values in classes/ucdn.php 1 = LATIN
+$mpdf->autoVietnamese = true;
+$mpdf->autoArabic = true;
+
+$mpdf->autoLangToFont = true;
+
+/* This works almost exactly the same as using autoLangToFont:
+ $stylesheet = file_get_contents('../lang2fonts.css');
+ $mpdf->WriteHTML($stylesheet,1);
+*/
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+exit;
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example63_new_mPDF_v6-0_features Images.php b/mpdf/examples/example63_new_mPDF_v6-0_features Images.php
new file mode 100644
index 0000000..a3bcde0
--- /dev/null
+++ b/mpdf/examples/example63_new_mPDF_v6-0_features Images.php
@@ -0,0 +1,255 @@
+
+body, div, p {
+ font-family: \'DejaVu Sans Condensed\';
+ font-size: 11pt;
+}
+.gradient {
+ border:0.1mm solid #220044;
+ background-color: #f0f2ff;
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+ box-shadow: 0.3em 0.3em #888888;
+}
+h4 {
+ font-weight: bold;
+ margin-top: 1em;
+ margin-bottom: 0.3em;
+ margin-top: 0;
+}
+div.text {
+ padding:0.8em;
+ margin-bottom: 0.7em;
+}
+p { margin: 0.25em 0; }
+p.code {
+ background-color: #e5e5e5;
+ margin: 1em 1cm;
+ padding: 0 0.3cm;
+ border:0.2mm solid #000088;
+ box-shadow: 0.3em 0.3em #888888;
+}
+p.example, div.example {
+ background-color: #eeeeee;
+ margin: 0.3em 1em 1em 1em;
+ padding: 0 0.3cm;
+ border:0.2mm solid #444444;
+}
+.code {
+ font-family: monospace;
+ font-size: 9pt;
+}
+.shadowtitle {
+ height: 8mm;
+ background-color: #EEDDFF;
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+ padding: 0.8em;
+ padding-left: 3em;
+ font-family:sans;
+ font-size: 26pt;
+ font-weight: bold;
+ border: 0.2mm solid white;
+ border-radius: 0.2em;
+ box-shadow: 0 0 1em 0.5em rgba(0,0,255,0.5);
+ color: #AAAACC;
+ text-shadow: 0.03em 0.03em #666, 0.05em 0.05em rgba(127,127,127,0.5), -0.015em -0.015em white;
+}
+h3 {
+ margin: 3em 0 2em -15mm;
+ background-color: #EEDDFF;
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+ padding: 0.5em;
+ padding-left: 3em;
+ width: 50%;
+ font-family:sans;
+ font-size: 16pt;
+ font-weight: bold;
+ border-left: none;
+ border-radius: 0 2em 2em 0;
+ box-shadow: 0 0 2em 0.5em rgba(255,0,0,1);
+ text-shadow: 0.05em 0.04em rgba(127,127,127,0.5);
+}
+.css {
+ font-family: arial;
+ font-style: italic;
+ color: #000088;
+}
+img.smooth {
+ image-rendering:auto;
+ image-rendering:optimizeQuality;
+ -ms-interpolation-mode:bicubic;
+}
+img.crisp {
+ image-rendering: -moz-crisp-edges; /* Firefox */
+ image-rendering: -o-crisp-edges; /* Opera */
+ image-rendering: -webkit-optimize-contrast;/* Webkit (non-standard naming) */
+ image-rendering: crisp-edges;
+ -ms-interpolation-mode: nearest-neighbor; /* IE (non-standard property) */
+}
+
+
+
+
+New Features in mPDF v6.0
+
+Images
+
+Gamma correction in PNG images
+Some PNG images contain a source Gamma correction value to maintain consistent colour display between devices.
+mPDF will adjust for gamma correction if a PNG image has a source gAMA entry <> 2.2
+Gamma correction is not supported in GIF files.
+
+For more information, and sample image files see http://www.libpng.org/pub/png/colorcube/gamma-consistency-test.html
+
+Below are some of the example images, displayed on a background of HTML colour, such that when displayed correctly they should appear as one solid block of the same colour:
+
+
+
+
+
+
+  |
+ |
+  |
+ |
+  |
+ |
+  |
+ |
+  |
+ |
+  |
+
+
+ Unlabelled GIF image (the usual kind) |
+ |
+ Unlabelled PNG image (no gamma info) |
+ |
+ PNG image with gamma 1/1.6 (i.e. 0.625) |
+ |
+ PNG image with gamma 1/2.2 (i.e. 0.4545) |
+ |
+ sRGB PNG image ("absolute colorimetric" rendering intent "sRGB") |
+ |
+ iCCP PNG images ("gamma 1.0" pixel data, linear ICC profiles: "iCCPGamma 1.0 profile") |
+
+
+
+
+
+
+Note that there are inconsistencies between browsers, so the image display varies considerably on the system you are using. There are also image errors which are not always apparent.
+
+
+The image below is taken from http://www.w3.org/TR/CSS21/intro.html and has the gAMA value set to 1.45454 This is probably unintentional and should be 0.45454 which is 1 / 2.2
+The image appears differently on IE9/Safari versus Firefox/Opera. To quote from http://www.libpng.org/pub/png/spec/1.2/PNG-Encoders.html "If the source file\'s gamma value is greater than 1.0, it is probably a display system exponent,....and you should use its reciprocal for the PNG gamma."
+Some applications seem to ignore this, displaying the image how it was probably intended.
+
+
+
+
+
+The two images below should be displayed with similar colour intensity. The one on the left is a 16-bit gamma-corrected PNG file; on the right is an unlabelled GIF file. Note that in Firefox (31.0) the image on the left looks duller because it has not been gamma-corrected for the display, whilst in IE (9)/Safari/Opera the images looks identical (correct).
+ 
+
+
+
+ICC color profiles
+Some PNG and JPEG image files contain an ICC color profile to alter colour display. These are supported in mPDF in PNG and JPG files, except PNG images which require converting via gd_image e.g. Alpha transparency, interlaced etc.
+
+Below is a PNG image which contains an ICC Profile which deliberately changes colours. When correctly displayed (applying the colour profile) ths colours should match the colour names. (In Firefox red appears as green, blue as red etc.)
+
+
+
+
+
+Wider support for PNG Images
+mPDF will now display almost every type of PNG image, including: paletted (Indexed) images with Alpha channel (full transparency), and grayscale or RGB truecolor images with single-colour transparency. One PNG type which cannot be handled by mPDF is a 16-bit image with binary (single-color) transparency. (This is because all images need to be converted to 8-bit for inclusion in PDF, and so for example if colour 0x4F27 is set as a transparency, it will treat all 0x4F.. pixels as transparent.)
+
+
+
+Alpha transparency (PNG images)
+Alpha transparency in PNG images has been fixed to work correctly against colour backgrounds e.g.:
+
+
+
+
+
+Interpolation
+PDF allows you to set image interpolation for an image - the result of this is variable and is dependent on the PDF viewer.
+mPDF allows you to specify whether interpolation is enabled, using CSS for each image, but: 1) it will not cascade i.e. the CSS property must be set directly on the img object or as class e.g. using <img class="smooth" style="image-rendering:auto"> 2) if an image appears more than once in the document, the interpolation setting will be that of the first appearance.
+
+A configurable variable in config.php determines the default value for the whole document: $this->interpolateImages = false;
+
+The draft CSS3 property "image-rendering" with the following values will be recognised by mPDF:
+
+- auto (default) - uses the value set by $this->interpolateImages
+- crisp-edges - interpolation disabled
+- optimizequality - interpolation enabled
+- smooth - interpolation enabled
+
+
+The image below on the left has interpolation enabled:
+
+
+ 
+ 
+
+
+NB Interpolation cannot be enabled on background images, SVG or WMF images.
+
+
+
+
+SVG Fonts
+mPDF 6 introduces (limited) support for SVG fonts, recognising the following elements and attributes:
+
+<defs>
+<font horiz-adv-x>
+<font-face font-family units-per-em ascent descent />
+<missing-glyph horiz-adv-x d />
+<glyph unicode horiz-adv-x d />
+
+
+In the example SVG below, the upper row of characters are drawn using paths and lines; in the lower row, they are written as text using glyphs defined as an SVG font.
+
+
+See the fonts-elem-01-t.svg file in the examples folder for more details.
+NB: @font-face is not supported.
+
+
+
+';
+//==============================================================
+if (isset($_REQUEST['html']) && $_REQUEST['html']) { echo $html; exit; }
+//==============================================================
+
+$mpdf->WriteHTML($html);
+
+$mpdf->Output();
+
+exit;
+
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/example_test.php b/mpdf/examples/example_test.php
new file mode 100644
index 0000000..c0de2a1
--- /dev/null
+++ b/mpdf/examples/example_test.php
@@ -0,0 +1,1962 @@
+fonttrans = array_merge($mpdf->fonttrans, array(
+ 'arial' => 'chelvetica',
+ 'helvetica' => 'chelvetica',
+ 'timesnewroman' => 'ctimes',
+ 'times' => 'ctimes',
+ 'couriernew' => 'ccourier',
+ 'courier' => 'ccourier',
+ 'sans' => 'chelvetica',
+ 'sans-serif' => 'chelvetica',
+ 'serif' => 'ctimes',
+ 'mono' => 'ccourier',
+));
+*/
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+//==============================================================
+//==============================================================
+$header = array(
+ 'L' => array(
+ ),
+ 'C' => array(
+ ),
+ 'R' => array(
+ 'content' => '{PAGENO}{nbpg}',
+ 'font-family' => 'sans',
+ 'font-style' => '',
+ 'font-size' => '9', /* gives default */
+ ),
+ 'line' => 1, /* 1 or 0 to include line above/below header/footer */
+);
+
+//$mpdf->SetHeader($header,'O');
+//$mpdf->SetHTMLFooter($footer);
+
+//==============================================================
+
+//$mpdf->mirrorMargins = 1; // Use different Odd/Even headers and footers and mirror margins (1 or 0)
+
+//$mpdf->showImageErrors = true;
+
+//$mpdf->SetDisplayMode('fullpage');
+
+//$mpdf->useLang = false;
+
+//$mpdf->useAutoFont = true;
+
+//$mpdf->ignore_invalid_utf8 = true;
+
+//$mpdf->keepColumns = true;
+
+//$mpdf->use_kwt = true;
+
+//$mpdf->hyphenate = true;
+
+//$mpdf->SetProtection(array('copy','print','modify','annot-forms'));
+//$mpdf->SetProtection(array('copy','print','modify','annot-forms'),'',null,128);
+//$mpdf->SetProtection(array('copy','print','modify','annot-forms','fill-forms','extract','assemble','print-highres'),'',null);
+
+//$mpdf->SetTitle("\xd8\xa7\xd9\x84\xd8\xb1\xd8\xa6\xd9\x8a\xd8\xb3");
+//$mpdf->SetAuthor("\xd8\xa7\xd9\x84\xd8\xb1\xd8\xa6\xd9\x8a\xd8\xb3");
+
+//$mpdf->SetWatermarkText("\xd8\xa7\xd9\x84\xd8\xb1\xd8\xa6\xd9\x8a\xd8\xb3");
+//$mpdf->showWatermarkText = true;
+//$mpdf->watermark_font = 'DejaVuSansCondensed';
+
+//$mpdf->SetCompression(false);
+
+//$mpdf->text_input_as_HTML = true;
+
+//$mpdf->annotMargin = -8;
+
+//$mpdf->title2annots = true;
+//$mpdf->Annotation('An annotation', 145, 24, 'Comment', "Ian Back", "My Subject", 0.7, array(127, 127, 255));
+
+//$mpdf->collapseBlockMargins = false; // mPDF 4.2 Allows top and bottom margins to collapse between block elements
+
+
+//$mpdf->allow_charset_conversion = true;
+//$mpdf->charset_in = 'win-1251';
+
+//$mpdf->useSubstitutions = true;
+//$mpdf->useActiveForms = true;
+
+//$mpdf->simpleTables = true; // Forces all cells to have same border, background etc. Improves performance
+//$mpdf->packTableData = true; // Reduce memory usage processing tables (but with increased processing time)
+
+// Using disk to cache table data can reduce memory usage dramatically, but at a cost of increased
+// executon time and disk access (read and write)
+//$mpdf->cacheTables = true;
+
+
+
+//==============================================================
+//$mpdf->SetImportUse();
+//$mpdf->SetSourceFile('example_all.pdf');
+//$tplIdx = $mpdf->ImportPage(9);
+//$mpdf->UseTemplate($tplIdx);
+//==============================================================
+//==============================================================
+//$mpdf->debug = true;
+//$mpdf->showStats = true;
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+/*
+// 4.3.003 TEST
+$html = 'Browser doesn\'t justify text before a BR Browser does justify text before an IMG 
+Browser doesn\'t justify text before a HR
Browser does justify text before an IMG 
+Browser does justify text before a TEXTAREA
+
+Browser does justify text before a SELECT ';
+
+//$html = 'If you want a single line of text to justify you need to do this
';
+//$mpdf->justifyB4br = true;
+//$mpdf->jSWord = 0.4; // Proportion (/1) of space (when justifying margins) to allocate to Word vs. Character
+//$mpdf->jSmaxChar = 0.25; // Maximum spacing to allocate to character spacing. (0 = no maximum)
+*/
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+/*
+// CJK Fonts
+$fonts = array(
+array('gb', 'GB (Chinese Simpl. Adobe)'),
+array('big5', 'BIG-5 (Chinese Trad. Adobe)'),
+array('sjis', 'SJIS (Japanese Adobe)'),
+array('arialunicodems', 'Arial Unicode MS'),
+array('cyberbit', 'CyberBit'),
+array('sun-exta', 'Sun-ExtA'),
+array('hannoma', 'Han Nom A'),
+array('mingliu', 'MingLiU'),
+array('mingliu_hkscs', 'MingLiU_HKSCS'),
+array('arplumingcn', 'AR PL Uming CN'),
+array('arpluminghk', 'AR PL Uming HK'),
+array('arplumingtw', 'AR PL Uming TW'),
+);
+$chars = array('34c7','4eca','4ede','4f3b','4fae','508e','50a6','50c7','517e','518f','51b2','5203','520f','5222','55c2','57d2','6b21','87a0','8880','8a03',
+'4EE4',
+'76F4',
+'9AA8',
+'9F31',
+'2493F',
+);
+
+$html .= "
+
+
+
+
+ |
+";
+foreach($fonts AS $f) {
+ $html .= "".$f[1]." | ";
+}
+$html .= "
+
+
+";
+foreach($chars AS $char) {
+ $html .= "| U+".strtoupper($char)." | ";
+ foreach($fonts AS $f) {
+ $html .= "".$char."; | ";
+ }
+ $html .= "
+";
+}
+$html .= "
+
+";
+*/
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+/*
+
+$html = '
+
+mPDF 5.6.40
+Bug fix
+';
+$mpdf->WriteHTML($html);
+
+
+
+
+
+$mpdf->allowCJKorphans = false; // FALSE=always wrap to next line; TRUE=squeeze or overflow [default true]
+
+
+$html = '
+部部部部部部部部部部
+
+CJKleading Leading characters - Not allowed at end of line 々
+部部部部部部部部部々部
+
+CJKfollowing Following characters - Not allowed at start ォ
+部部部部部部部部部部ォ
+
+';
+$mpdf->WriteHTML($html);
+
+//==============================================================
+$mpdf->allowCJKorphans = true; // FALSE=always wrap to next line; TRUE=squeeze or overflow [default true]
+
+
+$html = '
+CJKfollowing Following characters - Not allowed at start ォ
+部部部部部部部部部部ォ
+
+
+';
+$mpdf->WriteHTML($html);
+
+//==============================================================
+// CJK Line-breaking
+$align = 'left';
+$mpdf->allowCJKorphans = false; // FALSE=always wrap to next line; TRUE=squeeze or overflow [default true]
+$mpdf->allowCJKoverflow = false; // FALSE=squeeze; TRUE=overflow (only some characters, and disabled in tables) [default false]
+$html = '
+CJKoverflow Characters which are allowed to overflow the right margin ,
+text-align: '.$align.';
+$mpdf->allowCJKorphans = '.$mpdf->allowCJKorphans.';
+$mpdf->allowCJKoverflow = '.$mpdf->allowCJKoverflow.';
+部部部部部部部部部部,
+
+';
+$mpdf->WriteHTML($html);
+//==============================================================
+// CJK Line-breaking
+$align = 'justify';
+$mpdf->allowCJKorphans = false; // FALSE=always wrap to next line; TRUE=squeeze or overflow [default true]
+$mpdf->allowCJKoverflow = false; // FALSE=squeeze; TRUE=overflow (only some characters, and disabled in tables) [default false]
+$html = '
+text-align: '.$align.';
+$mpdf->allowCJKorphans = '.$mpdf->allowCJKorphans.';
+$mpdf->allowCJKoverflow = '.$mpdf->allowCJKoverflow.';
+部部部部部部部部部部,
+
+';
+$mpdf->WriteHTML($html);
+//==============================================================
+// CJK Line-breaking
+$align = 'left';
+$mpdf->allowCJKorphans = true; // FALSE=always wrap to next line; TRUE=squeeze or overflow [default true]
+$mpdf->allowCJKoverflow = true; // FALSE=squeeze; TRUE=overflow (only some characters, and disabled in tables) [default false]
+$html = '
+text-align: '.$align.';
+$mpdf->allowCJKorphans = '.$mpdf->allowCJKorphans.';
+$mpdf->allowCJKoverflow = '.$mpdf->allowCJKoverflow.';
+部部部部部部部部部部,
+';
+$mpdf->WriteHTML($html);
+//==============================================================
+// CJK Line-breaking
+$align = 'left';
+$mpdf->allowCJKorphans = true; // FALSE=always wrap to next line; TRUE=squeeze or overflow [default true]
+$mpdf->allowCJKoverflow = false; // FALSE=squeeze; TRUE=overflow (only some characters, and disabled in tables) [default false]
+$html = '
+text-align: '.$align.';
+$mpdf->allowCJKorphans = '.$mpdf->allowCJKorphans.';
+$mpdf->allowCJKoverflow = '.$mpdf->allowCJKoverflow.';
+部部部部部部部部部部,
+';
+$mpdf->WriteHTML($html);
+//==============================================================
+// CJK Line-breaking
+$align = 'justify';
+$mpdf->allowCJKorphans = true; // FALSE=always wrap to next line; TRUE=squeeze or overflow [default true]
+$mpdf->allowCJKoverflow = false; // FALSE=squeeze; TRUE=overflow (only some characters, and disabled in tables) [default false]
+$html = '
+text-align: '.$align.';
+$mpdf->allowCJKorphans = '.$mpdf->allowCJKorphans.';
+$mpdf->allowCJKoverflow = '.$mpdf->allowCJKoverflow.';
+部部部部部部部部部部,
+';
+$mpdf->WriteHTML($html);
+//==============================================================
+// CJK Line-breaking
+$align = 'justify';
+$mpdf->allowCJKorphans = true; // FALSE=always wrap to next line; TRUE=squeeze or overflow [default true]
+$mpdf->allowCJKoverflow = true; // FALSE=squeeze; TRUE=overflow (only some characters, and disabled in tables) [default false]
+$html = '
+text-align: '.$align.';
+$mpdf->allowCJKorphans = '.$mpdf->allowCJKorphans.';
+$mpdf->allowCJKoverflow = '.$mpdf->allowCJKoverflow.';
+部部部部部部部部部部,
+';
+$mpdf->WriteHTML($html);
+//==============================================================
+// CJK Line-breaking
+$align = 'justify';
+$mpdf->allowCJKorphans = true; // FALSE=always wrap to next line; TRUE=squeeze or overflow [default true]
+$mpdf->allowCJKoverflow = true; // FALSE=squeeze; TRUE=overflow (only some characters, and disabled in tables) [default false]
+$mpdf->CJKforceend = true;
+$html = '
+text-align: '.$align.';
+$mpdf->allowCJKorphans = '.$mpdf->allowCJKorphans.';
+$mpdf->allowCJKoverflow = '.$mpdf->allowCJKoverflow.';
+$mpdf->CJKforceend = '.$mpdf->CJKforceend .';
+部部部部部部部部部部,
+';
+$mpdf->WriteHTML($html);
+//==============================================================
+*/
+//==============================================================
+//==============================================================
+//==============================================================
+// Tai Tham (Lanna script)
+$htmlx = '
+
+ ᨢ᩶ᩣᨧᩮᩢ᩶ᩣᨸᩮᩢ᩠ᨶᩈᩣ᩠ᩅᨩ᩠ᨿᨦᩉ᩠ᨾᩲ᩵ ᩉ᩠ᨾᩯᨷᩴ᩵ᩬᨴᩮᩢ᩵ᩣᨯᩲᨠᩴ᩶ᩬᨧᩡᨸᩮᩢ᩠ᨶᩈᩣ᩠ᩅᩃᩯ᩠᩶ᩅ ᨲᩧ᩠ᨦᩅᩢ᩠ᨶᨾᩦᨷ᩵ᩤ᩠ᩅᨾᩣᩋᩯ᩠᩵ᩅ ᨾᩣᩋᩪ᩶ᨾᩣᨪᩯ᩠ᩅ ᨸᩮᩢ᩠ᨶᨤᩫ᩠ᨶᩃᨻᩪᩁ
+
+ ᨢ᩶ᩣᨧᩮᩢ᩶ᩣᨧᩡᩮᩃᩥᩬᨠᩋᩮᩢᩣᨹᩱ ᩋ᩶ᩣ᩠ᨿᨷ᩵ᩤ᩠ᩅᨩ᩠ᨿᨦᩁᩣ᩠ᨿᨩᩨ᩵ᨠᩯ᩠᩶ᩅᨾᩣᩃᩪᩁ ᩋ᩶ᩣ᩠ᨿᨠᩬᨦᨤᩫ᩠ᨶᨻᩯ᩵ᨢ᩠ᨿᩅᨨᩩᨶ ᩋ᩶ᩣ᩠ᨿᨤᩴᩣᩋ᩶ᩣ᩠ᨿᨾᩪᩁ ᩋ᩶ᩣ᩠ᨿᩈᩫ᩠ᨾᩋ᩶ᩣ᩠ᨿᨾᩦ
+
+ ᨻᩮᩥ᩠᩵ᨶᨷᩬᨠᩅ᩵ᩤᨧᩡᨾᩣᨢᩴᩬᨢ᩶ᩣᨧᩮᩢ᩶ᩣᨠᩴᩬᩁᩴᩬᨾᩣᩃᩯ᩠᩶ᩅᨸᩮᩢ᩠ᨶᨸᩦ ᨻᩴ᩵ᩬᨾᩯ᩵ᨳ᩶ᩣᨸᩪᩈᩁᩦᩋ᩶ᩣ᩠ᨿᨷ᩵ᩤ᩠ᩅᨲᩫ᩠ᩅᨯᩦᩉᩣ᩠ᨿᨪᩯ᩠ᨷᩉᩣ᩠ᨿᩈᩬ᩠ᨿ ᨢ᩶ᩣᨧᩮᩢ᩶ᩣᨷᩴ᩵ᩬᨩᩮᩥ᩵ᩬᩋᩉᩯ᩠ᨾᩃᩯ᩠᩶ᩅ ᨧᩡᨲᩯ᩠᩵ᨦᨠᩢ᩠ᨷᨾᩯ᩠᩶ᩅᨸᩱᩀᩪ᩵ᨸᩖᩣ᩠ᨿᨯᩬ᩠ᨿᨢᩣ᩠ᨿᨹ᩶ᩣ ᨢᩣ᩠ᨿᨻᩮᨩ᩠ᩁ᩺ ᨢᩣ᩠ᨿᨻᩖᩬ᩠ᨿᨢᩣ᩠ᨿᩉ᩠ᩅᩯᩁᨢᩣ᩠ᨿᩈᩕᩬ᩠ᨿᩀᩪ᩵ᨷᩫ᩠ᨶᨯᩬ᩠ᨿᨸᩩᨿ
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+// TEST DOUBLE BORDER
+//$mpdf->SetColumns(3);
+$htmlx = '
+
+
+Hallo World
+
+
+
+Hallo World
+
+
+
+Hallo World
+
+
+
+Hallo World
+
+
+
+
+
+Hallo World
+
+
+
+Hallo World
+
+
+
+Hallo World
+
+
+
+
+Hallo World
+
+
+
+
+
+
+
+
+
+
+ Hallo World
+
+ Hallo World
+
+ Hallo World
+
+
+
+
+
+
+
+
+
+
+| A whole new world |
+
+
+| A whole new world |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+';
+
+$mpdf->useKerning = true;
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+function SVGarcpath($start, $end, $cx = 50, $cy = 50, $r = 48) {
+ $start = deg2rad($start);
+ $end = deg2rad($end);
+ while ($end < $start) { $end += (M_PI*2); }
+ if (($end - $start) > M_PI) { $largearcflag = 1; }
+ else { $largearcflag = 0; }
+ $start = $start-(M_PI/2); // Adjust to start from the top=0 degrees
+ while ($start < 0) { $start += (M_PI*2); }
+ $end = $end-(M_PI/2);
+ while ($end < 0) { $end += (M_PI*2); }
+ $commands = array('M', $cx, $cy,
+ 'l', $r * cos($start), $r * sin($start),
+ 'A', $r, $r, 0, $largearcflag, 1, $cx + ($r * cos($end)), $cy + ($r * sin($end)),
+ "z");
+ $c = implode(' ', $commands);
+ return $c;
+}
+
+function SVGpie($segs, $w=30, $backgroundcolor="none", $linecolor="none", $linewidth=0, $seglinecolor="none", $seglinewidth=0) {
+ // $w is a number (? pixels)
+ // $seglinewidth is a number (? pixels)
+ $os = (max($seglinewidth,$linewidth))/2;
+ $svg = ''."\n";
+ return $svg;
+}
+
+$segs = array(
+ array(0, 90, "blue"),
+);
+$segs2 = array(
+ array(0, intval(0.65*360), "blue"),
+);
+
+$svg = SVGpie($segs, 30, "wheat", "none", 0, "none", 0);
+$svg2 = SVGpie($segs2, 30, "wheat", "none", 0, "none", 0);
+
+$html_SVG = '
+
+| Normal (25%): | '.$svg.' |
+| Large (65%): | '.$svg2.' |
+
+';
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+// Test In-line font characteristics
+$htmlx = '
+
+Normal Arial font-size 16 red bold italic Small Caps underline shadow not shadow; not underline; not small-caps; not italic; not bold; not red; not font-size-16; not Arial-font-family; normal
+
+
+|
+Normal Arial font-size 16 red bold italic Small Caps underline shadow not shadow; not underline; not small-caps; not italic; not bold; not red; not font-size-16; not Arial-font-family; normal
+ |
+
+
+Normal kern AWAY To nokern AWAY To not nokern AWAY To; not kern AWAY To; normal green blue not blue; not green; normal
+
+
+|
+Normal kern AWAY To nokern AWAY To not nokern AWAY To; not kern AWAY To; normal green blue not blue; not green; normal
+ |
+
+';
+
+//==============================================================
+//==============================================================
+// Test In-line font-feature characteristics
+$htmlx = '
+
+Calibri normal:
+£123450 (case32) 1st 3rd [CASE] g& CaSeMeNt traffic check
+
+pnum
+£123450 (case32) 1st 3rd [CASE] g& CaSeMeNt traffic check
+
+
+ordn
+£123450 (case32) 1st 3rd [CASE] g& CaSeMeNt traffic check
+
+
+
+onum
+£123450 (case32) 1st 3rd [CASE] g& CaSeMeNt traffic check
+
+lnum
+£123450 (case32) 1st 3rd [CASE] g& CaSeMeNt traffic check
+
+case
+£123450 (case32) 1st 3rd [CASE] g& CaSeMeNt traffic check
+
+salt
+£123450 (case32) 1st 3rd [CASE] g& CaSeMeNt traffic check
+
+dlig
+£123450 (case32) 1st 3rd [CASE] g& CaSeMeNt traffic check
+
+c2sc
+£123450 (case32) 1st 3rd [CASE] g& CaSeMeNt traffic check
+
+smcp
+£123450 (case32) 1st 3rd [CASE] g& CaSeMeNt traffic check
+
+sups
+£123450 (case32) 1st 3rd [CASE] g& CaSeMeNt traffic check
+
+ sups off:
+£123450 (case32) 1st 3rd [CASE] g& CaSeMeNt traffic check
+
+ smcp off:
+£123450 (case32) 1st 3rd [CASE] g& CaSeMeNt traffic check
+
+ c2sc off:
+£123450 (case32) 1st 3rd [CASE] g& CaSeMeNt traffic check
+
+ dlig off:
+£123450 (case32) 1st 3rd [CASE] g& CaSeMeNt traffic check
+
+ salt off:
+£123450 (case32) 1st 3rd [CASE] g& CaSeMeNt traffic check
+
+ case off:
+£123450 (case32) 1st 3rd [CASE] g& CaSeMeNt traffic check
+
+ lnum off:
+£123450 (case32) 1st 3rd [CASE] g& CaSeMeNt traffic check
+
+ onum off:
+£123450 (case32) 1st 3rd [CASE] g& CaSeMeNt traffic check
+ |
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+$mpdf->jSmaxChar = 5; // Maximum spacing to allocate to character spacing. (0 = no maximum)
+
+// Test GPOS
+$html = '
+
+ผู้ คู่
+
+
+
+ผู้ คู่
+
+// GSUB 5.2
+
+ಶಿಕ್ಷೆ ವಿಧಿಸಿದೆ
+
+
+// GSUB 7.2
+
+ಕ್ರೌ Kannada
+
+
+
+ಕ್ರೌ
+
+
+
+
+
+זֵּיְּשֳׂךָ
+
+
+
+זֵּיְּשֳׂךָ
+
+
+
+ Á á Ȧ ȧ Ä ä ï fi (DejaVu Sans Condensed)
+traffic
+insufflate
+ Á á Ȧ ȧ Ä ä ï fi traffic insufflate (Arial)
+ Á á Ȧ ȧ Ä ä ï fi (Times New Roman)
+
+
+// Test GPOS 2
+
+ To Á á Ȧ ȧ Ä ä ï fi Wö Ẅ Ta Tu Tö (Arial)
+AWAY To WAR
+ Ta To Á á Ȧ ȧ Ä ä ï fi (DejaVu Sans Condensed)
+traffic
+insufflate Ta Tu
+
+AWAY To WAR
+ To Á á Ȧ ȧ Ä ä ï fi Wö Ẅ Ta Tu Tö (DejaVu Sans Condensed)
+traffic
+insufflate
+
+ To Á á Ȧ ȧ Ä ä ï fi Wö Ta Tu Tö (Times New Roman)
+AWAY To WAR
+
+To Ta D̏ Ḍ ả Á á Ȧ ȧ Ä ä ï fi Wö Ta Tu Tö (Arial)
+AWAY To WAR
+To D̏ Ḍ ả Á á Ȧ ȧ Ä ä ï fi Wö Ta Tu Tö (Arial)
+AWAY To WAR
+Kerning = GPOS Lookup Type 2; Mark to base = GOS Lookup Type 4
+Ä̃̕ ä̃̕ ä̃̕ ã̈̕ ã̈̕ (GPOS Lookup Type 6)
+
+ç̥ (GPOS Lookup Type 5)
+
+ç̥ (GPOS Lookup Type 5)
+
+اثمكحه
+
+ (Cursive GPOS Lookup Type 3)
+Ä ä ä ã a̕
+Ä̕ ä̕ ä̃ ã̈ ã̕
+Ä̃̕ ä̃̕ ä̃̕ ã̈̕ ã̈̕
+
+
+
+
+اٙٙه اه ه وٙه وه ه
+
+
+
+
+trÄ̃̕ffic AWAY To trä̃̕ffic AWAY To trä̃̕ffic AWAY To trä̃̕ffic AWAY To trä̃̕ffic AWAY To trä̃̕ffic AWAY To trä̃̕ffic AWAY To trä̃̕ffic AWAY To trä̃̕ffic AWAY To trä̃̕ffic AWAY To
+
+trÄ̃̕ffic AWAY To trä̃̕ffic AWAY To trä̃̕ffic AWAY To trä̃̕ffic AWAY To
+
+
+// TEST GPOS Ligature Position
+
+
+يَـٰٓأَيُّهَا يَنتُم لَىٰٓ ۚ
+ وَلَا كَمَا
+ٱللَّهُ ٱللَّهَ وَلَا
+لَا
+رِّجَالِكُمْ ۖ
+
+خْرَىٰ ۚ وَلَا يَأْبَۚ
+وَلَا تَسْـَٔمُوٓا۟ أَوْ كَبِيرًا إِلَىٰٓ
+ٱللَّهِ وَأَدْنَىٰٓ أَلَّا إِلَّآ
+ بَيْنَكُمْ عَلَيْكُمْ أَلَّا
+يَعْتُمْ ۚ وَلَا كَاتِبٌۭ
+
+
+// TEST GPOS Ligature Position - TABLES
+
+|
+يَـٰٓأَيُّهَا يَنتُم لَىٰٓ ۚ
+ وَلَا كَمَا
+ٱللَّهُ ٱللَّهَ وَلَا
+لَا
+رِّجَالِكُمْ ۖ
+
+خْرَىٰ ۚ وَلَا يَأْبَۚ
+وَلَا تَسْـَٔمُوٓا۟ أَوْ كَبِيرًا إِلَىٰٓ
+ٱللَّهِ وَأَدْنَىٰٓ أَلَّا إِلَّآ
+ بَيْنَكُمْ عَلَيْكُمْ أَلَّا
+يَعْتُمْ ۚ وَلَا كَاتِبٌۭ
+ |
+
+
+
+// TEST \'curs\' GPOS
+
+
+ـىݦـ
+ﺌﺌﺌﺌﺌﺌﺌﺌﺌﺌ
+
+
+
+ـىݦـ
+ﺌﺌﺌﺌﺌﺌﺌﺌﺌﺌ
+
+
+
+سْتَشْهِدُ
+
+
+
+سْتَشْهِدُ
+
+
+// TEST LINE-BREAKING
+
+
+trÄ̃̕ff AWAY 1a) trä̃̕ffic AWAY To insuff-erable
+trä̃̕ffic ÄWAY
+
+
+trÄ̃̕ffic AWAY 1b) trä̃̕ffic AWAY To
+insufferable frä̃̕ffic ÄWAY To
+
+
+trÄ̃̕fficAWAYinsufferableTogrä̃̕fficAWAYToträ̃̕ffic2e)i)AWAYToträ̃̕fficAWAYToträ̃̕fficÄWAYTo
+
+
+trÄ̃̕ffic2e)ii)A)withSHYsufableToträ̃̕fficAWAYToträ̃̕ffic AWAY To hrä̃̕ffic AWAY To trä̃̕ffic AWAY To trä̃̕ffic ÄWAY To
+
+
+trÄ̃̕ffic AW 2e)ii)A) trä̃̕ffic AWAY To
+insufferable trä̃̕ffic AWAY 3.) trä̃̕ffic
+ÄWAY To trä̃̕ffic
+
+
+trÄ̃̕ffic2e)ii)B)sufferableToträ̃̕fficAWAYToträ̃̕ffic AWAY To hrä̃̕ffic AWAY To trä̃̕ffic AWAY To trä̃̕ffic ÄWAY To
+
+// TEST LINE-BREAKING - TABLES
+|
+trÄ̃̕ff AWAY 1a) trä̃̕ffic AWAY To insuff-erable
+trä̃̕ffic ÄWAY |
+
+|
+trÄ̃̕ffic AWAY 1b) trä̃̕ffic AWAY To
+insufferable frä̃̕ffic ÄWAY To |
+
+|
+trÄ̃̕fficAWAYinsufferableTogrä̃̕fficAWAYToträ̃̕ffic2e)i)AWAYToträ̃̕fficAWAYToträ̃̕fficÄWAYTo |
+
+|
+trÄ̃̕ffic2e)ii)A)withSHYsufableToträ̃̕fficAWAYToträ̃̕ffic AWAY To hrä̃̕ffic AWAY To trä̃̕ffic AWAY To trä̃̕ffic ÄWAY To |
+
+|
+trÄ̃̕ffic AW 2e)ii)A) trä̃̕ffic AWAY To
+insufferable trä̃̕ffic AWAY 3.) trä̃̕ffic
+ÄWAY To trä̃̕ffic |
+
+|
+trÄ̃̕ffic2e)ii)B)sufferableToträ̃̕fficAWAYToträ̃̕ffic AWAY To hrä̃̕ffic AWAY To trä̃̕ffic AWAY To trä̃̕ffic ÄWAY To |
+
+
+
+
+// CSS control of features
+
+all all all
+
+Small Caps. 1,278 and More.
+
+Small Caps. 1,278 and More.
+
+1st 100 1/2 traffic AWAY feast To
+
+1st 100 1/2 traffic AWAY feast To β θ φ
+
+1st 100 1/2 traffic AWAY feast To β θ φ
+
+C10H16N5O13P3
+
+Cambria:
+ \'salt\'
+ \'c2sc\'
+ \'smcp\'
+ \'sups\'
+ \'sinf\'
+ \'case\'
+ \'calt\'
+ \'tnum\'
+ \'pnum\'
+ \'onum\'
+ \'lnum\'
+ \'numr\'
+ \'dnom\'
+
+1st 100 1/2 traffic AWAY feast To β θ φ
+
+Calibri:
+ \'case\'
+ \'calt\'
+ \'numr\'
+ \'dnom\'
+ \'subs\'
+ \'tnum\'
+ \'pnum\'
+ \'onum\'
+ \'lnum\'
+ \'salt\'
+ \'c2sc\'
+ \'smcp\'
+ \'sups\'
+ \'ordn\'
+ \'liga\'
+ \'dlig\'
+1st 100 1/2 traffic AWAY feast To
+
+1st 100 1/2 traffic AWAY feast To
+
+// TEST GPOS Type 2 Format 1 (abvm)
+र्वे॑
+
+// TEST \'kern\' GPOS in Arabic Typesetting
+
+
+
+٣٤٥
+
+
+
+
+٣٤
+
+
+
+٣٤٥
+
+
+
+٣٤
+
+
+
+٣٤
+
+
+
+٣٤
+
+
+
+This test for reversal of chunks in flowing block, preserving consecutive chunks of LTR in an RTL line
+
+الحمد These English words and not reversed ٣٤٥ لله
+
+
+
+
+
+
+الحمد ٣٤٥ ٣٤٥ لله
+
+
+
+בדיקה באנגלית Latin Text - (ניסיון A)
+
+בדיקה באנגלית Latin Text - (ניסיון 2)
+
+
+בנק: 12, סניף: 11, מס\' חשבון: 111, מס\' המחאה: 1112
+
+
+קיזוז ימים בגין תחילת עבודה מתאריך 08/01/2013
+
+
+שירותי Cloud Computing
+
+
+
+(ٱللَّهَ) Ä̕ ä̕
+
+
+
+Ä̃̕ Ä̕ä̕ä̃ (ٱللَّهَ) Ä̕ ä̕
+
+
+GPOS Type 2 Format 1 "kern"
+
+كَبِيرًا إِلَىٰٓ
+
+
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+$mpdf->debug = true;
+//==============================================================
+//==============================================================
+$htmlx ='
+
+
+
+
+
+ৎত
+ৎতে
+ত
+ত্ত
+ত্তে
+ত্ত
+ত্তে
+
+
+
+ত্ = Khanda Ta. (U+09CE) character was added in Unicode v 4.1 and prior to this, (U+09A4 U+09CD U+200D) used
+
+
+Kannada
+ತಮ್ಮದೇ ಯುವತಿಯೊಬ್ಬಳನ್ನು ಸಾಬೀತಾಗಿದ್ದು ನಡೆಸಿದ್ದು ಇಂಗ್ಲೆಂಡ್ ನ್ಯಾಯಾಲಯವು ಯುವತಿಯನ್ನು ಮಲದೊಡ್ಡಪ್ಪ ಮತ್ತು ಭಾವ ಅತ್ಯಾಚಾರ ಕಾರ್ಡಿಫ್ ಕ್ರೌನ್ ನ್ಯಾಯಾಲಯದಲ್ಲಿ ಅಪರಾಧಿಗಳಲ್ಲಿ ಮಲತಂದೆ ಮತ್ತು ಮಲದೊಡ್ಡಪ್ಪ ಅಕ್ರಮ ವಲಸಿಗರಾಗಿದ್ದು ಅವರನ್ನು ಭಾರತಕ್ಕೆ ಮಾಡಲಾಗುತ್ತದೆ.
+
+
+ಮಲದೊಡ್ಡಪ್ಪ ಮತ್ತು ಮಲತಂದೆಗೆ ಕ್ರಮವಾಗಿ ಮತ್ತು
+
+
+ಬಾಲಕಿಯನ್ನೇ ಅತ್ಯಾಚಾರ ಮಾಡಿದ್ದರು ವರ್ಷವಿದ್ದಾಗ ಗರ್ಭಕ್ಕೆ ಕಾರಣವಾಗಿರುವುದನ್ನೂ ಮಲ ದೊಡ್ಡಪ್ಪ ಅವಧಿಯಲ್ಲಿ ಒಪ್ಪಿಕೊಂಡಿದ್ದಾನೆ ಆಕೆಯನ್ನು ಅತ್ಯಾಚಾರ ಮಾಡಿದ್ದು ಮಗುವಾಗಿದ್ದಾಗ ತೋರಿಸಿದ್ದ. ಅಲ್ಲದೆ ಹಲ್ಲೆ ನಡೆಸಿದ್ದ ನ್ಯಾಯಾಲಯ
+
+
+ಬಾಲಕಿಯಾಗಿದ್ದಾಗಲೇ ಆರಂಭಿಸಿದ್ದನ್ನು ನ್ಯಾಯಾಲಯ ಹೊರಗೆಳೆದಿತ್ತು.
+
+Telegu
+ఆగ్నేయ ఇరాన్లో ఆత్మాహుతి
+
+
+రెవల్యూషనరీ గార్డ్లతో ప్రముఖ కమాండర్లతోసహా మొత్తం చెందినట్లు లోక్సభ స్పీకర్
+
+
+దాడుల్లో భద్రతాదళాలకు శుశాత్రీ, మొహమ్మద్ తదితరులున్నారని, తీవ్రగాయాలపాలైనారని చెప్పారు.
+
+
+కమాండర్లు పాకిస్థాన్ సరిహద్దుల్లోనున్న పిశిన్ ప్రాంతంలో పాల్గొనేందుకు దేరి వెళ్ళారని
+
+Oriya
+ଆପଣଙ୍କୁ ସ୍ବାଗତ ଏହି ଉନ୍ମୁକ୍ତ ଇଣ୍ଟରନେଟ ବିଶ୍ବର ଉପଲବ୍ଧ ମଧ୍ୟ ବର୍ଦ୍ଧିତ କିମ୍ବା ଏହି ପୃଷ୍ଠାକୁ ସମ୍ପାଦନ ସମସ୍ତ ମୁକ୍ତ ଲାଇସେନ୍ସର ସର୍ତ୍ତ ଉପଲବ୍ଧ ମୁକ୍ତ ଇଲେକ୍ଟ୍ରୋନିକ୍ସ ପ୍ରିଣ୍ଟ୍ ପର୍ଯ୍ୟନ୍ତ ପ୍ରସଙ୍ଗ
+
+Punjabi
+ਗ੍ਰਹਿਮੰਤਰੀ ਉਨ੍ਹਾ ਦ੍ਰਮੁਕ ਸ਼੍ਰੀਲੰਕਾ
+
+Malayalam
+സിപിഎം
+
+Bengali (bn)
+স্বেচ্ছাসেবী ও ত্রাণ তীব্রতা স্রোত সংখ্যা স্বভাবতই আক্রমণ প্রবেশ নিয়ন্ত্রণ সাহায্যে
+
+Assamese
+উদ্দেশ্য বিশ্বকোষ প্ৰণয়ন সাহিত্যিকসকল
+গ্ৰাহ্য গ্ৰহন
+
+Misc
+অ্য ক ক় কি ক্ ক্ক ক্র ক্র্ক ক্ক ক্ক দ্য ন্ক ন্ধ ন্ব ন্য ন্র ন্ক ন্ধ ন্ব ন্র ন্ক ন্ধ ন্ব ন্র য্ র্ক র্কি র্কৌ র্ন্ র্ব্ব শ্য ষ্য স্য ি কো কৌ ক্র্ক ন্ক ন্ব ন্ক ন্ব ন্র র্কাং র্কাঃ র্কৌ র্ভ ৰ্ভ ৱ্ভ অৗ ন্ত্র ত্যু চ্য্র
+
+Reph
+র্ক র্কা র্কি র্কী র্কু র্কূ র্কে র্কৈ র্কো র্কৌ র্য র্য র্য র্র্য
+
+CP - Dependent
+া ি ী ু ূ ৃ ে ৈ ো ৌ
+
+GSUB
+ক্র খ্র গ্র ঘ্র জ্র ত্র দ্র ধ্র প্র ম্র শ্র স্র হ্র ছ্র ট্র ঠ্র ড্র থ্র ফ্র ব্র ভ্র ক্য খ্য গ্য ঘ্য চ্য জ্য ট্য ঠ্য ড্য ড়্য ঢ্য ত্য থ্য দ্য ধ্য ন্য প্য ফ্য ব্য ভ্য ম্য য্য র্য ল্য শ্য ষ্য স্য হ্য
+ক্ল গ্ল প্ল ম্ল ল্ল শ্ল স্ল হ্ল ক্ক
+
+
+ক্ব জ্ব ট্ব ত্ব দ্ব ধ্ব ন্ব ব্ব ম্ব ল্ব শ্ব ষ্ব স্ব হ্ব
+
+
+ণ্ণ ষ্ণ ষ্ণু হ্ণ হ্ণি জ্জ ট্ট ত্ত দ্দ ন্ন প্প ত্ন ম্ন স্ন হ্ন ক্ন গ্ন গ্ম ঙ্ম ট্ম ণ্ম ত্ম দ্ম ধ্ম ন্ম ম্ম ল্ম শ্ম ষ্ম হ্ম ক্ষ ক্ত গ্ধ ঙ্ক ঙ্খ ঙ্গ ঙ্ঘ চ্চ চ্ছ চ্ঞ জ্ঝ জ্ঞ ঞ্চ ঞ্ছ ঞ্জ ণ্ট ক্ট ণ্ড ন্ড দ্গ দ্ঘ দ্ধ দ্ভ ন্ত ন্থ ন্দ ন্ধ প্ত ব্জ ব্দ ম্প ম্ফ ম্ভ ল্ক ল্গ ল্প ল্ফ শ্চ ষ্ক ষ্ট ষ্ঠ ষ্প ষ্ফ স্ক স্খ স্ত স্থ স্প স্ফ ম্থ ল্ত ল্ধ ক্ম ক্স গ্গ ঘ্ন চ্ন
+
+
+ছ্ব
+
+
+ঞ্ঝ ড্ড ড্ম ড়্গ ণ্ঠ ণ্ঢ ণ্ব ত্থ থ্ব ধ্ন ন্ট ন্ঠ ন্স প্ট প্ন ফ্ল ব্ধ ব্ল ভ্ল ম্ত ম্দ ল্ট ল্ড শ্ছ শ্ন শ্ত স্ট স্ম
+
+
+চ্ছ্র চ্ছ্ব দ্দ্ব দ্ধ্ব ন্ধ্র ব্দ্র
+
+
+ক্ষ্ণ ক্ষ্ম
+
+
+জ্জ্ব ত্ত্ব ত্ম্য ন্ত্র ন্ত্ব ন্দ্র ন্ধ্য ন্ন্য ম্প্র ম্ভ্র র্ধ্ব র্শ্ব ষ্ট্র ষ্প্র স্ত্র স্ট্র স্ক্র ক্ট্র
+প্স
+
+
+';
+//==============================================================
+//==============================================================
+//==============================================================
+// ************ FIXES ************
+// ************ FIXES ************
+$htmlx ='
+
+
+FIX OTL (ZZZ93) Kannada: Old spec Lohit-Kannada -
+
+ನ್ನು ದ್ದು ನ್ನು ತ್ತು ದ್ದು ದ್ದು ನ್ನು ಪ್ಪ ಕ್ರೌ ಕ್ರ
+
+
+
+INDIC_FIX_1:
+র্ন্
+
+INDIC_FIX_2:
+
+న్లా
+న్లి
+న్లీ
+న్లు
+న్లూ
+న్లె
+న్లే
+న్లై
+న్లొ
+న్లో
+న్లౌ
+
+
+INDIC_FIX_3:
+
+ক্র্ক
+ক্র্ক
+
+INDIC_FIX_4:
+ర్డ్
+
+OTL_FIX_1 & OTL_FIX_2:
+ନ୍ମୁ Ä̃̕
+
+OTL_FIX_3:
+କ୍ଟ୍ର
+
+ZKI8 Fix - (NB With this, Indic fix 2 no longer required.)
+
+న్లో
+
+
+ZZZ96 Fix - GPOS fix in OTL Type 2 (kerning) for XPlacement of first character of pair
+
+ကြို
+
+Part 2) Kern on by default as needed for repositioning
+
+သန္တာ
+
+
+LOHIT fonts at :
+https://fedorahosted.org/lohit/wiki
+Version 2 are under development: http://pravin-s.blogspot.in/2013/08/project-creating-standard-and-reusable.html
+
+Solaiman-Lipi (Bengali): http://www.omicronlab.com/bangla-fonts.html
+
+
+Khmer Fix 1
+
+ង្រ្គ
+ង្គ្រ
+ន្រ្តី
+ន្ត្រី
+ង្រ្គោះ
+ង្គ្រោះ
+
+
+';
+// ************ FIXES ************
+// INDIC_FIX_1 Indic Initial re-ordering; stops search for base when Halant before ZWJ - this sets the BASE at position of ZWJ
+//define('OMIT_INDIC_FIX_1', 1);
+
+// INDIC_FIX_2 Indic Initial re-ordering; Indic If C(base) H ZWNJ C2 Matra - and Matra position is POS_BEFORE_SUB,
+// this changes it to correct position after the 2nd C (by changing it to POS_AFTER_SUB)
+// i.e. when ZWNJ prevents C2 from becoming a joined/form
+//define('OMIT_INDIC_FIX_2', 1);
+
+// INDIC_FIX_3 Indic Initial re-ordering; If C(pre-base) H Ra H C(base) - this allows blwf to be applied to pre-base H-Ra
+// whereas blwf is normally only applied post-base
+// If blwf not substituted, marks for Ra + H to apply 'rphf'
+//define('OMIT_INDIC_FIX_3', 1);
+
+// INDIC_FIX_4 Indic Initial re-ordering; ZWNJ should block H C from forming blwf post-base (e.g. Ra[base] H C H ZWNJ)
+// need to unmask backwards beyond first consonant arrived at */
+//define('OMIT_INDIC_FIX_4', 1);
+
+// OTL_FIX_1 GPOS Mark to Mark Attachment - prevent rule being skipped if the "base" mark is not attached to a ligature
+// because it would be skipped as it deems that the marks are attached to different ligs or components of ligs.
+//define('OMIT_OTL_FIX_1', 1);
+
+// OTL_FIX_2 GPOS Mark to Mark Attachment - sets a BaseWidth for the Mark to attach to
+//define('OMIT_OTL_FIX_2', 1);
+
+// OTL_FIX_3 GSUB Type 6 substitution, returned value for shift which meant next character was skipped for lookup (x3 lines)
+//define('OMIT_OTL_FIX_3', 1);
+
+// ZKI6 fixed moving characters using _move_info_pos()
+
+// ZKI7 fixed old_spec to mark Ra-Halant for pre-base ordering (instead of Halant-Ra)
+
+// ZKI8 Fix Indic Initial re-ordering: ZWNJ will stop search for base
+// INDIC_FIX_2 no longer required when this is used.
+
+
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+$htmlx = '
+
+
+
+KHMER
+
+ង្រ្គ
+ង្គ្រ
+ន្រ្តី
+ន្រ្តី
+ង្គ្រោះ
+
+
+
+យុវជនម្នាក់បានស្លាប់ដោយគ្រាប់កាំភ្លើងរបស់ប៉ូលិស និងបីនាក់ផ្សេងទៀតរងរបួស នៅក្នុងការប្រឈមមុខដាក់គ្នាដាច់ដោយឡែកគ្នាមួយ រវាងក្រុមយុវជនមួយក្រុម ជាមួយប៉ូលិស នៅម្តុំស្ពានក្បាលថ្នល់។ នេះបើតាមព័ត៌មានពីលោក ចាន់ សាវ៉េត មន្រ្តីស៊ើបអង្កេតរបស់អង្គការសិទ្ធិមនុស្សអាដហុក ដែលវត្តមាននៅកន្លែងកន្លែងកើតហេតុ នៅយប់ថ្ងៃអាទិត្យទី ១៥ កញ្ញានេះ។
+
+Khmer OS
+
+ង្រ្គ
+ង្គ្រ
+ន្រ្តី
+ន្រ្តី
+ង្គ្រោះ
+
+
+យុវជនម្នាក់បានស្លាប់ដោយគ្រាប់កាំភ្លើងរបស់ប៉ូលិស និងបីនាក់ផ្សេងទៀតរងរបួស នៅក្នុងការប្រឈមមុខដាក់គ្នាដាច់ដោយឡែកគ្នាមួយ រវាងក្រុមយុវជនមួយក្រុម ជាមួយប៉ូលិស នៅម្តុំស្ពានក្បាលថ្នល់។ នេះបើតាមព័ត៌មានពីលោក ចាន់ សាវ៉េត មន្រ្តីស៊ើបអង្កេតរបស់អង្គការសិទ្ធិមនុស្សអាដហុក ដែលវត្តមាននៅកន្លែងកន្លែងកើតហេតុ នៅយប់ថ្ងៃអាទិត្យទី ១៥ កញ្ញានេះ។
+
+
+Khmer
+
+ង្រ្គ
+ង្គ្រ
+ន្រ្តី
+ន្រ្តី
+ង្គ្រោះ
+
+
+យុវជនម្នាក់បានស្លាប់ដោយគ្រាប់កាំភ្លើងរបស់ប៉ូលិស និងបីនាក់ផ្សេងទៀតរងរបួស នៅក្នុងការប្រឈមមុខដាក់គ្នាដាច់ដោយឡែកគ្នាមួយ រវាងក្រុមយុវជនមួយក្រុម ជាមួយប៉ូលិស នៅម្តុំស្ពានក្បាលថ្នល់។ នេះបើតាមព័ត៌មានពីលោក ចាន់ សាវ៉េត មន្រ្តីស៊ើបអង្កេតរបស់អង្គការសិទ្ធិមនុស្សអាដហុក ដែលវត្តមាននៅកន្លែងកន្លែងកើតហេតុ នៅយប់ថ្ងៃអាទិត្យទី ១៥ កញ្ញានេះ។
+
+
+
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+$htmlx = '
+Thai shaper
+
+ด๋ำ
+ดํ๋า
+
+Lao shaper
+
+ດ໋ຳ
+ດໍ໋າ
+
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+/*
+$html = '
+
+SYRIAC - Estrangelo Edessa
+
+ܘܬܘܒ ܐܬܟܢܝܬ ܗܕܐ ܕܝܪܐ ܩܕܝܫܬܐ ܒܫܡ ܩܕܝܫܐ ܥܢܘܝܐ ܡܪܝ ܐܘܓܝܢ ܕܐܬܐ ܗ̱ܘܐ ܡܢ ܡܨܪܝܢ ܆ ܥܠ ܒܙܒܢ ܩܪܒܐ ܐܝܬܝܘ ܕܝܪ̈ܝܐ (ܐܝܟ ܬܫܥܝܬܐ ܬܘܕܝܬܢܝܬܐ) ܚܕܟܡܐ ܓܪ̈ܡܐ ܕܩܕܝܫܐ ܡܢ ܕܝܪܐ ܕܡܪܝ ܐܘܓܝܢ ܒܛܘܪܐ ܕ ܐܝܙܠܐ ܕܢܦܠ ܒܡܕܒܪܐ ܕ ܢܨܝܒܝܢ ܥܠ ܬܚܘܡܐ ܕ ܩܡܫܠܝ. ܘܬܘܒ ܐܬܟܢܝܬ ܕܝܪܐ ܕ ܙܥܦܪܐܢ ܐܘ ܟܘܪܟܡܐ ܒܫܡ ܡܪܝ (ܫܠܝܡܘܢ) ܕܝܪܝܐ ܕܫܬܐܣ ܠܕܝܪܐ ܒܫܢܬ 473 ܡ.
+
+
+';
+$mpdf->autoLangToFont = true;
+*/
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+/*
+$html = 'Distinguishes multiple languages enclosed in same element (tags):
+Arabic قال الرئيس
+English Cat sat on the large mat
+Tamil ஷியா
+Hindi भारत और
+Japanese いろはにほへと
+Chinese 来自商务部新闻办公
+Thai เป็นมนุษย
+Viet Một khảo sát mới cho biết người dân
+English Cat sat on the large mat
+Korean 키스의 고유조건은
+Syriac ܘܬܘܒ ܐܬܟܢܝܬ ܗܕܐ ܕܝܪܐ
+Myanmar (Burmese) မြန်မာအခေါ် တရားဝင်အားဖြင့်
+Khmer យុវជនម្នាក់បាន
+NKo ߟߐ߬ߝߋ߲ ߓߍ߯ ߟߊߝߋ߲
+Thaana ދިވެހި ވިކިޕީޑިއާ
+Arabic الحمد لله رب العالمين
+Urdu عزت کے اعتبار سے چیف جسٹس
+Pashto ځانمرگو بريدونو لږ
+Farsi گیکدیگر
+Sindhi جي ڳالهه ڪئي
+English Cat sat on the large mat
+
+';
+$mpdf->autoScriptToLang = true;
+$mpdf->baseScript = 1;
+$mpdf->autoVietnamese = true;
+$mpdf->autoArabic = true;
+$mpdf->autoLangToFont = true;
+*/
+//==============================================================
+//==============================================================
+//==============================================================
+// TIBETAN
+$htmlx = '
+
+
+༄།ཏདྱཐཱ།ཨོཾགཏེགཏེཔཱརགཏེཔཱརསཾགཏེབོདྷིསྭཱཧཱ།
+ཨོཾམུནིམུནིམཧཱམུནིཡེསྭཱཧཱ།ཨོཾཨཱམིདྷེཝཱཧྲཱི།ཨོཾམཎིཔདྨེཧཱུཾ།ཨོཾཨཱཿཧཱུཾ་
+བཛྲགུརུཔདྨསིདྡྷིཧཱུཾ།ཨོཾཨཱམརཱཎིཛྲིཝནཏིཡེསྭཱཧཱ།ཨོཾཝགིཤཱརིམུཾ།ཨོཾ་
+མཎིཔདྨེཧཱུཾ།ཨོཾབཛྲཔཱནིཧཱུཾ།ཨོཾཏཱརེཏུཏྟཱརེཏུརེསྭཱཧཱ།ཨོཾབྷྲཱུཾ་
+སྭཱཧཱ།ཨོཾཨཱམྲིཏཱཨཱཡུརྡདེསྭཱཧཱ།ཨོཾམརིཙྱེམཾསྭཱཧཱ།
+
+
+';
+//==============================================================
+//==============================================================
+$htmlx = '
+
+ 
+
+MYANMAR (Burmese) - Myanmar Text
+
+
+င်္က္ကျြွှေို့်ာှီ့ၤဲံ့းႍ
+
+
+
+
+
+';
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+// FIXES for kerning/line-justification
+$htmlx = '
+
+
+
+
+// Test of XPlacement/XAdvance at end of line
+
+وَلْيَك
+وَلْيَك
+وَلْيَك
+وَلْيَك
+وَلْيَك
+وَلْيَك
+وَلْيَك
+وَلْيَك
+وَلْيَك
+وَلْيَك
+وَلْيَك
+وَلْيَك
+
+
+کا
+
+
+
+GPOS Type 2: Format 2 (THAANA - MV Boli)
+
+ވިކިޕީޑިއާ
+
+
+GPOS Type 2: Format 2 (ARABIC XB Zar)
+
+کا
+
+
+GPOS Type 2: Format 2 (ARABIC XB Zar)
+
+توگه
+
+
+GPOS Type 2: Format 2 (SYRIAC - Estrangelo Edessa)
+
+ܡܨܪܝܢ
+
+
+
+
+GPOS Type 2: Format 1 (Tharlon)
+ ကြို
+
+GPOS Type 2: Format 1 (Arabic Typesetting)
+
+كَبِيرًا إِلَىٰٓ
+
+
+GPOS Type 2: Format 1 (Arial)
+
+ÄYÄWAY Tö
+
+
+
+';
+
+//==============================================================
+// WHITESPACE
+$htmlx = '
+
+From Lazamon\'s Brut
+
+
+ Monotonic: Hallo World Hallo World
+ | Monotonic: Hallo World Hallo World |
+
+ Hallo Hallo Hallo Hallo Hallo
+';
+//==============================================================
+// LANGUAGE TAGS - CYRILLIC
+$htmlx = '
+HTML language tags to distinguish Bulgarian, Russian, and Serbian,
+which have different italic forms for lowercase б, г, д, п, and/or т:
+
+
+| Bulgarian:
+ | [ бгдпт ]
+ | [ бгдпт ]
+ | Мога да ям стъкло и не ме боли.
+ |
+| Russian:
+ | [ бгдпт ]
+ | [ бгдпт ]
+ | Я могу есть стекло, это мне не вредит.
+ |
+| Serbian:
+ | [ бгдпт ]
+ | [ бгдпт ]
+ | Могу јести стакло
+а
+да ми
+не
+шкоди.
+ |
+';
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+// BIDI ALGORITHM FOR CHUNKS
+$htmlx = '
+Arabic (السلام عليكم)
+Arabic (السلام عليكم)
+(السلام عليكم) Arabic
+';
+
+//==============================================================
+// CSS unicode-bidi
+// normal | embed | bidi-override | inherit
+$htmlx = '
+// embed = add LRE (U+202A; for \'direction: ltr\') or RLE (U+202B; for \'direction: rtl\') at the start of element and PDF (U+202C) at the end of element
+
+ english17 עברית18 english19 עברית20
+ english17 עברית18 english19 עברית20
+ english17 עברית18 english19 עברית20
+
+
+// bidi-override = LRO (U+202D; for \'direction: ltr\') or RLO (U+202E; for \'direction: rtl\') at the start of the element or at the start of each anonymous child block box, if any, and a PDF (U+202C) at the end of the element
+
+ english17 עברית18 english19 עברית20
+ english17 עברית18 english19 עברית20
+ english17 עברית18 english19 עברית20
+
+
+';
+//==============================================================
+//==============================================================
+//==============================================================
+// used to determine the aspect value of a font.
+// CSS3 font-aspect: http://www.w3.org/TR/css3-fonts/#propdef-font-size-adjust
+// DejaVuSansCondensed 0.547
+// FreeSerif 0.45
+// Arabic Typesetting 0.278
+// Mondulkiri 0.45
+// Sun-ExtA 0.455
+// XB Riyaz 0.523
+$htmlx = '
+
+bb
+bb
+';
+//==============================================================
+//==============================================================
+// Test for alpha transparency in PNG
+$htmlx = '
+
+ 
+ 
+
+
+
+ 
+ 
+
+
+ 
+ 
+
+
+ 
+ 
+
+
+ 
+ 
+
+
+';
+
+//==============================================================
+//==============================================================
+$htmlx ='
+
+
+ 
+
+
+
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+// ICC based Color Profiles in Images + 16-bit Gamma
+$htmlx = '
+PNG (16-bit, Gamma):
+PNG (Gamma):
+PNG (ICC Profile):
+
+JPEG (ICC Profile):
+
+
+ | Profiles in each quadrant: |
+ v4 e-sRGB |
+ v4 YCC-RGB |
+
+
+ | |
+ v2 GBR |
+ v2 Adobe RGB |
+
+
+
+
+This should correctly display with the motorbike in green:
+
+';
+//==============================================================
+//==============================================================
+//==============================================================
+// UNDERLINE and LINE-THROUGH - together
+$htmlx ='
+Hallo World
+Hallo World
+Hallo World
+Hallo World
+Hallo World
+Hallo World
+Hallo World
+';
+//==============================================================
+//==============================================================
+// UNDERLINE and LINE-THROUGH - across spans
+$htmlx ='
+1st
+1st
+';
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//BUG TABLES - Width > Page - needing to wrap letters or resize
+// KEEP THIS to Illustrate mpdf - ZZZZZe.php Bug fix
+$html = '
+Latin script will resize rather than wrap -
+
+
+| AB | AB | AB | AB | AB | AB | AB | AB |
+AB | AB | AB | AB | AB | AB | AB | AB |
+AB | AB | AB | AB | AB | AB | AB | AB |
+AB | AB | AB | AB | AB | AB | AB | AB |
+AB | AB | AB | AB | AB | AB | AB | AB |
+AB | AB | AB | AB | AB | AB | AB | AB |
+AB |
+AB |
+AB |
+ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB |
+
+
+
+Can force wrap using overflow: wrap -
+
+
+| AB | AB | AB | AB | AB | AB | AB | AB |
+AB | AB | AB | AB | AB | AB | AB | AB |
+AB | AB | AB | AB | AB | AB | AB | AB |
+AB | AB | AB | AB | AB | AB | AB | AB |
+AB | AB | AB | AB | AB | AB | AB | AB |
+AB | AB | AB | AB | AB | AB | AB | AB |
+AB |
+AB |
+AB |
+ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB |
+
+
+
+CJK script will wrap characters (this example also resizes to minimum column width). In this case, minimum is 2 characters in last column because of a character which cannot start a line -
+
+
+| 部部 | 部部 | 部部 | 部部 |
+部部 | 部部 | 部部 | 部部 |
+部部 | 部部 | 部部 | 部部 |
+部部 | 部部 | 部部 | 部部 |
+部部 | 部部 | 部部 | 部部 |
+部部 | 部部 | 部部 | 部部 |
+部部 | 部部 | 部部 | 部部 |
+部部 | 部部 | 部部 | 部部 |
+部部 | 部部 | 部部 | 部部 |
+部部 | 部部 | 部部 | 部部 |
+部部 | 部部 | 部部 | 部部 |
+部部部部部部部部部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ |
+
+
+
+Default layout when resizing not required - note wrapping, but balanced column widths -
+
+
+| 部部 | 部部 | 部部 | 部部 |
+部部 | 部部 | 部部 | 部部 |
+部部 | 部部 | 部部 | 部部 |
+部部 | 部部 | 部部 | 部部 |
+部部 | 部部 | 部部 | 部部 |
+部部 | 部部 | 部部 | 部部 |
+部部部部部部部部部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ部ォ |
+
+
+
+';
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+$html = '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+';
+
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+if (isset($_REQUEST['html'])) { echo $html; exit; }
+if (isset($_REQUEST['source'])) {
+ $file = __FILE__;
+ header("Content-Type: text/plain");
+ header("Content-Length: ". filesize($file));
+ header("Content-Disposition: attachment; filename='".$file."'");
+ readfile($file);
+ exit;
+}
+//==============================================================
+$mpdf->WriteHTML($html);
+
+
+// $mpdf->WriteHTML('Generated in '.sprintf('%.2f',(microtime(true) - $mpdf->time0)).' seconds. Peak memory usage '.number_format((memory_get_peak_usage(true)/(1024*1024)),2).' MB ');
+
+// echo number_format((memory_get_peak_usage(true)/(1024*1024)),2).' MB ';
+
+//==============================================================
+//==============================================================
+// OUTPUT
+//$mpdf->SetCompression(false);
+$mpdf->Output(); exit;
+
+//$mpdf->Output('test.pdf','D'); exit;
+
+$s = $mpdf->Output('','S'); echo nl2br(htmlspecialchars($s)); exit;
+
+
+exit;
+
+//==============================================================
+//==============================================================
+//==============================================================
+//==============================================================
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/flowers-pattern.jpg b/mpdf/examples/flowers-pattern.jpg
new file mode 100644
index 0000000..45aaeeb
Binary files /dev/null and b/mpdf/examples/flowers-pattern.jpg differ
diff --git a/mpdf/examples/fonts-elem-01-t.svg b/mpdf/examples/fonts-elem-01-t.svg
new file mode 100644
index 0000000..dac89f8
--- /dev/null
+++ b/mpdf/examples/fonts-elem-01-t.svg
@@ -0,0 +1,58 @@
+
+
+
diff --git a/mpdf/examples/formsubmit.php b/mpdf/examples/formsubmit.php
new file mode 100644
index 0000000..f13a395
--- /dev/null
+++ b/mpdf/examples/formsubmit.php
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+Submitted data from PDF Form
+(See formsubmit.php in the Examples folder for details)
+';
+
+
+if (count($_POST)) {
+ // To display HTML output from PDF form
+ echo 'HTML format data sent as POST';
+ foreach($_POST AS $name=>$val) {
+ $t = mb_convert_encoding(PDFDocEncodingToWin1252($val), 'UTF-8', 'Windows-1252' ); // If from core fonts doc
+ echo 'PDFDocEnc: '.$name.' => '.htmlspecialchars($t).' ';
+ }
+}
+else if (count($_GET)) {
+ // To display HTML output from PDF form
+ echo 'HTML format data sent as GET';
+ foreach($_GET AS $name=>$val) {
+ $t = mb_convert_encoding(PDFDocEncodingToWin1252($val), 'UTF-8', 'Windows-1252' ); // If from core fonts doc
+ echo 'PDFDocEnc: '.$name.' => '.htmlspecialchars($t).' ';
+ }
+}
+
+else {
+ $postdata = file_get_contents("php://input");
+
+ if ($postdata) {
+ echo 'XFDF format data detected';
+ // To parse XFDF
+ if (preg_match_all('/\s*((.*?)<\/value\s*>)\s*<\/field\s*>/s', $postdata, $m)) {
+ for($i=0; $i(.*?)<\/value\s*>/s', $m[2][$i], $v);
+ if (count($v[0])>1) {
+ $values = array();
+ foreach($v[1] AS $val) { $values[] = $val; }
+ //foreach($v[1] AS $val) { $values[] = htmlspecialchars_decode($val); }
+ echo 'Field: '.$m[1][$i].' => [array of values] ('.implode(', ',$values).') ';
+ }
+ else {
+ //echo 'Field: '.$m[1][$i].' => '.htmlspecialchars_decode($m[3][$i]).' ';
+ echo 'Field: '.$m[1][$i].' => '.$m[3][$i].' ';
+ }
+ }
+ }
+ if (preg_match_all('/\s*\s*<\/field\s*>/s', $postdata, $m)) {
+ for($i=0; $iField: '.$m[1][$i].' => [blank]';
+ }
+ }
+ if (preg_match_all('//s', $postdata, $m)) {
+ for($i=0; $iField: '.$m[1][$i].' => [no value]';
+ }
+ }
+
+
+ // To display whole XFDF
+ //$postdata = preg_replace("/[\n\r]/", "", $postdata);
+ //$postdata = preg_replace('/>\s*', ">\n<", $postdata);
+ //echo nl2br(htmlspecialchars($postdata));
+ }
+ else { echo "No form data detected"; }
+}
+
+
+
+echo '';
+
+exit;
+
+function PDFDocEncodingToWin1252($txt) {
+ $Win1252ToPDFDocEncoding = array(
+ chr(0200) => chr(0240), chr(0214) => chr(0226), chr(0212) => chr(0227), chr(0237) => chr(0230),
+ chr(0225) => chr(0200), chr(0210) => chr(0032), chr(0206) => chr(0201), chr(0207) => chr(0202),
+ chr(0205) => chr(0203), chr(0227) => chr(0204), chr(0226) => chr(0205), chr(0203) => chr(0206),
+ chr(0213) => chr(0210), chr(0233) => chr(0211), chr(0211) => chr(0213), chr(0204) => chr(0214),
+ chr(0223) => chr(0215), chr(0224) => chr(0216), chr(0221) => chr(0217), chr(0222) => chr(0220),
+ chr(0202) => chr(0221), chr(0232) => chr(0235), chr(0230) => chr(0037), chr(0231) => chr(0222),
+ chr(0216) => chr(0231)
+ );
+ return strtr($txt, array_flip($Win1252ToPDFDocEncoding) );
+}
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/goto.gif b/mpdf/examples/goto.gif
new file mode 100644
index 0000000..e7de2b1
Binary files /dev/null and b/mpdf/examples/goto.gif differ
diff --git a/mpdf/examples/goto2.gif b/mpdf/examples/goto2.gif
new file mode 100644
index 0000000..b74091c
Binary files /dev/null and b/mpdf/examples/goto2.gif differ
diff --git a/mpdf/examples/goto2rtl.gif b/mpdf/examples/goto2rtl.gif
new file mode 100644
index 0000000..adbef51
Binary files /dev/null and b/mpdf/examples/goto2rtl.gif differ
diff --git a/mpdf/examples/img1.png b/mpdf/examples/img1.png
new file mode 100644
index 0000000..fe3f4de
Binary files /dev/null and b/mpdf/examples/img1.png differ
diff --git a/mpdf/examples/img2.png b/mpdf/examples/img2.png
new file mode 100644
index 0000000..2d142f4
Binary files /dev/null and b/mpdf/examples/img2.png differ
diff --git a/mpdf/examples/img3.png b/mpdf/examples/img3.png
new file mode 100644
index 0000000..a7a9487
Binary files /dev/null and b/mpdf/examples/img3.png differ
diff --git a/mpdf/examples/img4.png b/mpdf/examples/img4.png
new file mode 100644
index 0000000..e9c3f44
Binary files /dev/null and b/mpdf/examples/img4.png differ
diff --git a/mpdf/examples/img5.png b/mpdf/examples/img5.png
new file mode 100644
index 0000000..1e4c5ec
Binary files /dev/null and b/mpdf/examples/img5.png differ
diff --git a/mpdf/examples/index.php b/mpdf/examples/index.php
new file mode 100644
index 0000000..f9ab014
--- /dev/null
+++ b/mpdf/examples/index.php
@@ -0,0 +1,41 @@
+mPDF Example Files';
+
+foreach($files AS $n=>$f) {
+ echo ''.$n.') '.$f[0].' PDF ';
+}
+
+echo '';
+exit;
+
+
+// For PHP4 compatability
+if (!function_exists('scandir')) {
+ function scandir($dir = './', $sort = 0) {
+ $dir_open = @ opendir($dir);
+ if (! $dir_open)
+ return false;
+ while (($dir_content = readdir($dir_open)) !== false)
+ $files[] = $dir_content;
+ if ($sort == 1)
+ rsort($files, SORT_STRING);
+ else
+ sort($files, SORT_STRING);
+ return $files;
+ }
+}
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/examples/klematis.jpg b/mpdf/examples/klematis.jpg
new file mode 100644
index 0000000..b87e920
Binary files /dev/null and b/mpdf/examples/klematis.jpg differ
diff --git a/mpdf/examples/layers_tab.jpg b/mpdf/examples/layers_tab.jpg
new file mode 100644
index 0000000..4d96ff3
Binary files /dev/null and b/mpdf/examples/layers_tab.jpg differ
diff --git a/mpdf/examples/loading.gif b/mpdf/examples/loading.gif
new file mode 100644
index 0000000..e846e1d
Binary files /dev/null and b/mpdf/examples/loading.gif differ
diff --git a/mpdf/examples/mpdfstyleA4.css b/mpdf/examples/mpdfstyleA4.css
new file mode 100644
index 0000000..3492077
--- /dev/null
+++ b/mpdf/examples/mpdfstyleA4.css
@@ -0,0 +1,47 @@
+ body { font-family: DejaVuSansCondensed, sans-serif; font-size: 11pt; }
+ p { text-align: justify; margin-bottom: 4pt; margin-top:0pt; }
+
+ hr { width: 70%; height: 1px;
+ text-align: center; color: #999999;
+ margin-top: 8pt; margin-bottom: 8pt; }
+
+ a { color: #000066; font-style: normal; text-decoration: underline;
+ font-weight: normal; }
+
+ pre { font-family: DejaVuSansMono, monospaced; font-size: 9pt; margin-top: 5pt; margin-bottom: 5pt; }
+
+ h1 { font-weight: normal; font-size: 26pt; color: #000066;
+ font-family: DejaVuSansCondensed, sans-serif; margin-top: 18pt; margin-bottom: 6pt;
+ border-top: 0.075cm solid #000000; border-bottom: 0.075cm solid #000000;
+ text-align: ; page-break-after:avoid; }
+ h2 { font-weight: bold; font-size: 12pt; color: #000066;
+ font-family: DejaVuSansCondensed, sans-serif; margin-top: 6pt; margin-bottom: 6pt;
+ border-top: 0.07cm solid #000000; border-bottom: 0.07cm solid #000000;
+ text-align: ; text-transform: uppercase; page-break-after:avoid; }
+ h3 { font-weight: normal; font-size: 26pt; color: #000000;
+ font-family: DejaVuSansCondensed, sans-serif; margin-top: 0pt; margin-bottom: 6pt;
+ border-top: 0; border-bottom: 0;
+ text-align: ; page-break-after:avoid; }
+ h4 { font-weight: ; font-size: 13pt; color: #9f2b1e;
+ font-family: DejaVuSansCondensed, sans-serif; margin-top: 10pt; margin-bottom: 7pt;
+ font-variant: small-caps;
+ text-align: ; margin-collapse:collapse; page-break-after:avoid; }
+ h5 { font-weight: bold; font-style:italic; ; font-size: 11pt; color: #000044;
+ font-family: DejaVuSansCondensed, sans-serif; margin-top: 8pt; margin-bottom: 4pt;
+ text-align: ; page-break-after:avoid; }
+ h6 { font-weight: bold; font-size: 9.5pt; color: #333333;
+ font-family: DejaVuSansCondensed, sans-serif; margin-top: 6pt; margin-bottom: ;
+ text-align: ; page-break-after:avoid; }
+
+
+ .breadcrumb {
+ text-align: right; font-size: 8pt; font-family: DejaVuSerifCondensed, serif; color: #666666;
+ font-weight: bold; font-style: normal; margin-bottom: 6pt; }
+
+ .infobox { margin-top:10pt; background-color:#DDDDBB; text-align:center; border:1px solid #880000; }
+
+ .big { font-size: 1.5em; }
+ .red { color: #880000; }
+ .slanted { font-style: italic; }
+
+
diff --git a/mpdf/examples/mpdfstylePaged.css b/mpdf/examples/mpdfstylePaged.css
new file mode 100644
index 0000000..904372a
--- /dev/null
+++ b/mpdf/examples/mpdfstylePaged.css
@@ -0,0 +1,120 @@
+ @page {
+ size: 15cm 17cm; /* width height {1,2} | auto | portrait | landscape NB 'em' and 'ex' % are not allowed */
+ margin: 10%; /* % of page-box width for LR, height for TB */
+ margin-header: 5mm;
+ margin-footer: 5mm;
+ margin-left: 4cm;
+ margin-right: 2cm;
+ odd-header-name: myHeader2Odd;
+ even-header-name: html_myHTMLHeaderEven;
+ odd-footer-name: html_myHTMLFooterOdd;
+ even-footer-name: myFooter2Even;
+ marks: crop; /* crop | cross | none */
+ }
+
+ @page :first {
+ margin-top: 5cm; /* Top margin on first page 10cm */
+ }
+
+ @page standard {
+ size: auto; /* auto is the default mPDF value */
+ margin: 10%; /* % of page-box width for LR, height for TB */
+ marks: none; /* crop | cross | none */
+ }
+
+ @page standard :first {
+ margin-top: 7cm; /* Top margin on first page 10cm */
+ }
+
+ @page bigsquare {
+ size: 15cm 20cm;
+ margin-left: 4cm;
+ marks: crop cross; /* crop | cross | none */
+ background: transparent url('bg.jpg') repeat scroll 5mm 5mm; /* position inset by bleedMargin */
+ }
+
+ @page bigsquare :right {
+ header: html_myHTMLHeaderOdd;
+ footer: html_myHTMLFooterOdd;
+ }
+
+ @page bigsquare :left { /* left is what mPDF calls EVEN page - right=ODD */
+ header: html_myHTMLHeaderEven;
+ footer: html_myHTMLFooterEven;
+ }
+
+ @page smallsquare {
+ size: 25cm 15cm;
+ margin-left: 4cm;
+ marks: crop; /* crop | cross | none */
+ background-gradient: linear #c7cdde #f0f2ff 0 1 0 0.5;
+ }
+
+ @page rotated {
+ size: landscape;
+ marks: none; /* crop | cross | none */
+ background-color: #fff0f2;
+ margin-left: 3cm;
+ margin-right: 3cm;
+ }
+ @page rotated :first {
+ margin-top: 7cm; /* Top margin on first page 10cm */
+ }
+
+ h1.heading1 { color: #1188FF;
+ }
+
+ h1.heading2 { color: #88FF11;
+ page-break-before: always;
+ page: standard;
+ }
+ h1.heading3 { color: #FF1188;
+ page-break-before: right;
+ }
+ h1.heading4 { color: #FF8811;
+ page-break-before: left;
+ page: bigsquare;
+ }
+ h1.heading5 { color: #11FF88;
+ page: smallsquare;
+ }
+ h1.heading6 { color: #8811FF;
+ page: rotated;
+ }
+
+ br.paging { page-break-after: always; }
+
+ body { font-family: DejaVuSansCondensed; font-size: 11pt; }
+ p { text-align: justify; margin-bottom: 4pt; margin-top:0pt; }
+
+ hr { width: 70%; height: 1px;
+ text-align: center; color: #999999;
+ margin-top: 8pt; margin-bottom: 8pt; }
+
+ a { color: #000066; font-style: normal; text-decoration: underline;
+ font-weight: normal; }
+
+ pre { font-family: DejaVuSansMono; font-size: 9pt; margin-top: 5pt; margin-bottom: 5pt; }
+
+ h1 { font-weight: normal; font-size: 26pt; color: #000066;
+ font-family: DejaVuSansCondensed; margin-top: 18pt; margin-bottom: 6pt;
+ border-top: 0.075cm solid #000000; border-bottom: 0.075cm solid #000000;
+ text-align: ; page-break-after:avoid; }
+ h2 { font-weight: bold; font-size: 12pt; color: #000066;
+ font-family: DejaVuSansCondensed; margin-top: 6pt; margin-bottom: 6pt;
+ border-top: 0.07cm solid #000000; border-bottom: 0.07cm solid #000000;
+ text-align: ; text-transform: uppercase; page-break-after:avoid; }
+ h3 { font-weight: normal; font-size: 26pt; color: #000000;
+ font-family: DejaVuSansCondensed; margin-top: 0pt; margin-bottom: 6pt;
+ border-top: 0; border-bottom: 0;
+ text-align: ; page-break-after:avoid; }
+ h4 { font-weight: ; font-size: 13pt; color: #9f2b1e;
+ font-family: DejaVuSansCondensed; margin-top: 10pt; margin-bottom: 7pt;
+ text-align: ; margin-collapse:collapse; page-break-after:avoid; }
+ h5 { font-weight: bold; font-style:italic; ; font-size: 11pt; color: #000044;
+ font-family: DejaVuSansCondensed; margin-top: 8pt; margin-bottom: 4pt;
+ text-align: ; page-break-after:avoid; }
+ h6 { font-weight: bold; font-size: 9.5pt; color: #333333;
+ font-family: DejaVuSansCondensed; margin-top: 6pt; margin-bottom: ;
+ text-align: ; page-break-after:avoid; }
+
diff --git a/mpdf/examples/mpdfstyletables.css b/mpdf/examples/mpdfstyletables.css
new file mode 100644
index 0000000..d97fe9d
--- /dev/null
+++ b/mpdf/examples/mpdfstyletables.css
@@ -0,0 +1,122 @@
+
+ body { font-family: 'DejaVu Sans Condensed'; font-size: 11pt; }
+ p { text-align: justify; margin-bottom: 4pt; margin-top:0pt; }
+
+ table {font-family: 'DejaVu Sans Condensed'; font-size: 9pt; line-height: 1.2;
+ margin-top: 2pt; margin-bottom: 5pt;
+ border-collapse: collapse; }
+
+ thead { font-weight: bold; vertical-align: bottom; }
+ tfoot { font-weight: bold; vertical-align: top; }
+ thead td { font-weight: bold; }
+ tfoot td { font-weight: bold; }
+
+ .headerrow td, .headerrow th { background-gradient: linear #b7cebd #f5f8f5 0 1 0 0.2; }
+ .footerrow td, .footerrow th { background-gradient: linear #b7cebd #f5f8f5 0 1 0 0.2; }
+
+ th { font-weight: bold;
+ vertical-align: top;
+ padding-left: 2mm;
+ padding-right: 2mm;
+ padding-top: 0.5mm;
+ padding-bottom: 0.5mm;
+ }
+
+ td { padding-left: 2mm;
+ vertical-align: top;
+ padding-right: 2mm;
+ padding-top: 0.5mm;
+ padding-bottom: 0.5mm;
+ }
+
+ th p { margin:0pt; }
+ td p { margin:0pt; }
+
+ table.widecells td {
+ padding-left: 5mm;
+ padding-right: 5mm;
+ }
+ table.tallcells td {
+ padding-top: 3mm;
+ padding-bottom: 3mm;
+ }
+
+ hr { width: 70%; height: 1px;
+ text-align: center; color: #999999;
+ margin-top: 8pt; margin-bottom: 8pt; }
+
+ a { color: #000066; font-style: normal; text-decoration: underline;
+ font-weight: normal; }
+
+ pre { font-family: 'DejaVu Sans Mono'; font-size: 9pt; margin-top: 5pt; margin-bottom: 5pt; }
+
+ h1 { font-weight: normal; font-size: 26pt; color: #000066;
+ font-family: 'DejaVu Sans Condensed'; margin-top: 18pt; margin-bottom: 6pt;
+ border-top: 0.075cm solid #000000; border-bottom: 0.075cm solid #000000;
+ text-align: ; page-break-after:avoid; }
+ h2 { font-weight: bold; font-size: 12pt; color: #000066;
+ font-family: 'DejaVu Sans Condensed'; margin-top: 6pt; margin-bottom: 6pt;
+ border-top: 0.07cm solid #000000; border-bottom: 0.07cm solid #000000;
+ text-align: ; text-transform:uppercase; page-break-after:avoid; }
+ h3 { font-weight: normal; font-size: 26pt; color: #000000;
+ font-family: 'DejaVu Sans Condensed'; margin-top: 0pt; margin-bottom: 6pt;
+ border-top: 0; border-bottom: 0;
+ text-align: ; page-break-after:avoid; }
+ h4 { font-weight: ; font-size: 13pt; color: #9f2b1e;
+ font-family: 'DejaVu Sans Condensed'; margin-top: 10pt; margin-bottom: 7pt; font-variant: small-caps;
+ text-align: ; margin-collapse:collapse; page-break-after:avoid; }
+ h5 { font-weight: bold; font-style:italic; ; font-size: 11pt; color: #000044;
+ font-family: 'DejaVu Sans Condensed'; margin-top: 8pt; margin-bottom: 4pt;
+ text-align: ; page-break-after:avoid; }
+ h6 { font-weight: bold; font-size: 9.5pt; color: #333333;
+ font-family: 'DejaVu Sans Condensed'; margin-top: 6pt; margin-bottom: ;
+ text-align: ; page-break-after:avoid; }
+
+ .breadcrumb {
+ text-align: right; font-size: 8pt; font-family: 'DejaVu Serif Condensed'; color: #666666;
+ font-weight: bold; font-style: normal; margin-bottom: 6pt; }
+
+ .bpmTopic tbody tr:nth-child(even) { background-color: #f5f8f5; }
+ .bpmTopicC tbody tr:nth-child(even) { background-color: #f5f8f5; }
+ .bpmNoLines tbody tr:nth-child(even) { background-color: #f5f8f5; }
+ .bpmNoLinesC tbody tr:nth-child(even) { background-color: #f5f8f5; }
+ .bpmTopnTail tbody tr:nth-child(even) { background-color: #f5f8f5; }
+ .bpmTopnTailC tbody tr:nth-child(even) { background-color: #f5f8f5; }
+
+ .evenrow td, .evenrow th { background-color: #f5f8f5; }
+ .oddrow td, .oddrow th { background-color: #e3ece4; }
+
+ .bpmTopic { background-color: #e3ece4; }
+ .bpmTopicC { background-color: #e3ece4; }
+ .bpmNoLines { background-color: #e3ece4; }
+ .bpmNoLinesC { background-color: #e3ece4; }
+ .bpmClear { }
+ .bpmClearC { text-align: center; }
+ .bpmTopnTail { background-color: #e3ece4; topntail: 0.02cm solid #495b4a;}
+ .bpmTopnTailC { background-color: #e3ece4; topntail: 0.02cm solid #495b4a;}
+ .bpmTopnTailClear { topntail: 0.02cm solid #495b4a; }
+ .bpmTopnTailClearC { topntail: 0.02cm solid #495b4a; }
+
+ .bpmTopicC td, .bpmTopicC td p { text-align: center; }
+ .bpmNoLinesC td, .bpmNoLinesC td p { text-align: center; }
+ .bpmClearC td, .bpmClearC td p { text-align: center; }
+ .bpmTopnTailC td, .bpmTopnTailC td p { text-align: center; }
+ .bpmTopnTailClearC td, .bpmTopnTailClearC td p { text-align: center; }
+
+ .pmhMiddleCenter { text-align:center; vertical-align:middle; }
+ .pmhMiddleRight { text-align:right; vertical-align:middle; }
+ .pmhBottomCenter { text-align:center; vertical-align:bottom; }
+ .pmhBottomRight { text-align:right; vertical-align:bottom; }
+ .pmhTopCenter { text-align:center; vertical-align:top; }
+ .pmhTopRight { text-align:right; vertical-align:top; }
+ .pmhTopLeft { text-align:left; vertical-align:top; }
+ .pmhBottomLeft { text-align:left; vertical-align:bottom; }
+ .pmhMiddleLeft { text-align:left; vertical-align:middle; }
+
+ .infobox { margin-top:10pt; background-color:#DDDDBB; text-align:center; border:1px solid #880000; }
+
+ .bpmTopic td, .bpmTopic th { border-top: 1px solid #FFFFFF; }
+ .bpmTopicC td, .bpmTopicC th { border-top: 1px solid #FFFFFF; }
+ .bpmTopnTail td, .bpmTopnTail th { border-top: 1px solid #FFFFFF; }
+ .bpmTopnTailC td, .bpmTopnTailC th { border-top: 1px solid #FFFFFF; }
+
diff --git a/mpdf/examples/sample_basic.pdf b/mpdf/examples/sample_basic.pdf
new file mode 100644
index 0000000..86c4d74
Binary files /dev/null and b/mpdf/examples/sample_basic.pdf differ
diff --git a/mpdf/examples/sample_logoheader2.pdf b/mpdf/examples/sample_logoheader2.pdf
new file mode 100644
index 0000000..946883d
Binary files /dev/null and b/mpdf/examples/sample_logoheader2.pdf differ
diff --git a/mpdf/examples/sample_orientation2.pdf b/mpdf/examples/sample_orientation2.pdf
new file mode 100644
index 0000000..84944d9
Binary files /dev/null and b/mpdf/examples/sample_orientation2.pdf differ
diff --git a/mpdf/examples/sample_orientation3.pdf b/mpdf/examples/sample_orientation3.pdf
new file mode 100644
index 0000000..c23ca31
Binary files /dev/null and b/mpdf/examples/sample_orientation3.pdf differ
diff --git a/mpdf/examples/sunset.jpg b/mpdf/examples/sunset.jpg
new file mode 100644
index 0000000..ddd5118
Binary files /dev/null and b/mpdf/examples/sunset.jpg differ
diff --git a/mpdf/examples/test.pdf b/mpdf/examples/test.pdf
new file mode 100644
index 0000000..322fee9
Binary files /dev/null and b/mpdf/examples/test.pdf differ
diff --git a/mpdf/examples/tiger.bmp b/mpdf/examples/tiger.bmp
new file mode 100644
index 0000000..176565d
Binary files /dev/null and b/mpdf/examples/tiger.bmp differ
diff --git a/mpdf/examples/tiger.gif b/mpdf/examples/tiger.gif
new file mode 100644
index 0000000..12081da
Binary files /dev/null and b/mpdf/examples/tiger.gif differ
diff --git a/mpdf/examples/tiger.jpg b/mpdf/examples/tiger.jpg
new file mode 100644
index 0000000..a88e6b3
Binary files /dev/null and b/mpdf/examples/tiger.jpg differ
diff --git a/mpdf/examples/tiger.php b/mpdf/examples/tiger.php
new file mode 100644
index 0000000..55365ef
--- /dev/null
+++ b/mpdf/examples/tiger.php
@@ -0,0 +1,19 @@
+
\ No newline at end of file
diff --git a/mpdf/examples/tiger.png b/mpdf/examples/tiger.png
new file mode 100644
index 0000000..72c85ab
Binary files /dev/null and b/mpdf/examples/tiger.png differ
diff --git a/mpdf/examples/tiger.svg b/mpdf/examples/tiger.svg
new file mode 100644
index 0000000..66cf570
--- /dev/null
+++ b/mpdf/examples/tiger.svg
@@ -0,0 +1,653 @@
+
+
+
\ No newline at end of file
diff --git a/mpdf/examples/tiger.wmf b/mpdf/examples/tiger.wmf
new file mode 100644
index 0000000..34c0b52
Binary files /dev/null and b/mpdf/examples/tiger.wmf differ
diff --git a/mpdf/examples/tiger2.png b/mpdf/examples/tiger2.png
new file mode 100644
index 0000000..af42742
Binary files /dev/null and b/mpdf/examples/tiger2.png differ
diff --git a/mpdf/examples/tiger2.wmf b/mpdf/examples/tiger2.wmf
new file mode 100644
index 0000000..c60c75a
Binary files /dev/null and b/mpdf/examples/tiger2.wmf differ
diff --git a/mpdf/examples/tiger24trns.png b/mpdf/examples/tiger24trns.png
new file mode 100644
index 0000000..e3b3e0c
Binary files /dev/null and b/mpdf/examples/tiger24trns.png differ
diff --git a/mpdf/examples/tiger300px300dpi.png b/mpdf/examples/tiger300px300dpi.png
new file mode 100644
index 0000000..62f7405
Binary files /dev/null and b/mpdf/examples/tiger300px300dpi.png differ
diff --git a/mpdf/examples/tiger300px96dpi.png b/mpdf/examples/tiger300px96dpi.png
new file mode 100644
index 0000000..67174a7
Binary files /dev/null and b/mpdf/examples/tiger300px96dpi.png differ
diff --git a/mpdf/examples/tiger8trns.gif b/mpdf/examples/tiger8trns.gif
new file mode 100644
index 0000000..d46053b
Binary files /dev/null and b/mpdf/examples/tiger8trns.gif differ
diff --git a/mpdf/examples/tigercmyk.jpg b/mpdf/examples/tigercmyk.jpg
new file mode 100644
index 0000000..e67d5e2
Binary files /dev/null and b/mpdf/examples/tigercmyk.jpg differ
diff --git a/mpdf/examples/tux.svg b/mpdf/examples/tux.svg
new file mode 100644
index 0000000..de8c869
--- /dev/null
+++ b/mpdf/examples/tux.svg
@@ -0,0 +1,1487 @@
+
+
diff --git a/mpdf/examples/windmill.jpg b/mpdf/examples/windmill.jpg
new file mode 100644
index 0000000..378a91c
Binary files /dev/null and b/mpdf/examples/windmill.jpg differ
diff --git a/mpdf/font/ccourier.php b/mpdf/font/ccourier.php
new file mode 100644
index 0000000..1a6e572
--- /dev/null
+++ b/mpdf/font/ccourier.php
@@ -0,0 +1,10 @@
+629,'Descent'=>-157,'CapHeight'=>562,'FontBBox'=>'[-23 -250 715 805]');
+$desc=array('Flags'=>33,'FontBBox'=>'[-23 -250 715 805]','ItalicAngle'=>0,'Ascent'=>805,'Descent'=>-250,'Leading'=>0,'CapHeight'=>562,'XHeight'=>426,'StemV'=>51,'StemH'=>51,'AvgWidth'=>600,'MaxWidth'=>600,'MissingWidth'=>600);
+$up=-100;
+$ut=50;
+
+?>
diff --git a/mpdf/font/ccourierb.php b/mpdf/font/ccourierb.php
new file mode 100644
index 0000000..d8ce8a0
--- /dev/null
+++ b/mpdf/font/ccourierb.php
@@ -0,0 +1,10 @@
+629,'Descent'=>-157,'CapHeight'=>562,'FontBBox'=>'[-113 -250 749 801]');
+$desc=array('Flags'=>33,'FontBBox'=>'[-113 -250 749 801]','ItalicAngle'=>0,'Ascent'=>801,'Descent'=>-250,'Leading'=>0,'CapHeight'=>562,'XHeight'=>439,'StemV'=>106,'StemH'=>84,'AvgWidth'=>600,'MaxWidth'=>600,'MissingWidth'=>600);
+$up=-100;
+$ut=50;
+
+
+?>
diff --git a/mpdf/font/ccourierbi.php b/mpdf/font/ccourierbi.php
new file mode 100644
index 0000000..0a03eb1
--- /dev/null
+++ b/mpdf/font/ccourierbi.php
@@ -0,0 +1,10 @@
+629,'Descent'=>-157,'CapHeight'=>562,'FontBBox'=>'[-57 -250 869 801]');
+$desc=array('Flags'=>97,'FontBBox'=>'[-57 -250 869 801]','ItalicAngle'=>-12,'Ascent'=>801,'Descent'=>-250,'Leading'=>0,'CapHeight'=>562,'XHeight'=>439,'StemV'=>106,'StemH'=>84,'AvgWidth'=>600,'MaxWidth'=>600,'MissingWidth'=>600);
+$up=-100;
+$ut=50;
+
+
+?>
diff --git a/mpdf/font/ccourieri.php b/mpdf/font/ccourieri.php
new file mode 100644
index 0000000..9b26cfe
--- /dev/null
+++ b/mpdf/font/ccourieri.php
@@ -0,0 +1,10 @@
+629,'Descent'=>-157,'CapHeight'=>562,'FontBBox'=>'[-27 -250 849 805]');
+$desc=array('Flags'=>97,'FontBBox'=>'[-27 -250 849 805]','ItalicAngle'=>-12,'Ascent'=>805,'Descent'=>-250,'Leading'=>0,'CapHeight'=>562,'XHeight'=>426,'StemV'=>51,'StemH'=>51,'AvgWidth'=>600,'MaxWidth'=>600,'MissingWidth'=>600);
+$up=-100;
+$ut=50;
+
+
+?>
diff --git a/mpdf/font/chelvetica.php b/mpdf/font/chelvetica.php
new file mode 100644
index 0000000..d645618
--- /dev/null
+++ b/mpdf/font/chelvetica.php
@@ -0,0 +1,21 @@
+278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
+ chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>278,'"'=>355,'#'=>556,'$'=>556,'%'=>889,'&'=>667,'\''=>191,'('=>333,')'=>333,'*'=>389,'+'=>584,
+ ','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>278,';'=>278,'<'=>584,'='=>584,'>'=>584,'?'=>556,'@'=>1015,'A'=>667,
+ 'B'=>667,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>500,'K'=>667,'L'=>556,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
+ 'X'=>667,'Y'=>667,'Z'=>611,'['=>278,'\\'=>278,']'=>278,'^'=>469,'_'=>556,'`'=>333,'a'=>556,'b'=>556,'c'=>500,'d'=>556,'e'=>556,'f'=>278,'g'=>556,'h'=>556,'i'=>222,'j'=>222,'k'=>500,'l'=>222,'m'=>833,
+ 'n'=>556,'o'=>556,'p'=>556,'q'=>556,'r'=>333,'s'=>500,'t'=>278,'u'=>556,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>500,'{'=>334,'|'=>260,'}'=>334,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>222,chr(131)=>556,
+ chr(132)=>333,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>222,chr(146)=>222,chr(147)=>333,chr(148)=>333,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
+ chr(154)=>500,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>260,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
+ chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>556,chr(182)=>537,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>667,chr(193)=>667,chr(194)=>667,chr(195)=>667,chr(196)=>667,chr(197)=>667,
+ chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+ chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>500,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>556,chr(241)=>556,
+ chr(242)=>556,chr(243)=>556,chr(244)=>556,chr(245)=>556,chr(246)=>556,chr(247)=>584,chr(248)=>611,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>500,chr(254)=>556,chr(255)=>500);
+
+//$desc=array('Ascent'=>718,'Descent'=>-207,'CapHeight'=>718,'FontBBox'=>'[-166 -225 1000 931]');
+$desc=array('Flags'=>32,'FontBBox'=>'[-166 -225 1000 931]','ItalicAngle'=>0,'Ascent'=>931,'Descent'=>-225,'Leading'=>0,'CapHeight'=>718,'XHeight'=>523,'StemV'=>88,'StemH'=>76,'AvgWidth'=>513,'MaxWidth'=>1015,'MissingWidth'=>513);
+$up=-100;
+$ut=50;
+$kerninfo=array ( chr(49)=> array ( chr(49)=> -74, ), chr(65)=> array ( chr(84)=> -74, chr(86)=> -74, chr(87)=> -37, chr(89)=> -74, chr(118)=> -18, chr(119)=> -18, chr(121)=> -18, chr(146)=> -74, ), chr(70)=> array ( chr(44)=> -110, chr(46)=> -110, chr(65)=> -55, ), chr(76)=> array ( chr(84)=> -74, chr(86)=> -74, chr(87)=> -74, chr(89)=> -74, chr(121)=> -37, chr(146)=> -55, ), chr(80)=> array ( chr(44)=> -128, chr(46)=> -128, chr(65)=> -74, ), chr(82)=> array ( chr(84)=> -18, chr(86)=> -18, chr(87)=> -18, chr(89)=> -18, ), chr(84)=> array ( chr(44)=> -110, chr(46)=> -110, chr(58)=> -110, chr(65)=> -74, chr(79)=> -18, chr(97)=> -110, chr(99)=> -110, chr(101)=> -110, chr(105)=> -37, chr(111)=> -110, chr(114)=> -37, chr(115)=> -110, chr(117)=> -37, chr(119)=> -55, chr(121)=> -55, ), chr(86)=> array ( chr(44)=> -91, chr(46)=> -91, chr(58)=> -37, chr(65)=> -74, chr(97)=> -74, chr(101)=> -55, chr(105)=> -18, chr(111)=> -55, chr(114)=> -37, chr(117)=> -37, chr(121)=> -37, ), chr(87)=> array ( chr(44)=> -55, chr(46)=> -55, chr(58)=> -18, chr(65)=> -37, chr(97)=> -37, chr(101)=> -18, chr(105)=> 0, chr(111)=> -18, chr(114)=> -18, chr(117)=> -18, chr(121)=> -8, ), chr(89)=> array ( chr(44)=> -128, chr(46)=> -128, chr(58)=> -55, chr(65)=> -74, chr(97)=> -74, chr(101)=> -91, chr(105)=> -37, chr(111)=> -91, chr(112)=> -74, chr(113)=> -91, chr(117)=> -55, chr(118)=> -55, ), chr(102)=> array ( chr(102)=> -18, chr(146)=> 18, ), chr(114)=> array ( chr(44)=> -55, chr(46)=> -55, chr(146)=> 37, ), chr(118)=> array ( chr(44)=> -74, chr(46)=> -74, ), chr(119)=> array ( chr(44)=> -55, chr(46)=> -55, ), chr(121)=> array ( chr(44)=> -74, chr(46)=> -74, ), chr(145)=> array ( chr(145)=> -18, ), chr(146)=> array ( chr(115)=> -18, chr(146)=> -18, ), );
+?>
\ No newline at end of file
diff --git a/mpdf/font/chelveticab.php b/mpdf/font/chelveticab.php
new file mode 100644
index 0000000..f70d14e
--- /dev/null
+++ b/mpdf/font/chelveticab.php
@@ -0,0 +1,22 @@
+278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
+ chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>333,'"'=>474,'#'=>556,'$'=>556,'%'=>889,'&'=>722,'\''=>238,'('=>333,')'=>333,'*'=>389,'+'=>584,
+ ','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>333,';'=>333,'<'=>584,'='=>584,'>'=>584,'?'=>611,'@'=>975,'A'=>722,
+ 'B'=>722,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>556,'K'=>722,'L'=>611,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
+ 'X'=>667,'Y'=>667,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>584,'_'=>556,'`'=>333,'a'=>556,'b'=>611,'c'=>556,'d'=>611,'e'=>556,'f'=>333,'g'=>611,'h'=>611,'i'=>278,'j'=>278,'k'=>556,'l'=>278,'m'=>889,
+ 'n'=>611,'o'=>611,'p'=>611,'q'=>611,'r'=>389,'s'=>556,'t'=>333,'u'=>611,'v'=>556,'w'=>778,'x'=>556,'y'=>556,'z'=>500,'{'=>389,'|'=>280,'}'=>389,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>278,chr(131)=>556,
+ chr(132)=>500,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>278,chr(146)=>278,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
+ chr(154)=>556,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>280,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
+ chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>611,chr(182)=>556,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722,
+ chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+ chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>556,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>611,chr(241)=>611,
+ chr(242)=>611,chr(243)=>611,chr(244)=>611,chr(245)=>611,chr(246)=>611,chr(247)=>584,chr(248)=>611,chr(249)=>611,chr(250)=>611,chr(251)=>611,chr(252)=>611,chr(253)=>556,chr(254)=>611,chr(255)=>556);
+
+//$desc=array('Ascent'=>718,'Descent'=>-207,'CapHeight'=>718,'FontBBox'=>'[-170 -228 1003 962]');
+$desc=array('Flags'=>32,'FontBBox'=>'[-170 -228 1003 962]','ItalicAngle'=>0,'Ascent'=>962,'Descent'=>-228,'Leading'=>0,'CapHeight'=>718,'XHeight'=>532,'StemV'=>140,'StemH'=>118,'AvgWidth'=>535,'MaxWidth'=>1000,'MissingWidth'=>535);
+$up=-100;
+$ut=50;
+$kerninfo=array ( chr(49)=> array ( chr(49)=> -55, ), chr(65)=> array ( chr(84)=> -74, chr(86)=> -74, chr(87)=> -55, chr(89)=> -91, chr(118)=> -37, chr(119)=> -18, chr(121)=> -37, chr(146)=> -55, ), chr(70)=> array ( chr(44)=> -110, chr(46)=> -110, chr(65)=> -55, ), chr(76)=> array ( chr(84)=> -74, chr(86)=> -74, chr(87)=> -55, chr(89)=> -91, chr(121)=> -37, chr(146)=> -55, ), chr(80)=> array ( chr(44)=> -128, chr(46)=> -128, chr(65)=> -74, ), chr(82)=> array ( chr(86)=> -18, chr(87)=> -18, chr(89)=> -37, ), chr(84)=> array ( chr(44)=> -110, chr(46)=> -110, chr(58)=> -110, chr(65)=> -74, chr(79)=> -18, chr(97)=> -74, chr(99)=> -74, chr(101)=> -74, chr(105)=> -18, chr(111)=> -74, chr(114)=> -55, chr(115)=> -74, chr(117)=> -74, chr(119)=> -74, chr(121)=> -74, ), chr(86)=> array ( chr(44)=> -91, chr(46)=> -91, chr(58)=> -55, chr(65)=> -74, chr(97)=> -55, chr(101)=> -55, chr(105)=> -18, chr(111)=> -74, chr(114)=> -55, chr(117)=> -37, chr(121)=> -37, ), chr(87)=> array ( chr(44)=> -55, chr(46)=> -55, chr(58)=> -18, chr(65)=> -55, chr(97)=> -37, chr(101)=> -18, chr(105)=> -8, chr(111)=> -18, chr(114)=> -18, chr(117)=> -18, chr(121)=> -18, ), chr(89)=> array ( chr(44)=> -110, chr(46)=> -110, chr(58)=> -74, chr(65)=> -91, chr(97)=> -55, chr(101)=> -55, chr(105)=> -37, chr(111)=> -74, chr(112)=> -55, chr(113)=> -74, chr(117)=> -55, chr(118)=> -55, ), chr(102)=> array ( chr(146)=> 18, ), chr(114)=> array ( chr(44)=> -55, chr(46)=> -55, chr(146)=> 37, ), chr(118)=> array ( chr(44)=> -74, chr(46)=> -74, ), chr(119)=> array ( chr(44)=> -37, chr(46)=> -37, ), chr(121)=> array ( chr(44)=> -74, chr(46)=> -74, ), chr(145)=> array ( chr(145)=> -37, ), chr(146)=> array ( chr(115)=> -37, chr(146)=> -37, ), );
+
+?>
\ No newline at end of file
diff --git a/mpdf/font/chelveticabi.php b/mpdf/font/chelveticabi.php
new file mode 100644
index 0000000..5a69900
--- /dev/null
+++ b/mpdf/font/chelveticabi.php
@@ -0,0 +1,22 @@
+278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
+ chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>333,'"'=>474,'#'=>556,'$'=>556,'%'=>889,'&'=>722,'\''=>238,'('=>333,')'=>333,'*'=>389,'+'=>584,
+ ','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>333,';'=>333,'<'=>584,'='=>584,'>'=>584,'?'=>611,'@'=>975,'A'=>722,
+ 'B'=>722,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>556,'K'=>722,'L'=>611,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
+ 'X'=>667,'Y'=>667,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>584,'_'=>556,'`'=>333,'a'=>556,'b'=>611,'c'=>556,'d'=>611,'e'=>556,'f'=>333,'g'=>611,'h'=>611,'i'=>278,'j'=>278,'k'=>556,'l'=>278,'m'=>889,
+ 'n'=>611,'o'=>611,'p'=>611,'q'=>611,'r'=>389,'s'=>556,'t'=>333,'u'=>611,'v'=>556,'w'=>778,'x'=>556,'y'=>556,'z'=>500,'{'=>389,'|'=>280,'}'=>389,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>278,chr(131)=>556,
+ chr(132)=>500,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>278,chr(146)=>278,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
+ chr(154)=>556,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>280,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
+ chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>611,chr(182)=>556,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722,
+ chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+ chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>556,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>611,chr(241)=>611,
+ chr(242)=>611,chr(243)=>611,chr(244)=>611,chr(245)=>611,chr(246)=>611,chr(247)=>584,chr(248)=>611,chr(249)=>611,chr(250)=>611,chr(251)=>611,chr(252)=>611,chr(253)=>556,chr(254)=>611,chr(255)=>556);
+
+//$desc=array('Ascent'=>718,'Descent'=>-207,'CapHeight'=>718,'FontBBox'=>'[-174 -228 1114 962]');
+$desc=array('Flags'=>96,'FontBBox'=>'[-174 -228 1114 962]','ItalicAngle'=>-12,'Ascent'=>962,'Descent'=>-228,'Leading'=>0,'CapHeight'=>718,'XHeight'=>532,'StemV'=>140,'StemH'=>118,'AvgWidth'=>535,'MaxWidth'=>1000,'MissingWidth'=>535);
+$up=-100;
+$ut=50;
+$kerninfo=array ( chr(49)=> array ( chr(49)=> -74, ), chr(65)=> array ( chr(84)=> -74, chr(86)=> -74, chr(87)=> -55, chr(89)=> -74, chr(146)=> -55, ), chr(70)=> array ( chr(44)=> -110, chr(46)=> -110, chr(65)=> -55, ), chr(76)=> array ( chr(84)=> -74, chr(86)=> -55, chr(87)=> -55, chr(89)=> -74, chr(146)=> -74, ), chr(80)=> array ( chr(44)=> -128, chr(46)=> -128, chr(65)=> -74, ), chr(82)=> array ( chr(84)=> -18, chr(87)=> -18, chr(89)=> -18, ), chr(84)=> array ( chr(44)=> -74, chr(46)=> -74, chr(58)=> -74, chr(65)=> -74, chr(79)=> -18, chr(97)=> -37, chr(99)=> -37, chr(101)=> -37, chr(105)=> -18, chr(111)=> -37, chr(114)=> -18, chr(115)=> -37, chr(117)=> -18, chr(119)=> -37, chr(121)=> -37, ), chr(86)=> array ( chr(44)=> -91, chr(46)=> -91, chr(58)=> -37, chr(65)=> -74, chr(97)=> -37, chr(101)=> -37, chr(105)=> -37, chr(111)=> -37, chr(114)=> -18, chr(117)=> -18, chr(121)=> -18, ), chr(87)=> array ( chr(44)=> -74, chr(46)=> -74, chr(58)=> -37, chr(65)=> -55, chr(97)=> -18, chr(101)=> -18, chr(105)=> -8, chr(111)=> -18, chr(114)=> -18, chr(117)=> -18, chr(121)=> -18, ), chr(89)=> array ( chr(44)=> -91, chr(46)=> -91, chr(58)=> -55, chr(65)=> -74, chr(97)=> -37, chr(101)=> -37, chr(105)=> -37, chr(111)=> -37, chr(112)=> -37, chr(113)=> -37, chr(117)=> -37, chr(118)=> -37, ), chr(102)=> array ( chr(102)=> -18, chr(146)=> 18, ), chr(114)=> array ( chr(44)=> -55, chr(46)=> -55, chr(146)=> 37, ), chr(118)=> array ( chr(44)=> -55, chr(46)=> -55, ), chr(119)=> array ( chr(44)=> -37, chr(46)=> -37, ), chr(121)=> array ( chr(44)=> -37, chr(46)=> -37, ), chr(145)=> array ( chr(145)=> -37, ), chr(146)=> array ( chr(115)=> -18, chr(116)=> 18, chr(146)=> -37, ), );
+
+?>
\ No newline at end of file
diff --git a/mpdf/font/chelveticai.php b/mpdf/font/chelveticai.php
new file mode 100644
index 0000000..206669e
--- /dev/null
+++ b/mpdf/font/chelveticai.php
@@ -0,0 +1,22 @@
+278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
+ chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>278,'"'=>355,'#'=>556,'$'=>556,'%'=>889,'&'=>667,'\''=>191,'('=>333,')'=>333,'*'=>389,'+'=>584,
+ ','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>278,';'=>278,'<'=>584,'='=>584,'>'=>584,'?'=>556,'@'=>1015,'A'=>667,
+ 'B'=>667,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>500,'K'=>667,'L'=>556,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944,
+ 'X'=>667,'Y'=>667,'Z'=>611,'['=>278,'\\'=>278,']'=>278,'^'=>469,'_'=>556,'`'=>333,'a'=>556,'b'=>556,'c'=>500,'d'=>556,'e'=>556,'f'=>278,'g'=>556,'h'=>556,'i'=>222,'j'=>222,'k'=>500,'l'=>222,'m'=>833,
+ 'n'=>556,'o'=>556,'p'=>556,'q'=>556,'r'=>333,'s'=>500,'t'=>278,'u'=>556,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>500,'{'=>334,'|'=>260,'}'=>334,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>222,chr(131)=>556,
+ chr(132)=>333,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>222,chr(146)=>222,chr(147)=>333,chr(148)=>333,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
+ chr(154)=>500,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>260,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333,
+ chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>556,chr(182)=>537,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>667,chr(193)=>667,chr(194)=>667,chr(195)=>667,chr(196)=>667,chr(197)=>667,
+ chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+ chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>500,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>556,chr(241)=>556,
+ chr(242)=>556,chr(243)=>556,chr(244)=>556,chr(245)=>556,chr(246)=>556,chr(247)=>584,chr(248)=>611,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>500,chr(254)=>556,chr(255)=>500);
+
+//$desc=array('Ascent'=>718,'Descent'=>-207,'CapHeight'=>718,'FontBBox'=>'[-170 -225 1116 931]');
+$desc=array('Flags'=>96,'FontBBox'=>'[-170 -225 1116 931]','ItalicAngle'=>-12,'Ascent'=>931,'Descent'=>-225,'Leading'=>0,'CapHeight'=>718,'XHeight'=>523,'StemV'=>88,'StemH'=>76,'AvgWidth'=>513,'MaxWidth'=>1015,'MissingWidth'=>513);
+$up=-100;
+$ut=50;
+$kerninfo=array ( chr(49)=> array ( chr(49)=> -74, ), chr(65)=> array ( chr(84)=> -74, chr(86)=> -55, chr(87)=> -18, chr(89)=> -74, chr(118)=> -18, chr(119)=> -18, chr(121)=> -8, chr(146)=> -37, ), chr(70)=> array ( chr(44)=> -128, chr(46)=> -128, chr(65)=> -74, ), chr(76)=> array ( chr(84)=> -74, chr(86)=> -55, chr(87)=> -37, chr(89)=> -91, chr(121)=> -18, chr(146)=> -55, ), chr(80)=> array ( chr(44)=> -128, chr(46)=> -128, chr(65)=> -74, ), chr(82)=> array ( chr(84)=> -18, chr(86)=> -18, chr(87)=> -18, chr(89)=> -37, ), chr(84)=> array ( chr(44)=> -91, chr(46)=> -91, chr(58)=> -74, chr(65)=> -74, chr(79)=> -18, chr(97)=> -91, chr(99)=> -91, chr(101)=> -91, chr(105)=> -8, chr(111)=> -91, chr(114)=> -74, chr(115)=> -91, chr(117)=> -74, chr(119)=> -74, chr(121)=> -74, ), chr(86)=> array ( chr(44)=> -74, chr(46)=> -74, chr(58)=> -18, chr(65)=> -55, chr(97)=> -37, chr(101)=> -37, chr(105)=> -18, chr(111)=> -37, chr(114)=> -18, chr(117)=> -18, chr(121)=> -18, ), chr(87)=> array ( chr(44)=> -37, chr(46)=> -37, chr(65)=> -18, chr(97)=> -18, chr(101)=> -18, chr(105)=> -8, ), chr(89)=> array ( chr(44)=> -91, chr(46)=> -91, chr(58)=> -37, chr(65)=> -55, chr(97)=> -74, chr(101)=> -55, chr(105)=> -18, chr(111)=> -55, chr(112)=> -55, chr(113)=> -55, chr(117)=> -37, chr(118)=> -37, ), chr(102)=> array ( chr(146)=> 37, ), chr(114)=> array ( chr(44)=> -55, chr(46)=> -37, chr(146)=> 37, ), chr(118)=> array ( chr(44)=> -74, chr(46)=> -74, ), chr(119)=> array ( chr(44)=> -55, chr(46)=> -55, ), chr(121)=> array ( chr(44)=> -74, chr(46)=> -74, ), chr(145)=> array ( chr(145)=> -37, ), chr(146)=> array ( chr(115)=> -18, chr(146)=> -37, ), );
+
+?>
\ No newline at end of file
diff --git a/mpdf/font/csymbol.php b/mpdf/font/csymbol.php
new file mode 100644
index 0000000..2345f01
--- /dev/null
+++ b/mpdf/font/csymbol.php
@@ -0,0 +1,22 @@
+250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250,
+ chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>713,'#'=>500,'$'=>549,'%'=>833,'&'=>778,'\''=>439,'('=>333,')'=>333,'*'=>500,'+'=>549,
+ ','=>250,'-'=>549,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>278,';'=>278,'<'=>549,'='=>549,'>'=>549,'?'=>444,'@'=>549,'A'=>722,
+ 'B'=>667,'C'=>722,'D'=>612,'E'=>611,'F'=>763,'G'=>603,'H'=>722,'I'=>333,'J'=>631,'K'=>722,'L'=>686,'M'=>889,'N'=>722,'O'=>722,'P'=>768,'Q'=>741,'R'=>556,'S'=>592,'T'=>611,'U'=>690,'V'=>439,'W'=>768,
+ 'X'=>645,'Y'=>795,'Z'=>611,'['=>333,'\\'=>863,']'=>333,'^'=>658,'_'=>500,'`'=>500,'a'=>631,'b'=>549,'c'=>549,'d'=>494,'e'=>439,'f'=>521,'g'=>411,'h'=>603,'i'=>329,'j'=>603,'k'=>549,'l'=>549,'m'=>576,
+ 'n'=>521,'o'=>549,'p'=>549,'q'=>521,'r'=>549,'s'=>603,'t'=>439,'u'=>576,'v'=>713,'w'=>686,'x'=>493,'y'=>686,'z'=>494,'{'=>480,'|'=>200,'}'=>480,'~'=>549,chr(127)=>0,chr(128)=>0,chr(129)=>0,chr(130)=>0,chr(131)=>0,
+ chr(132)=>0,chr(133)=>0,chr(134)=>0,chr(135)=>0,chr(136)=>0,chr(137)=>0,chr(138)=>0,chr(139)=>0,chr(140)=>0,chr(141)=>0,chr(142)=>0,chr(143)=>0,chr(144)=>0,chr(145)=>0,chr(146)=>0,chr(147)=>0,chr(148)=>0,chr(149)=>0,chr(150)=>0,chr(151)=>0,chr(152)=>0,chr(153)=>0,
+ chr(154)=>0,chr(155)=>0,chr(156)=>0,chr(157)=>0,chr(158)=>0,chr(159)=>0,chr(160)=>750,chr(161)=>620,chr(162)=>247,chr(163)=>549,chr(164)=>167,chr(165)=>713,chr(166)=>500,chr(167)=>753,chr(168)=>753,chr(169)=>753,chr(170)=>753,chr(171)=>1042,chr(172)=>987,chr(173)=>603,chr(174)=>987,chr(175)=>603,
+ chr(176)=>400,chr(177)=>549,chr(178)=>411,chr(179)=>549,chr(180)=>549,chr(181)=>713,chr(182)=>494,chr(183)=>460,chr(184)=>549,chr(185)=>549,chr(186)=>549,chr(187)=>549,chr(188)=>1000,chr(189)=>603,chr(190)=>1000,chr(191)=>658,chr(192)=>823,chr(193)=>686,chr(194)=>795,chr(195)=>987,chr(196)=>768,chr(197)=>768,
+ chr(198)=>823,chr(199)=>768,chr(200)=>768,chr(201)=>713,chr(202)=>713,chr(203)=>713,chr(204)=>713,chr(205)=>713,chr(206)=>713,chr(207)=>713,chr(208)=>768,chr(209)=>713,chr(210)=>790,chr(211)=>790,chr(212)=>890,chr(213)=>823,chr(214)=>549,chr(215)=>250,chr(216)=>713,chr(217)=>603,chr(218)=>603,chr(219)=>1042,
+ chr(220)=>987,chr(221)=>603,chr(222)=>987,chr(223)=>603,chr(224)=>494,chr(225)=>329,chr(226)=>790,chr(227)=>790,chr(228)=>786,chr(229)=>713,chr(230)=>384,chr(231)=>384,chr(232)=>384,chr(233)=>384,chr(234)=>384,chr(235)=>384,chr(236)=>494,chr(237)=>494,chr(238)=>494,chr(239)=>494,chr(240)=>0,chr(241)=>329,
+ chr(242)=>274,chr(243)=>686,chr(244)=>686,chr(245)=>686,chr(246)=>384,chr(247)=>384,chr(248)=>384,chr(249)=>384,chr(250)=>384,chr(251)=>384,chr(252)=>494,chr(253)=>494,chr(254)=>494,chr(255)=>0);
+
+//$desc=array('FontBBox'=>'[-180 -293 1090 1010]');
+$desc=array('Flags'=>4,'FontBBox'=>'[-180 -293 1090 1010]','ItalicAngle'=>0,'Ascent'=>1010,'Descent'=>-293,'Leading'=>0,'CapHeight'=>1010,'StemV'=>85,'StemH'=>92,'AvgWidth'=>587,'MaxWidth'=>1042,'MissingWidth'=>587);
+$up=-100;
+$ut=50;
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/font/ctimes.php b/mpdf/font/ctimes.php
new file mode 100644
index 0000000..9530798
--- /dev/null
+++ b/mpdf/font/ctimes.php
@@ -0,0 +1,22 @@
+250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250,
+ chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>408,'#'=>500,'$'=>500,'%'=>833,'&'=>778,'\''=>180,'('=>333,')'=>333,'*'=>500,'+'=>564,
+ ','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>278,';'=>278,'<'=>564,'='=>564,'>'=>564,'?'=>444,'@'=>921,'A'=>722,
+ 'B'=>667,'C'=>667,'D'=>722,'E'=>611,'F'=>556,'G'=>722,'H'=>722,'I'=>333,'J'=>389,'K'=>722,'L'=>611,'M'=>889,'N'=>722,'O'=>722,'P'=>556,'Q'=>722,'R'=>667,'S'=>556,'T'=>611,'U'=>722,'V'=>722,'W'=>944,
+ 'X'=>722,'Y'=>722,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>469,'_'=>500,'`'=>333,'a'=>444,'b'=>500,'c'=>444,'d'=>500,'e'=>444,'f'=>333,'g'=>500,'h'=>500,'i'=>278,'j'=>278,'k'=>500,'l'=>278,'m'=>778,
+ 'n'=>500,'o'=>500,'p'=>500,'q'=>500,'r'=>333,'s'=>389,'t'=>278,'u'=>500,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>444,'{'=>480,'|'=>200,'}'=>480,'~'=>541,chr(127)=>350,chr(128)=>500,chr(129)=>350,chr(130)=>333,chr(131)=>500,
+ chr(132)=>444,chr(133)=>1000,chr(134)=>500,chr(135)=>500,chr(136)=>333,chr(137)=>1000,chr(138)=>556,chr(139)=>333,chr(140)=>889,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>333,chr(146)=>333,chr(147)=>444,chr(148)=>444,chr(149)=>350,chr(150)=>500,chr(151)=>1000,chr(152)=>333,chr(153)=>980,
+ chr(154)=>389,chr(155)=>333,chr(156)=>722,chr(157)=>350,chr(158)=>444,chr(159)=>722,chr(160)=>250,chr(161)=>333,chr(162)=>500,chr(163)=>500,chr(164)=>500,chr(165)=>500,chr(166)=>200,chr(167)=>500,chr(168)=>333,chr(169)=>760,chr(170)=>276,chr(171)=>500,chr(172)=>564,chr(173)=>333,chr(174)=>760,chr(175)=>333,
+ chr(176)=>400,chr(177)=>564,chr(178)=>300,chr(179)=>300,chr(180)=>333,chr(181)=>500,chr(182)=>453,chr(183)=>250,chr(184)=>333,chr(185)=>300,chr(186)=>310,chr(187)=>500,chr(188)=>750,chr(189)=>750,chr(190)=>750,chr(191)=>444,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722,
+ chr(198)=>889,chr(199)=>667,chr(200)=>611,chr(201)=>611,chr(202)=>611,chr(203)=>611,chr(204)=>333,chr(205)=>333,chr(206)=>333,chr(207)=>333,chr(208)=>722,chr(209)=>722,chr(210)=>722,chr(211)=>722,chr(212)=>722,chr(213)=>722,chr(214)=>722,chr(215)=>564,chr(216)=>722,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+ chr(220)=>722,chr(221)=>722,chr(222)=>556,chr(223)=>500,chr(224)=>444,chr(225)=>444,chr(226)=>444,chr(227)=>444,chr(228)=>444,chr(229)=>444,chr(230)=>667,chr(231)=>444,chr(232)=>444,chr(233)=>444,chr(234)=>444,chr(235)=>444,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>500,chr(241)=>500,
+ chr(242)=>500,chr(243)=>500,chr(244)=>500,chr(245)=>500,chr(246)=>500,chr(247)=>564,chr(248)=>500,chr(249)=>500,chr(250)=>500,chr(251)=>500,chr(252)=>500,chr(253)=>500,chr(254)=>500,chr(255)=>500);
+
+//$desc=array('Ascent'=>683,'Descent'=>-217,'CapHeight'=>662,'FontBBox'=>'[-168 -218 1000 898]');
+$desc=array('Flags'=>32,'FontBBox'=>'[-168 -218 1000 898]','ItalicAngle'=>0,'Ascent'=>898,'Descent'=>-218,'Leading'=>0,'CapHeight'=>662,'XHeight'=>450,'StemV'=>84,'StemH'=>28,'AvgWidth'=>495,'MaxWidth'=>1000,'MissingWidth'=>495);
+$up=-100;
+$ut=50;
+$kerninfo=array ( chr(49)=> array ( chr(49)=> -37, ), chr(65)=> array ( chr(84)=> -110, chr(86)=> -128, chr(87)=> -80, chr(89)=> -91, chr(118)=> -74, chr(119)=> -91, chr(121)=> -91, chr(146)=> -110, ), chr(70)=> array ( chr(44)=> -80, chr(46)=> -80, chr(65)=> -74, ), chr(76)=> array ( chr(84)=> -91, chr(86)=> -91, chr(87)=> -74, chr(89)=> -100, chr(121)=> -55, chr(146)=> -91, ), chr(80)=> array ( chr(44)=> -110, chr(46)=> -110, chr(65)=> -91, ), chr(82)=> array ( chr(84)=> -60, chr(86)=> -80, chr(87)=> -55, chr(89)=> -55, chr(121)=> -40, ), chr(84)=> array ( chr(44)=> -74, chr(46)=> -74, chr(58)=> -49, chr(65)=> -80, chr(79)=> -18, chr(97)=> -69, chr(99)=> -69, chr(101)=> -69, chr(105)=> -35, chr(111)=> -69, chr(114)=> -35, chr(115)=> -69, chr(117)=> -35, chr(119)=> -69, chr(121)=> -69, ), chr(86)=> array ( chr(44)=> -128, chr(46)=> -128, chr(58)=> -74, chr(65)=> -128, chr(97)=> -110, chr(101)=> -110, chr(105)=> -60, chr(111)=> -128, chr(114)=> -60, chr(117)=> -60, chr(121)=> -110, ), chr(87)=> array ( chr(44)=> -91, chr(46)=> -91, chr(58)=> -37, chr(65)=> -110, chr(97)=> -80, chr(101)=> -80, chr(105)=> -40, chr(111)=> -80, chr(114)=> -40, chr(117)=> -40, chr(121)=> -60, ), chr(89)=> array ( chr(44)=> -128, chr(46)=> -128, chr(58)=> -91, chr(65)=> -110, chr(97)=> -100, chr(101)=> -100, chr(105)=> -55, chr(111)=> -100, chr(112)=> -91, chr(113)=> -110, chr(117)=> -110, chr(118)=> -100, ), chr(102)=> array ( chr(102)=> -18, chr(146)=> 55, ), chr(114)=> array ( chr(44)=> -40, chr(46)=> -55, chr(103)=> -18, chr(146)=> 37, ), chr(118)=> array ( chr(44)=> -64, chr(46)=> -64, ), chr(119)=> array ( chr(44)=> -64, chr(46)=> -64, ), chr(121)=> array ( chr(44)=> -64, chr(46)=> -64, ), chr(145)=> array ( chr(145)=> -74, ), chr(146)=> array ( chr(115)=> -55, chr(116)=> -18, chr(146)=> -74, ), );
+
+?>
\ No newline at end of file
diff --git a/mpdf/font/ctimesb.php b/mpdf/font/ctimesb.php
new file mode 100644
index 0000000..5cf517c
--- /dev/null
+++ b/mpdf/font/ctimesb.php
@@ -0,0 +1,22 @@
+250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250,
+ chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>555,'#'=>500,'$'=>500,'%'=>1000,'&'=>833,'\''=>278,'('=>333,')'=>333,'*'=>500,'+'=>570,
+ ','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>333,';'=>333,'<'=>570,'='=>570,'>'=>570,'?'=>500,'@'=>930,'A'=>722,
+ 'B'=>667,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>778,'I'=>389,'J'=>500,'K'=>778,'L'=>667,'M'=>944,'N'=>722,'O'=>778,'P'=>611,'Q'=>778,'R'=>722,'S'=>556,'T'=>667,'U'=>722,'V'=>722,'W'=>1000,
+ 'X'=>722,'Y'=>722,'Z'=>667,'['=>333,'\\'=>278,']'=>333,'^'=>581,'_'=>500,'`'=>333,'a'=>500,'b'=>556,'c'=>444,'d'=>556,'e'=>444,'f'=>333,'g'=>500,'h'=>556,'i'=>278,'j'=>333,'k'=>556,'l'=>278,'m'=>833,
+ 'n'=>556,'o'=>500,'p'=>556,'q'=>556,'r'=>444,'s'=>389,'t'=>333,'u'=>556,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>444,'{'=>394,'|'=>220,'}'=>394,'~'=>520,chr(127)=>350,chr(128)=>500,chr(129)=>350,chr(130)=>333,chr(131)=>500,
+ chr(132)=>500,chr(133)=>1000,chr(134)=>500,chr(135)=>500,chr(136)=>333,chr(137)=>1000,chr(138)=>556,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>667,chr(143)=>350,chr(144)=>350,chr(145)=>333,chr(146)=>333,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>500,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
+ chr(154)=>389,chr(155)=>333,chr(156)=>722,chr(157)=>350,chr(158)=>444,chr(159)=>722,chr(160)=>250,chr(161)=>333,chr(162)=>500,chr(163)=>500,chr(164)=>500,chr(165)=>500,chr(166)=>220,chr(167)=>500,chr(168)=>333,chr(169)=>747,chr(170)=>300,chr(171)=>500,chr(172)=>570,chr(173)=>333,chr(174)=>747,chr(175)=>333,
+ chr(176)=>400,chr(177)=>570,chr(178)=>300,chr(179)=>300,chr(180)=>333,chr(181)=>556,chr(182)=>540,chr(183)=>250,chr(184)=>333,chr(185)=>300,chr(186)=>330,chr(187)=>500,chr(188)=>750,chr(189)=>750,chr(190)=>750,chr(191)=>500,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722,
+ chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>389,chr(205)=>389,chr(206)=>389,chr(207)=>389,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>570,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+ chr(220)=>722,chr(221)=>722,chr(222)=>611,chr(223)=>556,chr(224)=>500,chr(225)=>500,chr(226)=>500,chr(227)=>500,chr(228)=>500,chr(229)=>500,chr(230)=>722,chr(231)=>444,chr(232)=>444,chr(233)=>444,chr(234)=>444,chr(235)=>444,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>500,chr(241)=>556,
+ chr(242)=>500,chr(243)=>500,chr(244)=>500,chr(245)=>500,chr(246)=>500,chr(247)=>570,chr(248)=>500,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>500,chr(254)=>556,chr(255)=>500);
+
+//$desc=array('Ascent'=>683,'Descent'=>-217,'CapHeight'=>676,'FontBBox'=>'[-168 -218 1000 935]');
+$desc=array('Flags'=>32,'FontBBox'=>'[-168 -218 1000 935]','ItalicAngle'=>0,'Ascent'=>935,'Descent'=>-218,'Leading'=>0,'CapHeight'=>676,'XHeight'=>461,'StemV'=>139,'StemH'=>44,'AvgWidth'=>516,'MaxWidth'=>1000,'MissingWidth'=>516);
+$up=-100;
+$ut=50;
+$kerninfo=array ( chr(49)=> array ( chr(49)=> -55, ), chr(65)=> array ( chr(84)=> -74, chr(86)=> -128, chr(87)=> -110, chr(89)=> -91, chr(118)=> -74, chr(119)=> -74, chr(121)=> -74, chr(146)=> -74, ), chr(70)=> array ( chr(44)=> -91, chr(46)=> -91, chr(65)=> -74, ), chr(76)=> array ( chr(84)=> -91, chr(86)=> -91, chr(87)=> -91, chr(89)=> -91, chr(121)=> -55, chr(146)=> -91, ), chr(80)=> array ( chr(44)=> -91, chr(46)=> -91, chr(65)=> -74, ), chr(82)=> array ( chr(84)=> -35, chr(86)=> -35, chr(87)=> -35, chr(89)=> -35, chr(121)=> -35, ), chr(84)=> array ( chr(44)=> -74, chr(46)=> -74, chr(58)=> -74, chr(65)=> -74, chr(79)=> -18, chr(97)=> -91, chr(99)=> -91, chr(101)=> -91, chr(105)=> -18, chr(111)=> -91, chr(114)=> -74, chr(115)=> -91, chr(117)=> -91, chr(119)=> -74, chr(121)=> -74, ), chr(86)=> array ( chr(44)=> -128, chr(46)=> -128, chr(58)=> -91, chr(65)=> -128, chr(79)=> -20, chr(97)=> -91, chr(101)=> -91, chr(105)=> -37, chr(111)=> -91, chr(114)=> -74, chr(117)=> -91, chr(121)=> -91, ), chr(87)=> array ( chr(44)=> -91, chr(46)=> -91, chr(58)=> -55, chr(65)=> -110, chr(97)=> -55, chr(101)=> -55, chr(105)=> -18, chr(111)=> -55, chr(114)=> -18, chr(117)=> -18, chr(121)=> -37, ), chr(89)=> array ( chr(44)=> -91, chr(46)=> -91, chr(58)=> -91, chr(65)=> -91, chr(97)=> -110, chr(101)=> -110, chr(105)=> -37, chr(111)=> -110, chr(112)=> -91, chr(113)=> -110, chr(117)=> -91, chr(118)=> -110, ), chr(102)=> array ( chr(102)=> 0, chr(146)=> 55, ), chr(114)=> array ( chr(44)=> -91, chr(46)=> -91, chr(99)=> -18, chr(101)=> -18, chr(104)=> 0, chr(111)=> -18, chr(113)=> -18, chr(116)=> 0, chr(119)=> 0, chr(120)=> 0, chr(121)=> 0, chr(122)=> 0, chr(146)=> 18, ), chr(118)=> array ( chr(44)=> -55, chr(46)=> -55, ), chr(119)=> array ( chr(44)=> -55, chr(46)=> -55, ), chr(121)=> array ( chr(44)=> -55, chr(46)=> -55, ), chr(145)=> array ( chr(145)=> -74, ), chr(146)=> array ( chr(115)=> -37, chr(146)=> -74, ), );
+
+?>
\ No newline at end of file
diff --git a/mpdf/font/ctimesbi.php b/mpdf/font/ctimesbi.php
new file mode 100644
index 0000000..d6a297f
--- /dev/null
+++ b/mpdf/font/ctimesbi.php
@@ -0,0 +1,22 @@
+250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250,
+ chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>389,'"'=>555,'#'=>500,'$'=>500,'%'=>833,'&'=>778,'\''=>278,'('=>333,')'=>333,'*'=>500,'+'=>570,
+ ','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>333,';'=>333,'<'=>570,'='=>570,'>'=>570,'?'=>500,'@'=>832,'A'=>667,
+ 'B'=>667,'C'=>667,'D'=>722,'E'=>667,'F'=>667,'G'=>722,'H'=>778,'I'=>389,'J'=>500,'K'=>667,'L'=>611,'M'=>889,'N'=>722,'O'=>722,'P'=>611,'Q'=>722,'R'=>667,'S'=>556,'T'=>611,'U'=>722,'V'=>667,'W'=>889,
+ 'X'=>667,'Y'=>611,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>570,'_'=>500,'`'=>333,'a'=>500,'b'=>500,'c'=>444,'d'=>500,'e'=>444,'f'=>333,'g'=>500,'h'=>556,'i'=>278,'j'=>278,'k'=>500,'l'=>278,'m'=>778,
+ 'n'=>556,'o'=>500,'p'=>500,'q'=>500,'r'=>389,'s'=>389,'t'=>278,'u'=>556,'v'=>444,'w'=>667,'x'=>500,'y'=>444,'z'=>389,'{'=>348,'|'=>220,'}'=>348,'~'=>570,chr(127)=>350,chr(128)=>500,chr(129)=>350,chr(130)=>333,chr(131)=>500,
+ chr(132)=>500,chr(133)=>1000,chr(134)=>500,chr(135)=>500,chr(136)=>333,chr(137)=>1000,chr(138)=>556,chr(139)=>333,chr(140)=>944,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>333,chr(146)=>333,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>500,chr(151)=>1000,chr(152)=>333,chr(153)=>1000,
+ chr(154)=>389,chr(155)=>333,chr(156)=>722,chr(157)=>350,chr(158)=>389,chr(159)=>611,chr(160)=>250,chr(161)=>389,chr(162)=>500,chr(163)=>500,chr(164)=>500,chr(165)=>500,chr(166)=>220,chr(167)=>500,chr(168)=>333,chr(169)=>747,chr(170)=>266,chr(171)=>500,chr(172)=>606,chr(173)=>333,chr(174)=>747,chr(175)=>333,
+ chr(176)=>400,chr(177)=>570,chr(178)=>300,chr(179)=>300,chr(180)=>333,chr(181)=>576,chr(182)=>500,chr(183)=>250,chr(184)=>333,chr(185)=>300,chr(186)=>300,chr(187)=>500,chr(188)=>750,chr(189)=>750,chr(190)=>750,chr(191)=>500,chr(192)=>667,chr(193)=>667,chr(194)=>667,chr(195)=>667,chr(196)=>667,chr(197)=>667,
+ chr(198)=>944,chr(199)=>667,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>389,chr(205)=>389,chr(206)=>389,chr(207)=>389,chr(208)=>722,chr(209)=>722,chr(210)=>722,chr(211)=>722,chr(212)=>722,chr(213)=>722,chr(214)=>722,chr(215)=>570,chr(216)=>722,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+ chr(220)=>722,chr(221)=>611,chr(222)=>611,chr(223)=>500,chr(224)=>500,chr(225)=>500,chr(226)=>500,chr(227)=>500,chr(228)=>500,chr(229)=>500,chr(230)=>722,chr(231)=>444,chr(232)=>444,chr(233)=>444,chr(234)=>444,chr(235)=>444,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>500,chr(241)=>556,
+ chr(242)=>500,chr(243)=>500,chr(244)=>500,chr(245)=>500,chr(246)=>500,chr(247)=>570,chr(248)=>500,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>444,chr(254)=>500,chr(255)=>444);
+
+//$desc=array('Ascent'=>683,'Descent'=>-217,'CapHeight'=>669,'FontBBox'=>'[-200 -218 996 921]');
+$desc=array('Flags'=>96,'FontBBox'=>'[-200 -218 996 921]','ItalicAngle'=>-15,'Ascent'=>921,'Descent'=>-218,'Leading'=>0,'CapHeight'=>669,'XHeight'=>462,'StemV'=>121,'StemH'=>42,'AvgWidth'=>501,'MaxWidth'=>1000,'MissingWidth'=>501);
+$up=-100;
+$ut=50;
+$kerninfo=array ( chr(49)=> array ( chr(49)=> -55, ), chr(65)=> array ( chr(84)=> -55, chr(86)=> -74, chr(87)=> -91, chr(89)=> -55, chr(118)=> -74, chr(119)=> -74, chr(121)=> -74, chr(146)=> -74, ), chr(70)=> array ( chr(44)=> -128, chr(46)=> -128, chr(65)=> -91, ), chr(76)=> array ( chr(84)=> -18, chr(86)=> -37, chr(87)=> -37, chr(89)=> -37, chr(121)=> -37, chr(146)=> -55, ), chr(80)=> array ( chr(44)=> -128, chr(46)=> -128, chr(65)=> -74, ), chr(82)=> array ( chr(86)=> -18, chr(87)=> -18, chr(89)=> -18, chr(121)=> -18, ), chr(84)=> array ( chr(44)=> -91, chr(46)=> -91, chr(58)=> -74, chr(65)=> -55, chr(79)=> -18, chr(97)=> -91, chr(99)=> -91, chr(101)=> -91, chr(105)=> -37, chr(111)=> -91, chr(114)=> -37, chr(115)=> -91, chr(117)=> -37, chr(119)=> -37, chr(121)=> -37, ), chr(86)=> array ( chr(44)=> -128, chr(46)=> -128, chr(58)=> -74, chr(65)=> -74, chr(97)=> -110, chr(101)=> -110, chr(105)=> -55, chr(111)=> -110, chr(114)=> -55, chr(117)=> -55, chr(121)=> -74, ), chr(87)=> array ( chr(44)=> -74, chr(46)=> -74, chr(58)=> -55, chr(65)=> -74, chr(97)=> -74, chr(101)=> -74, chr(105)=> -37, chr(111)=> -74, chr(114)=> -74, chr(117)=> -55, chr(121)=> -55, ), chr(89)=> array ( chr(44)=> -91, chr(46)=> -74, chr(58)=> -91, chr(65)=> -74, chr(97)=> -91, chr(101)=> -110, chr(105)=> -55, chr(111)=> -110, chr(112)=> -74, chr(113)=> -110, chr(117)=> -91, chr(118)=> -91, ), chr(102)=> array ( chr(102)=> -18, chr(146)=> 55, ), chr(114)=> array ( chr(44)=> -55, chr(46)=> -55, chr(146)=> 37, ), chr(118)=> array ( chr(44)=> -37, chr(46)=> -37, ), chr(119)=> array ( chr(44)=> -37, chr(46)=> -37, ), chr(121)=> array ( chr(44)=> -37, chr(46)=> -37, ), chr(145)=> array ( chr(145)=> -74, ), chr(146)=> array ( chr(115)=> -74, chr(116)=> -37, chr(146)=> -74, ), );
+
+?>
\ No newline at end of file
diff --git a/mpdf/font/ctimesi.php b/mpdf/font/ctimesi.php
new file mode 100644
index 0000000..a6859e7
--- /dev/null
+++ b/mpdf/font/ctimesi.php
@@ -0,0 +1,22 @@
+250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250,
+ chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>420,'#'=>500,'$'=>500,'%'=>833,'&'=>778,'\''=>214,'('=>333,')'=>333,'*'=>500,'+'=>675,
+ ','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>333,';'=>333,'<'=>675,'='=>675,'>'=>675,'?'=>500,'@'=>920,'A'=>611,
+ 'B'=>611,'C'=>667,'D'=>722,'E'=>611,'F'=>611,'G'=>722,'H'=>722,'I'=>333,'J'=>444,'K'=>667,'L'=>556,'M'=>833,'N'=>667,'O'=>722,'P'=>611,'Q'=>722,'R'=>611,'S'=>500,'T'=>556,'U'=>722,'V'=>611,'W'=>833,
+ 'X'=>611,'Y'=>556,'Z'=>556,'['=>389,'\\'=>278,']'=>389,'^'=>422,'_'=>500,'`'=>333,'a'=>500,'b'=>500,'c'=>444,'d'=>500,'e'=>444,'f'=>278,'g'=>500,'h'=>500,'i'=>278,'j'=>278,'k'=>444,'l'=>278,'m'=>722,
+ 'n'=>500,'o'=>500,'p'=>500,'q'=>500,'r'=>389,'s'=>389,'t'=>278,'u'=>500,'v'=>444,'w'=>667,'x'=>444,'y'=>444,'z'=>389,'{'=>400,'|'=>275,'}'=>400,'~'=>541,chr(127)=>350,chr(128)=>500,chr(129)=>350,chr(130)=>333,chr(131)=>500,
+ chr(132)=>556,chr(133)=>889,chr(134)=>500,chr(135)=>500,chr(136)=>333,chr(137)=>1000,chr(138)=>500,chr(139)=>333,chr(140)=>944,chr(141)=>350,chr(142)=>556,chr(143)=>350,chr(144)=>350,chr(145)=>333,chr(146)=>333,chr(147)=>556,chr(148)=>556,chr(149)=>350,chr(150)=>500,chr(151)=>889,chr(152)=>333,chr(153)=>980,
+ chr(154)=>389,chr(155)=>333,chr(156)=>667,chr(157)=>350,chr(158)=>389,chr(159)=>556,chr(160)=>250,chr(161)=>389,chr(162)=>500,chr(163)=>500,chr(164)=>500,chr(165)=>500,chr(166)=>275,chr(167)=>500,chr(168)=>333,chr(169)=>760,chr(170)=>276,chr(171)=>500,chr(172)=>675,chr(173)=>333,chr(174)=>760,chr(175)=>333,
+ chr(176)=>400,chr(177)=>675,chr(178)=>300,chr(179)=>300,chr(180)=>333,chr(181)=>500,chr(182)=>523,chr(183)=>250,chr(184)=>333,chr(185)=>300,chr(186)=>310,chr(187)=>500,chr(188)=>750,chr(189)=>750,chr(190)=>750,chr(191)=>500,chr(192)=>611,chr(193)=>611,chr(194)=>611,chr(195)=>611,chr(196)=>611,chr(197)=>611,
+ chr(198)=>889,chr(199)=>667,chr(200)=>611,chr(201)=>611,chr(202)=>611,chr(203)=>611,chr(204)=>333,chr(205)=>333,chr(206)=>333,chr(207)=>333,chr(208)=>722,chr(209)=>667,chr(210)=>722,chr(211)=>722,chr(212)=>722,chr(213)=>722,chr(214)=>722,chr(215)=>675,chr(216)=>722,chr(217)=>722,chr(218)=>722,chr(219)=>722,
+ chr(220)=>722,chr(221)=>556,chr(222)=>611,chr(223)=>500,chr(224)=>500,chr(225)=>500,chr(226)=>500,chr(227)=>500,chr(228)=>500,chr(229)=>500,chr(230)=>667,chr(231)=>444,chr(232)=>444,chr(233)=>444,chr(234)=>444,chr(235)=>444,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>500,chr(241)=>500,
+ chr(242)=>500,chr(243)=>500,chr(244)=>500,chr(245)=>500,chr(246)=>500,chr(247)=>675,chr(248)=>500,chr(249)=>500,chr(250)=>500,chr(251)=>500,chr(252)=>500,chr(253)=>444,chr(254)=>500,chr(255)=>444);
+
+//$desc=array('Ascent'=>683,'Descent'=>-217,'CapHeight'=>653,'FontBBox'=>'[-169 -217 1010 883]');
+$desc=array('Flags'=>96,'FontBBox'=>'[-169 -217 1010 883]','ItalicAngle'=>-15.5,'Ascent'=>883,'Descent'=>-217,'Leading'=>0,'CapHeight'=>653,'XHeight'=>441,'StemV'=>76,'StemH'=>32,'AvgWidth'=>491,'MaxWidth'=>1000,'MissingWidth'=>491);
+$up=-100;
+$ut=50;
+$kerninfo=array ( chr(49)=> array ( chr(49)=> -74, ), chr(65)=> array ( chr(84)=> -37, chr(86)=> -49, chr(87)=> -37, chr(89)=> -55, chr(118)=> -55, chr(119)=> -55, chr(121)=> -55, chr(146)=> -37, ), chr(70)=> array ( chr(44)=> -128, chr(46)=> -128, chr(65)=> -128, ), chr(76)=> array ( chr(84)=> -20, chr(86)=> -37, chr(87)=> -37, chr(89)=> -20, chr(121)=> -29, chr(146)=> -37, ), chr(80)=> array ( chr(44)=> -128, chr(46)=> -128, chr(65)=> -128, ), chr(82)=> array ( chr(84)=> 0, chr(86)=> -18, chr(87)=> -18, chr(89)=> -18, chr(121)=> -18, ), chr(84)=> array ( chr(44)=> -74, chr(46)=> -74, chr(58)=> -55, chr(65)=> -74, chr(79)=> -18, chr(97)=> -91, chr(99)=> -91, chr(101)=> -91, chr(105)=> -55, chr(111)=> -91, chr(114)=> -55, chr(115)=> -91, chr(117)=> -55, chr(119)=> -74, chr(121)=> -74, ), chr(86)=> array ( chr(44)=> -128, chr(46)=> -128, chr(58)=> -64, chr(65)=> -74, chr(79)=> -29, chr(97)=> -110, chr(101)=> -110, chr(105)=> -74, chr(111)=> -110, chr(114)=> -74, chr(117)=> -74, chr(121)=> -91, ), chr(87)=> array ( chr(44)=> -91, chr(46)=> -91, chr(58)=> -64, chr(65)=> -69, chr(97)=> -91, chr(101)=> -91, chr(105)=> -55, chr(111)=> -91, chr(114)=> -55, chr(117)=> -55, chr(121)=> -91, ), chr(89)=> array ( chr(44)=> -91, chr(46)=> -91, chr(58)=> -64, chr(65)=> -69, chr(97)=> -91, chr(101)=> -91, chr(105)=> -74, chr(111)=> -91, chr(112)=> -91, chr(113)=> -110, chr(117)=> -91, chr(118)=> -91, ), chr(102)=> array ( chr(146)=> 91, ), chr(114)=> array ( chr(44)=> -110, chr(46)=> -110, chr(99)=> -37, chr(100)=> -37, chr(101)=> -37, chr(103)=> -37, chr(104)=> -18, chr(111)=> -37, chr(113)=> -37, chr(114)=> 0, chr(116)=> 0, chr(117)=> 0, chr(118)=> 0, chr(119)=> 0, chr(120)=> 0, chr(121)=> 0, chr(146)=> 37, ), chr(118)=> array ( chr(44)=> -74, chr(46)=> -74, ), chr(119)=> array ( chr(44)=> -74, chr(46)=> -74, ), chr(121)=> array ( chr(44)=> -55, chr(46)=> -55, ), chr(145)=> array ( chr(145)=> -110, ), chr(146)=> array ( chr(115)=> -128, chr(116)=> -110, chr(146)=> -110, ), );
+
+?>
\ No newline at end of file
diff --git a/mpdf/font/czapfdingbats.php b/mpdf/font/czapfdingbats.php
new file mode 100644
index 0000000..86cea38
--- /dev/null
+++ b/mpdf/font/czapfdingbats.php
@@ -0,0 +1,22 @@
+0,chr(1)=>0,chr(2)=>0,chr(3)=>0,chr(4)=>0,chr(5)=>0,chr(6)=>0,chr(7)=>0,chr(8)=>0,chr(9)=>0,chr(10)=>0,chr(11)=>0,chr(12)=>0,chr(13)=>0,chr(14)=>0,chr(15)=>0,chr(16)=>0,chr(17)=>0,chr(18)=>0,chr(19)=>0,chr(20)=>0,chr(21)=>0,
+ chr(22)=>0,chr(23)=>0,chr(24)=>0,chr(25)=>0,chr(26)=>0,chr(27)=>0,chr(28)=>0,chr(29)=>0,chr(30)=>0,chr(31)=>0,' '=>278,'!'=>974,'"'=>961,'#'=>974,'$'=>980,'%'=>719,'&'=>789,'\''=>790,'('=>791,')'=>690,'*'=>960,'+'=>939,
+ ','=>549,'-'=>855,'.'=>911,'/'=>933,'0'=>911,'1'=>945,'2'=>974,'3'=>755,'4'=>846,'5'=>762,'6'=>761,'7'=>571,'8'=>677,'9'=>763,':'=>760,';'=>759,'<'=>754,'='=>494,'>'=>552,'?'=>537,'@'=>577,'A'=>692,
+ 'B'=>786,'C'=>788,'D'=>788,'E'=>790,'F'=>793,'G'=>794,'H'=>816,'I'=>823,'J'=>789,'K'=>841,'L'=>823,'M'=>833,'N'=>816,'O'=>831,'P'=>923,'Q'=>744,'R'=>723,'S'=>749,'T'=>790,'U'=>792,'V'=>695,'W'=>776,
+ 'X'=>768,'Y'=>792,'Z'=>759,'['=>707,'\\'=>708,']'=>682,'^'=>701,'_'=>826,'`'=>815,'a'=>789,'b'=>789,'c'=>707,'d'=>687,'e'=>696,'f'=>689,'g'=>786,'h'=>787,'i'=>713,'j'=>791,'k'=>785,'l'=>791,'m'=>873,
+ 'n'=>761,'o'=>762,'p'=>762,'q'=>759,'r'=>759,'s'=>892,'t'=>892,'u'=>788,'v'=>784,'w'=>438,'x'=>138,'y'=>277,'z'=>415,'{'=>392,'|'=>392,'}'=>668,'~'=>668,chr(127)=>0,chr(128)=>390,chr(129)=>390,chr(130)=>317,chr(131)=>317,
+ chr(132)=>276,chr(133)=>276,chr(134)=>509,chr(135)=>509,chr(136)=>410,chr(137)=>410,chr(138)=>234,chr(139)=>234,chr(140)=>334,chr(141)=>334,chr(142)=>0,chr(143)=>0,chr(144)=>0,chr(145)=>0,chr(146)=>0,chr(147)=>0,chr(148)=>0,chr(149)=>0,chr(150)=>0,chr(151)=>0,chr(152)=>0,chr(153)=>0,
+ chr(154)=>0,chr(155)=>0,chr(156)=>0,chr(157)=>0,chr(158)=>0,chr(159)=>0,chr(160)=>0,chr(161)=>732,chr(162)=>544,chr(163)=>544,chr(164)=>910,chr(165)=>667,chr(166)=>760,chr(167)=>760,chr(168)=>776,chr(169)=>595,chr(170)=>694,chr(171)=>626,chr(172)=>788,chr(173)=>788,chr(174)=>788,chr(175)=>788,
+ chr(176)=>788,chr(177)=>788,chr(178)=>788,chr(179)=>788,chr(180)=>788,chr(181)=>788,chr(182)=>788,chr(183)=>788,chr(184)=>788,chr(185)=>788,chr(186)=>788,chr(187)=>788,chr(188)=>788,chr(189)=>788,chr(190)=>788,chr(191)=>788,chr(192)=>788,chr(193)=>788,chr(194)=>788,chr(195)=>788,chr(196)=>788,chr(197)=>788,
+ chr(198)=>788,chr(199)=>788,chr(200)=>788,chr(201)=>788,chr(202)=>788,chr(203)=>788,chr(204)=>788,chr(205)=>788,chr(206)=>788,chr(207)=>788,chr(208)=>788,chr(209)=>788,chr(210)=>788,chr(211)=>788,chr(212)=>894,chr(213)=>838,chr(214)=>1016,chr(215)=>458,chr(216)=>748,chr(217)=>924,chr(218)=>748,chr(219)=>918,
+ chr(220)=>927,chr(221)=>928,chr(222)=>928,chr(223)=>834,chr(224)=>873,chr(225)=>828,chr(226)=>924,chr(227)=>924,chr(228)=>917,chr(229)=>930,chr(230)=>931,chr(231)=>463,chr(232)=>883,chr(233)=>836,chr(234)=>836,chr(235)=>867,chr(236)=>867,chr(237)=>696,chr(238)=>696,chr(239)=>874,chr(240)=>0,chr(241)=>874,
+ chr(242)=>760,chr(243)=>946,chr(244)=>771,chr(245)=>865,chr(246)=>771,chr(247)=>888,chr(248)=>967,chr(249)=>888,chr(250)=>831,chr(251)=>873,chr(252)=>927,chr(253)=>970,chr(254)=>918,chr(255)=>0);
+
+//$desc=array('FontBBox'=>'[-1 -143 981 820]');
+$desc=array('Flags'=>4,'FontBBox'=>'[-1 -143 981 820]','ItalicAngle'=>0,'Ascent'=>820,'Descent'=>-143,'Leading'=>0,'CapHeight'=>820,'StemV'=>90,'StemH'=>28,'AvgWidth'=>746,'MaxWidth'=>1016,'MissingWidth'=>746);
+$up=-100;
+$ut=50;
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/graph.php b/mpdf/graph.php
new file mode 100644
index 0000000..b2ae426
--- /dev/null
+++ b/mpdf/graph.php
@@ -0,0 +1,720 @@
+1 hrs old
+ $interval = 3600;
+ if ($handle = opendir(_MPDF_PATH.'graph_cache')) {
+ while (false !== ($file = readdir($handle))) {
+ if (((filemtime(_MPDF_PATH.'graph_cache/'.$file)+$interval) < time()) && ($file != "..") && ($file != ".")) {
+ @unlink(_MPDF_PATH.'graph_cache/'.$file); // mPDF 4.0
+ }
+ }
+ closedir($handle);
+ }
+//==============================================================================================================
+// LOAD GRAPHS
+
+ include_once(_JPGRAPH_PATH.'jpgraph.php');
+ include_once(_JPGRAPH_PATH.'jpgraph_line.php' );
+ include_once(_JPGRAPH_PATH.'jpgraph_log.php' );
+ include_once(_JPGRAPH_PATH.'jpgraph_scatter.php' );
+ include_once(_JPGRAPH_PATH.'jpgraph_regstat.php' );
+ include_once(_JPGRAPH_PATH.'jpgraph_pie.php');
+ include_once(_JPGRAPH_PATH.'jpgraph_pie3d.php');
+ include_once(_JPGRAPH_PATH.'jpgraph_bar.php');
+ include_once(_JPGRAPH_PATH.'jpgraph_radar.php');
+
+//======================================================================================================
+//*****************************************************************************************************
+//*****************************************************************************************************
+//*****************************************************************************************************
+//*****************************************************************************************************
+//*****************************************************************************************************
+//*****************************************************************************************************
+//======================================================================================================
+//======================================================================================================
+
+//======================================================================================================
+//======================================================================================================
+
+//======================================================================================================
+function print_graph($g,$pgwidth) {
+ $splines = false;
+ $bandw = false;
+ $percent = false;
+ $show_percent = false;
+ $stacked = false;
+ $h = false;
+ $show_values = false;
+ $hide_grid = false;
+ $hide_y_axis = false;
+
+ if (isset($g['attr']['TYPE']) && $g['attr']['TYPE']) { $type = strtolower($g['attr']['TYPE']); }
+ if (!in_array($type,array('bar','horiz_bar','line','radar','pie','pie3d','xy','scatter'))) { $type = 'bar'; } // Default=bar
+
+ if (isset($g['attr']['STACKED']) && $g['attr']['STACKED']) { $stacked = true; } // stacked for bar or horiz_bar
+ if (isset($g['attr']['SPLINES']) && $g['attr']['SPLINES'] && $type=='xy') { $splines = true; } // splines for XY line graphs
+ if (isset($g['attr']['BANDW']) && $g['attr']['BANDW']) { $bandw = true; } // black and white
+ if (isset($g['attr']['LEGEND-OVERLAP']) && $g['attr']['LEGEND-OVERLAP']) { $overlap = true; } // avoid overlap of Legends over graph (line, bar, horiz_bar only)
+ if (isset($g['attr']['PERCENT']) && $g['attr']['PERCENT'] && $type != 'xy' && $type != 'scatter') { $percent = true; } // Show data series as percent of total in series
+ if (isset($g['attr']['SHOW-VALUES']) && $g['attr']['SHOW-VALUES']) { $show_values = true; } // Show the individual data values
+ if (isset($g['attr']['HIDE-GRID']) && $g['attr']['HIDE-GRID']) { $hide_grid = true; } // Hide the y-axis gridlines
+ if (isset($g['attr']['HIDE-Y-AXIS']) && $g['attr']['HIDE-Y-AXIS']) { $hide_y_axis = true; } // Hide the y-axis
+
+
+ // Antialias: If true - better quality curves, but graph line will only be 1px even in PDF 300dpi
+ // default=true for most except line and radar
+ if (isset($g['attr']['ANTIALIAS']) && ($g['attr']['ANTIALIAS']=='' || $g['attr']['ANTIALIAS']==0)) { $antialias = false; }
+ else if (isset($g['attr']['ANTIALIAS']) && $g['attr']['ANTIALIAS'] > 0) { $antialias = true; }
+ else if ($type=='line' || $type=='radar') { $antialias = false; }
+ else { $antialias = true; }
+
+ if ($g['attr']['DPI']) { $dpi = intval($g['attr']['DPI']); }
+ if (!$dpi || $dpi < 50 || $dpi > 2400) { $dpi = 150; } // Default dpi 150
+ $k = (0.2645/25.4 * $dpi);
+
+ // mPDF 4.5.009
+ global $JpgUseSVGFormat;
+ if (isset($JpgUseSVGFormat) && $JpgUseSVGFormat) {
+ $img_type = 'svg';
+ $k = 1; // Overrides as Vector scale does not need DPI
+ }
+ else {
+ $img_type = 'png';
+ }
+
+ if (isset($g['attr']['TITLE']) && $g['attr']['TITLE']) { $title = $g['attr']['TITLE']; }
+
+ if (isset($g['attr']['LABEL-X']) && $g['attr']['LABEL-X']) { $xlabel = $g['attr']['LABEL-X']; } // NOT IMPLEMENTED??????
+ if (isset($g['attr']['LABEL-Y']) && $g['attr']['LABEL-Y']) { $ylabel = $g['attr']['LABEL-Y']; }
+
+ if (isset($g['attr']['AXIS-X']) && $g['attr']['AXIS-X']) { $xaxis = strtolower($g['attr']['AXIS-X']); }
+ if (!in_array($xaxis,array('text','lin','linear','log'))) { $xaxis = 'text'; } // Default=text
+ if ($xaxis == 'linear') { $xaxis = 'lin'; }
+
+ if (isset($g['attr']['AXIS-Y']) && $g['attr']['AXIS-Y']) { $yaxis = strtolower($g['attr']['AXIS-Y']); }
+ if (!in_array($yaxis,array('lin','linear','log','percent'))) { $yaxis = 'lin'; } // Default=lin
+ if ($yaxis == 'percent') { $show_percent = true; $yaxis = 'lin'; } // Show percent sign on scales
+ if ($yaxis == 'linear') { $yaxis = 'lin'; }
+
+ if ($splines) { $xaxis = 'lin'; }
+ $axes = $xaxis.$yaxis; // e.g.textlin, textlog, loglog, loglin, linlog (XY)
+
+ // mPDF 4.0
+ if (isset($g['attr']['cWIDTH']) && $g['attr']['cWIDTH']) { $w=($g['attr']['cWIDTH'] / 0.2645); } // pixels
+ if (isset($g['attr']['cHEIGHT']) && $g['attr']['cHEIGHT']) { $h=($g['attr']['cHEIGHT'] / 0.2645); }
+
+
+ if (isset($g['attr']['SERIES']) && strtolower($g['attr']['SERIES']) == 'rows') { $dataseries = 'rows'; }
+ else { $dataseries = 'cols'; }
+
+ // Defaults - define data
+ $rowbegin = 2;
+ $colbegin = 2;
+ if($type=='scatter' || $type=='xy') {
+ if ($dataseries == 'rows') { $rowbegin = 1; }
+ else { $colbegin = 1; }
+ }
+ $rowend = 0;
+ $colend = 0;
+
+ if (isset($g['attr']['DATA-ROW-BEGIN']) && ($g['attr']['DATA-ROW-BEGIN'] === '0' || $g['attr']['DATA-ROW-BEGIN'] > 0)) { $rowbegin = $g['attr']['DATA-ROW-BEGIN']; }
+
+ if (isset($g['attr']['DATA-COL-BEGIN']) && ($g['attr']['DATA-COL-BEGIN'] === '0' || $g['attr']['DATA-COL-BEGIN'] > 0)) { $colbegin = $g['attr']['DATA-COL-BEGIN']; }
+
+ if (isset($g['attr']['DATA-ROW-END']) && ($g['attr']['DATA-ROW-END'] === '0' || $g['attr']['DATA-ROW-END'] <> 0)) { $rowend = $g['attr']['DATA-ROW-END']; }
+ if (isset($g['attr']['DATA-COL-END']) && ($g['attr']['DATA-COL-END'] === '0' || $g['attr']['DATA-COL-END'] <> 0)) { $colend = $g['attr']['DATA-COL-END']; }
+
+ $nr = count($g['data']);
+ $nc = 0;
+ foreach($g['data'] AS $r) {
+ $cc=0;
+ foreach($r AS $c) { $cc++; }
+ $nc = max($nc,$cc);
+ }
+ if ($colend == 0) { $colend = $nc; }
+ else if ($colend < 0) { $colend = $nc+$colend; }
+
+ if ($rowend == 0) { $rowend = $nr; }
+ else if ($rowend < 0) { $rowend = $nr+$rowend; }
+
+ if ($colend < $colbegin) { $colend = $colbegin; }
+ if ($rowend < $rowbegin) { $rowend = $rowbegin; }
+
+// if ($type == 'xy' || $type=='scatter') { $colstart=0; }
+
+ // Get Data + Totals
+ $data = array();
+ $totals = array();
+ for ($r=($rowbegin-1);$r<$rowend;$r++) {
+ for ($c=($colbegin-1);$c<$colend;$c++) {
+ if (isset($g['data'][$r][$c])) { $g['data'][$r][$c] = floatval($g['data'][$r][$c] ); }
+ else { $g['data'][$r][$c] = 0; }
+ if ($dataseries=='rows') {
+ $data[($r+1-$rowbegin)][($c+1-$colbegin)] = $g['data'][$r][$c] ;
+ $totals[($r+1-$rowbegin)] += $g['data'][$r][$c] ;
+ }
+ else {
+ $data[($c+1-$colbegin)][($r+1-$rowbegin)] = $g['data'][$r][$c] ;
+ if (isset($totals[($c+1-$colbegin)])) { $totals[($c+1-$colbegin)] += $g['data'][$r][$c] ; }
+ else { $totals[($c+1-$colbegin)] = $g['data'][$r][$c] ; }
+ }
+ }
+ }
+ // PERCENT
+ if ($percent && $type != 'pie' && $type != 'pie3d') {
+ for ($r=0;$r1) {
+ for ($r=($rowbegin-1);$r<$rowend;$r++) {
+ $legends[($r+1-$rowbegin)] = $g['data'][$r][0] ;
+ $longestlegend = max($longestlegend, strlen( $g['data'][$r][0] ));
+ }
+ }
+ if ($rowbegin>1) {
+ for ($c=($colbegin-1);$c<$colend;$c++) {
+ $labels[($c+1-$colbegin)] = $g['data'][0][$c] ;
+ $longestlabel = max($longestlabel , strlen( $g['data'][0][$c] ));
+ }
+ }
+ }
+ else if ($dataseries=='rows') {
+ if ($colbegin>1) {
+ for ($r=($rowbegin-1);$r<$rowend;$r++) {
+ $labels[($r+1-$rowbegin)] = $g['data'][$r][0] ;
+ $longestlabel = max($longestlabel , strlen( $g['data'][$r][0] ));
+ }
+ }
+ if ($rowbegin>1) {
+ for ($c=($colbegin-1);$c<$colend;$c++) {
+ $legends[($c+1-$colbegin)] = $g['data'][0][$c] ;
+ $longestlegend = max($longestlegend, strlen( $g['data'][0][$c] ));
+ }
+ }
+ }
+ // Default sizes
+ $defsize = array();
+ $defsize['pie'] = array('w' => 600, 'h' => 300);
+ $defsize['pie3d'] = array('w' => 600, 'h' => 300);
+ $defsize['radar'] = array('w' => 600, 'h' => 300);
+ $defsize['line'] = array('w' => 600, 'h' => 400);
+ $defsize['xy'] = array('w' => 600, 'h' => 400);
+ $defsize['scatter'] = array('w' => 600, 'h' => 400);
+ $defsize['bar'] = array('w' => 600, 'h' => 400);
+ $defsize['horiz_bar'] = array('w' => 600, 'h' => 500);
+
+
+ // Use default ratios
+ if ($w && !$h) { $h = $w*$defsize[$type]['h']/$defsize[$type]['w']; }
+ if ($h && !$w) { $w = $h*$defsize[$type]['w']/$defsize[$type]['h']; }
+ if (!$h && !$w) { $w = $defsize[$type]['w']; $h = $defsize[$type]['h']; }
+
+
+ if (count($data)>0 && $type) {
+ $figure_file = "graph_cache/".rand(11111,999999999).".".$img_type;
+ if ($bandw) { $colours = array('snow1','black','snow4','snow3','snow2','cadetblue4','cadetblue3','cadetblue1','bisque4','bisque2','beige'); }
+ else { $colours = array('cyan','darkorchid4','cadetblue3','khaki1','darkolivegreen2','cadetblue4','coral','cyan4','rosybrown3','wheat1'); }
+ $fills = array('navy','orange','red','yellow','purple','navy','orange','red','yellow','purple');
+ $patterns = array(PATTERN_DIAG1,PATTERN_CROSS1,PATTERN_STRIPE1,PATTERN_DIAG3,PATTERN_CROSS2,PATTERN_DIAG2,PATTERN_DIAG4,PATTERN_CROSS3, PATTERN_CROSS4,PATTERN_STRIPE1);
+ $markers = array(MARK_DIAMOND, MARK_SQUARE, MARK_CIRCLE, MARK_UTRIANGLE, MARK_DTRIANGLE, MARK_FILLEDCIRCLE, MARK_CROSS, MARK_STAR, MARK_X);
+
+ // LEGENDS
+ if ($type == 'pie' || $type == 'pie3d') {
+ $graph = new PieGraph (($w*$k),($h*$k));
+ }
+ else if ($type == 'radar') {
+ $graph = new RadarGraph(($w*$k),($h*$k));
+ }
+ else {
+ $graph = new Graph(($w*$k),($h*$k));
+ }
+
+// mPDF 4.5.009
+// $graph->img->SetImgFormat($img_type) ;
+// if (strtoupper($img_type)=='JPEG') { $graph->img->SetQuality(90); }
+ if ($antialias) { $graph->img->SetAntiAliasing(); }
+ $graph->SetShadow(true, 2*$k);
+ $graph->SetMarginColor("white");
+ // TITLE
+ $graph->title->Set($title);
+ $graph->title->SetMargin(10*$k);
+ $graph->title->SetFont(FF_USERFONT,FS_BOLD,11*$k);
+ $graph->title->SetColor("black");
+ $graph->legend->SetLineSpacing(3*$k);
+ $graph->legend->SetMarkAbsSize(6*$k);
+ $graph->legend->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+
+ // Set GRAPH IMAGE MARGINS
+ if ($type == 'pie' || $type == 'pie3d') {
+ $psize = 0.3;
+ $pposxabs = ($w/2);
+ $pposy = 0.55;
+ if ($longestlegend) { // if legend showing
+ $pposxabs -= ((($longestlegend * 5) + 20) / 2);
+ }
+ $pposx = ($pposxabs / $w);
+ $graph->legend->Pos(0.02,0.5,'right','center');
+ }
+ else if ($type == 'radar') {
+ $psize = 0.5;
+ $pposxabs = ($w/2);
+ $pposy = 0.55;
+ if ($longestlabel) { // if legend showing
+ $pposxabs -= ((($longestlabel * 5) + 20) / 2);
+ }
+ $pposx = ($pposxabs / $w);
+ $graph->legend->Pos(0.02,0.5,'right','center');
+ }
+ else if ($type == 'xy' || $type == 'scatter') {
+ $pml = 50;
+ $pmr = 20;
+ $pmt = 60;
+ $pmb = 50;
+ $xaxislblmargin = $pmb - 30;
+ $yaxislblmargin = $pml - 15;
+ $graph->legend->Pos(0.02,0.1,'right','top');
+ }
+ else if ($type == 'line' || $type == 'bar') {
+ $pml = 50;
+ $pmr = 20;
+ $pmt = 60;
+ $pmb = 50;
+ $xlangle = 0;
+ $ll = ($longestlegend * 5); // 45 degrees 8pt fontsize
+ if ($ll > 5 || ($ll>3 && count($data)>10)) {
+ $pmb = max($pmb, $ll + 30);
+ $xlangle = 50;
+ }
+ $xaxislblmargin = $pmb - 30;
+ $yaxislblmargin = $pml - 15;
+ if ($longestlabel && !$overlap) { // if legend showing
+ $pmr = ((($longestlabel * 5) + 40));
+ }
+ $graph->legend->Pos(0.02,0.1,'right','top');
+ }
+ else if ($type == 'horiz_bar') {
+ $pml = 50;
+ $pmr = 20;
+ $pmt = 50;
+ $pmb = 45;
+ $ll = ($longestlegend * 6.5); // 8pt fontsize
+ $pml = max($pml, $ll + 20);
+ $xaxislblmargin = $pml - 20;
+ $yaxislblmargin = $pmb - 15;
+ if ($longestlabel && !$overlap) { // if legend showing
+ $pmr = ((($longestlabel * 5) + 40));
+ }
+ $graph->legend->Pos(0.02,0.1,'right','top');
+ }
+
+
+ // DRAW THE GRAPHS
+ if ($type == 'pie') {
+ $p1 = new PiePlot($data[0]);
+ $p1->SetSliceColors($colours);
+
+ if ($show_values) {
+ $p1->value->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+ if ($percent) { $p1->SetLabelType(PIE_VALUE_PERADJ); } //PIE_VAL_PER = default
+ else { $p1->SetLabelType(PIE_VALUE_ABS); }
+ if ($percent || $show_percent) { $p1->value->SetFormat("%d%%"); }
+ else { $p1->value->SetFormat("%s"); }
+ // Enable and set policy for guide-lines. Make labels line up vertically
+ $p1->SetGuideLines(true);
+ $p1->SetGuideLinesAdjust(1.5);
+ }
+ else { $p1->value->Show(false); }
+ $p1->SetLegends($legends);
+ $p1->SetSize($psize);
+ $p1->SetCenter($pposx, $pposy);
+ if ($labels[0]) {
+ $graph->subtitle->Set($labels[0]);
+ $graph->subtitle->SetMargin(10*$k);
+ $graph->subtitle->SetFont(FF_USERFONT,FS_BOLD,11*$k);
+ $graph->subtitle->SetColor("black");
+ }
+ $graph->Add($p1);
+ }
+ else if ($type == 'pie3d') {
+ $p1 = new PiePlot3d($data[0]);
+ $p1->SetSliceColors($colours);
+ if ($show_values) {
+ $p1->value->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+ if ($percent) { $p1->SetLabelType(PIE_VALUE_PERADJ); } //PIE_VAL_PER = default
+ else { $p1->SetLabelType(PIE_VALUE_ABS); }
+ if ($percent || $show_percent) { $p1->value->SetFormat("%d%%"); }
+ else { $p1->value->SetFormat("%s"); }
+ }
+ else { $p1->value->Show(false); }
+ $p1->SetLegends($legends);
+ $p1->SetEdge();
+ $p1->SetSize($psize);
+ $p1->SetCenter($pposx, $pposy);
+
+ if ($labels[0]) {
+ $graph->subtitle->Set($labels[0]);
+ $graph->subtitle->SetMargin(10*$k);
+ $graph->subtitle->SetFont(FF_USERFONT,FS_BOLD,11*$k);
+ $graph->subtitle->SetColor("black");
+ }
+
+ $graph->Add( $p1);
+ }
+ // RADAR
+ else if ($type == 'radar') {
+ $graph->SetSize($psize);
+ $graph->SetPos($pposx, $pposy);
+
+ $graph->SetTitles( $legends); // labels each axis
+
+ $graph->axis->title->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+ $graph->axis->title->SetMargin(5*$k);
+ $graph->axis->SetWeight(1*$k);
+ $graph->axis->HideLabels();
+ $graph->axis->SetFont(FF_USERFONT,FS_NORMAL,6*$k);
+ $graph->HideTickMarks();
+
+ $group = array();
+ foreach($data AS $series => $dat) {
+ $rdata = array();
+ foreach($data[$series] AS $row) { $rdata[] = $row; }
+ if (count($rdata)<3) { die("ERROR::Graph::Cannot create a Radar Plot with less than 3 data points."); }
+ // Create the radar plot
+ $bplot = new RadarPlot($rdata);
+ $bplot->mark->SetType($markers[$series]);
+ $bplot->mark->SetFillColor($colours[$series]);
+ $bplot->mark->SetWidth(3*$k);
+ $bplot->SetColor($colours[$series]);
+ if ($series == 0) { $bplot->SetFillColor('lightred'); }
+ else { $bplot->SetFill(false); }
+ $bplot->SetLineWeight(1*$k);
+ $bplot->SetLegend($labels[$series]);
+ if ($bandw) { $bplot->SetShadow("gray5"); }
+ $graph->Add($bplot);
+ }
+ }
+ // LINE
+ else if ($type == 'line') {
+ // Setup the graph.
+ $graph->img->SetMargin($pml*$k,$pmr*$k,$pmt*$k,$pmb*$k); // LRTB
+ $graph->SetScale($axes);
+ $graph->yaxis->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+
+ if ($ylabel) {
+ $graph->yaxis->title->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+ $graph->yaxis->SetTitle($ylabel,'middle');
+ $graph->yaxis->SetTitleMargin($yaxislblmargin*$k);
+ }
+
+ $graph->yaxis->SetLabelMargin(4*$k);
+ if ($percent || $show_percent) { $graph->yaxis->SetLabelFormat('%d%%'); } // Percent
+
+ // Show 0 label on Y-axis (default is not to show)
+ $graph->yscale->ticks->SupressZeroLabel(true);
+ if ($hide_y_axis) { $graph->yaxis->Hide(); }
+ if ($hide_grid) { $graph->ygrid->Show(false); }
+
+ // Setup X-axis labels
+ $graph->xaxis->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+ $graph->xaxis->SetTickLabels($legends);
+ $graph->xaxis->SetLabelAngle($xlangle);
+ $graph->xaxis->SetLabelMargin(4*$k);
+ // X-axis title
+ if ($xlabel) {
+ $graph->xaxis->title->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+ $graph->xaxis->SetTitle($xlabel,'middle');
+ $graph->xaxis->SetTitleMargin($xaxislblmargin*$k);
+ }
+ foreach($data AS $series => $rdata) {
+ $bplot = new LinePlot($rdata);
+ $bplot->mark->SetType($markers[$series]);
+ $bplot->mark->SetFillColor($colours[$series]);
+ $bplot->mark->SetWidth(4*$k);
+ if ($show_values) {
+ $bplot->value-> Show(); // Not if scatter
+ $bplot->value->SetMargin(6*$k);
+ $bplot->value->SetColor("darkred");
+ $bplot->value->SetFont( FF_USERFONT, FS_NORMAL, 8*$k);
+ if ($percent || $show_percent) { $bplot->value->SetFormat( '%d%%'); }
+ else { $bplot->value->SetFormat("%s"); }
+ }
+ // Set color for each line
+ $bplot->SetColor($colours[$series]);
+ $bplot->SetWeight(2*$k);
+ $bplot->SetLegend($labels[$series]);
+ if ($bandw) { $bplot->SetShadow("gray5"); }
+ // Indent the X-scale so the first and last point doesn't fall on the edges
+ $bplot->SetCenter();
+ $graph->Add($bplot);
+ }
+
+ }
+ // XY or SCATTER
+ else if ($type == 'xy' || $type == 'scatter') {
+ // Setup the graph.
+ $graph->img->SetMargin($pml*$k,$pmr*$k,$pmt*$k,$pmb*$k); // LRTB
+ $graph->SetScale($axes);
+ // Setup font for axis
+ $graph->yaxis->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+ // Y-axis title
+ if ($labels[1]) {
+ $graph->yaxis->title->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+ $graph->yaxis->SetTitleMargin($yaxislblmargin*$k);
+ $graph->yaxis->SetTitle($labels[1],'middle');
+ }
+
+
+ $graph->yaxis->SetLabelMargin(4*$k);
+ if ($percent || $show_percent) { $graph->yaxis->SetLabelFormat('%d%%'); } // Percent
+
+ // Show 0 label on Y-axis (default is not to show)
+ $graph->yscale->ticks->SupressZeroLabel(true);
+ // Just let the maximum be autoscaled
+ $graph->yaxis->scale->SetAutoMin(0);
+ if ($hide_y_axis) { $graph->yaxis->Hide(); }
+ if ($hide_grid) { $graph->ygrid->Show(false); }
+
+ // Setup X-axis labels
+ $graph->xaxis->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+// mPDF 2.5 Corrects labelling of x-axis
+// $graph->xaxis->SetTickLabels($legends);
+ $graph->xaxis->SetLabelAngle(50);
+ $graph->xaxis->SetLabelMargin(4*$k);
+ // X-axis title
+ if ($labels[0]) {
+ $graph->xaxis->title->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+ $graph->xaxis->SetTitleMargin($xaxislblmargin*$k);
+ $graph->xaxis->SetTitle($labels[0],'middle');
+ }
+
+ // Create the bar plot
+ // SPLINES
+ if ($splines && $type=='xy') {
+ $spline = new Spline($data[0],$data[1]);
+ list($newx,$newy) = $spline->Get(100);
+ }
+ else {
+ $newx = $data[0];
+ $newy = $data[1];
+ }
+
+ if ($type=='xy') {
+ // LINE PLOT
+ $bplot = new LinePlot($newy, $newx);
+ // Set color for each line
+ $bplot->SetColor($fills[0]);
+ $bplot->SetWeight(4*$k);
+ if ($bandw) { $bplot->SetShadow("gray5"); }
+ $graph->Add($bplot);
+ }
+
+ // SCATTER PLOT
+ $cplot = new ScatterPlot($data[1], $data[0]);
+
+ $cplot->mark->SetType($markers[0]);
+ $cplot->mark->SetFillColor($fills[0]);
+ $cplot->mark->SetWidth(8*$k);
+ if ($show_values) {
+// mPDF 2.5
+ if ($type=='xy') { $cplot->value->Show(); } // Not if scatter
+ $cplot->value->SetMargin(8*$k);
+ $cplot->value->SetColor("darkred");
+ $cplot->value->SetFont( FF_USERFONT, FS_NORMAL, 6*$k);
+
+ if ($percent || $show_percent) { $cplot->value->SetFormat( '%d%%'); }
+ else { $cplot->value->SetFormat("%s"); }
+ }
+
+ // Set color for each line
+ $cplot->SetColor($fills[0]);
+ $cplot->SetWeight(4*$k);
+ if ($bandw) { $cplot->SetShadow("gray5"); }
+ $graph->Add($cplot);
+
+ }
+ // BAR
+ else if ($type == 'bar') {
+ // Setup the graph.
+ $graph->img->SetMargin($pml*$k,$pmr*$k,$pmt*$k,$pmb*$k); // LRTB
+ $graph->SetScale($axes);
+ // Setup y-axis
+ $graph->yaxis->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+ if ($hide_y_axis) { $graph->yaxis->Hide(); }
+ if ($hide_grid) { $graph->ygrid->Show(false); }
+ $graph->yaxis->SetLabelMargin(4*$k);
+ if ($ylabel) {
+ $graph->yaxis->title->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+ $graph->yaxis->SetTitle($ylabel,'middle');
+ $graph->yaxis->SetTitleMargin($yaxislblmargin*$k);
+ }
+ // Show 0 label on Y-axis (default is not to show)
+ $graph->yscale->ticks->SupressZeroLabel(false);
+ // Setup X-axis labels
+ $graph->xaxis->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+ $graph->xaxis->SetTickLabels($legends);
+ $graph->xaxis->SetLabelAngle($xlangle);
+ $graph->xaxis->SetLabelMargin(4*$k);
+ // X-axis title
+ if ($xlabel) {
+ $graph->xaxis->title->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+ $graph->xaxis->SetTitle($xlabel,'middle');
+ $graph->xaxis->SetTitleMargin($xaxislblmargin*$k);
+ }
+
+ $group = array();
+ foreach($data AS $series => $dat) {
+ $rdata = array();
+ foreach($data[$series] AS $row) { $rdata[] = $row; }
+
+ // Create the bar plot
+ $bplot = new BarPlot($rdata);
+ $bplot->SetWidth(0.6); // for SINGLE??
+ // Setup color for gradient fill style
+ if ($bandw) { $bplot->SetPattern( $patterns[$series]); }
+ else { $bplot->SetFillGradient($fills[$series],"#EEEEEE",GRAD_LEFT_REFLECTION); }
+
+ // Set color for the frame of each bar
+ $bplot->SetColor("darkgray");
+ $bplot->SetLegend($labels[$series]);
+ if ($bandw) { $bplot->SetShadow("gray5"); }
+ if ($show_values) {
+ $bplot->value->Show();
+ $bplot->value->SetMargin(6*$k);
+ $bplot->value->SetColor("darkred");
+ $bplot->value->SetFont( FF_USERFONT, FS_NORMAL, 8*$k);
+ if ($percent || $show_percent) { $bplot->value->SetFormat( '%d%%'); }
+ else { $bplot->value->SetFormat("%s"); }
+ }
+
+ $group[] = $bplot;
+ }
+ if (count($data)==1) {
+ $graph->Add($group[0]);
+ }
+ else {
+ // Create the grouped bar plot
+ if ($stacked) {
+ $gbplot = new AccBarPlot ($group);
+ }
+ else {
+ $gbplot = new GroupBarPlot ($group);
+ }
+ $graph->Add($gbplot);
+ }
+ }
+ else if ($type == 'horiz_bar') {
+ $graph->SetScale($axes);
+ $graph->Set90AndMargin($pml*$k,$pmr*$k,$pmt*$k,$pmb*$k); // LRTB
+
+ // Setup y-axis
+ $graph->yaxis->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+ $graph->yaxis->SetLabelMargin(4*$k);
+
+ $graph->yaxis->SetPos('max'); // Intersect at top of x-axis i.e. y axis is at bottom
+ // First make the labels look right
+ $graph->yaxis->SetLabelAlign('center','top');
+ if ($percent || $show_percent) { $graph->yaxis->SetLabelFormat('%d%%'); }
+ $graph->yaxis->SetLabelSide(SIDE_RIGHT);
+ $graph->yaxis->scale->SetGrace(10); // sets 10% headroom
+ if ($hide_y_axis) { $graph->yaxis->Hide(); }
+ if ($hide_grid) { $graph->ygrid->Show(false); }
+
+ // The fix the tick marks
+ $graph->yaxis->SetTickSide(SIDE_LEFT);
+ if ($ylabel) {
+ $graph->yaxis->title->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+ $graph->yaxis->SetTitle($ylabel,'middle');
+ $graph->yaxis->SetTitleMargin($yaxislblmargin*$k);
+ // Finally setup the title
+ $graph->yaxis->SetTitleSide(SIDE_RIGHT);
+ // To align the title to the right use :
+ $graph->yaxis->title->Align('right');
+ $graph->yaxis->title->SetAngle(0);
+
+ }
+
+ // Show 0 label on Y-axis (default is not to show)
+ $graph->yscale->ticks->SupressZeroLabel(false);
+ // Setup X-axis labels
+ $graph->xaxis->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+ $graph->xaxis->title->SetAngle(90);
+ $graph->xaxis->SetTickLabels($legends);
+ $graph->xaxis->SetLabelMargin(4*$k);
+ // X-axis title
+ if ($xlabel) {
+ $graph->xaxis->title->SetFont(FF_USERFONT,FS_NORMAL,8*$k);
+ $graph->xaxis->SetTitleMargin($xaxislblmargin*$k);
+ $graph->xaxis->SetTitle($xlabel,'middle');
+ }
+ $group = array();
+ foreach($data AS $series => $dat) {
+ $rdata = array();
+ foreach($data[$series] AS $row) { $rdata[] = $row; }
+ // Create the bar pot
+ $bplot = new BarPlot($rdata);
+ $bplot->SetWidth(0.6); // for SINGLE??
+ // Setup color for gradient fill style
+ if ($bandw) { $bplot->SetPattern( $patterns[$series]); }
+ else { $bplot->SetFillGradient($fills[$series],"#EEEEEE",GRAD_LEFT_REFLECTION); }
+
+ // Set color for the frame of each bar
+ $bplot->SetColor("darkgray");
+ $bplot->SetLegend($labels[$series]);
+ if ($bandw) { $bplot->SetShadow("gray5"); }
+ if ($show_values) {
+ $bplot->value-> Show();
+ $bplot->value->SetMargin(6*$k);
+ $bplot->value->SetColor("darkred");
+ $bplot->value->SetFont( FF_USERFONT, FS_NORMAL, 8*$k);
+ if ($percent || $show_percent) { $bplot->value->SetFormat( '%d%%'); }
+ else { $bplot->value->SetFormat("%s"); }
+ }
+
+ $group[] = $bplot;
+ }
+ if (count($data)==1) {
+ $graph->Add($group[0]);
+ }
+ else {
+ // Create the grouped bar plot
+ if ($stacked) {
+ $gbplot = new AccBarPlot ($group);
+ }
+ else {
+ $gbplot = new GroupBarPlot ($group);
+ }
+ $graph->Add($gbplot);
+ }
+ }
+ if ($graph) {
+ $graph->Stroke( _MPDF_PATH.$figure_file);
+ $srcpath = str_replace("\\","/",dirname(__FILE__)) . "/";
+ $srcpath .= $figure_file;
+ return array('file'=>$srcpath, 'w'=>$w, 'h'=>$h);
+ }
+ }
+ return false;
+}
+//======================================================================================================
+//======================================================================================================
+//======================================================================================================
+//======================================================================================================
+
+?>
\ No newline at end of file
diff --git a/mpdf/graph_cache/dummy.txt b/mpdf/graph_cache/dummy.txt
new file mode 100644
index 0000000..4123496
--- /dev/null
+++ b/mpdf/graph_cache/dummy.txt
@@ -0,0 +1,2 @@
+This is just a placeholder file so that the folder is created on install.
+It can be deleted once installed.
\ No newline at end of file
diff --git a/mpdf/iccprofiles/SWOP2006_Coated5v2.icc b/mpdf/iccprofiles/SWOP2006_Coated5v2.icc
new file mode 100644
index 0000000..0d06cd5
Binary files /dev/null and b/mpdf/iccprofiles/SWOP2006_Coated5v2.icc differ
diff --git a/mpdf/iccprofiles/sRGB_IEC61966-2-1.icc b/mpdf/iccprofiles/sRGB_IEC61966-2-1.icc
new file mode 100644
index 0000000..d0ef573
Binary files /dev/null and b/mpdf/iccprofiles/sRGB_IEC61966-2-1.icc differ
diff --git a/mpdf/includes/CJKdata.php b/mpdf/includes/CJKdata.php
new file mode 100644
index 0000000..8423052
--- /dev/null
+++ b/mpdf/includes/CJKdata.php
@@ -0,0 +1,101 @@
+ 250, 33 => 250, 34 => 408, 35 => 668, 36 => 490, 37 => 875, 38 => 698, 39 => 250, 40 => 240, 41 => 240,
+ 42 => 417, 43 => 667, 44 => 250, 45 => 313, 46 => 250, 47 => 520, 48 => 500, 49 => 500, 50 => 500, 51 => 500,
+ 52 => 500, 53 => 500, 54 => 500, 55 => 500, 56 => 500, 57 => 500, 58 => 250, 59 => 250, 60 => 667, 61 => 667,
+ 62 => 667, 63 => 396, 64 => 921, 65 => 677, 66 => 615, 67 => 719, 68 => 760, 69 => 625, 70 => 552, 71 => 771,
+ 72 => 802, 73 => 354, 74 => 354, 75 => 781, 76 => 604, 77 => 927, 78 => 750, 79 => 823, 80 => 563, 81 => 823,
+ 82 => 729, 83 => 542, 84 => 698, 85 => 771, 86 => 729, 87 => 948, 88 => 771, 89 => 677, 90 => 635, 91 => 344,
+ 92 => 520, 93 => 344, 94 => 469, 95 => 500, 96 => 250, 97 => 469, 98 => 521, 99 => 427, 100 => 521, 101 => 438,
+ 102 => 271, 103 => 469, 104 => 531, 105 => 250, 106 => 250, 107 => 458, 108 => 240, 109 => 802, 110 => 531, 111 => 500,
+ 112 => 521, 113 => 521, 114 => 365, 115 => 333, 116 => 292, 117 => 521, 118 => 458, 119 => 677, 120 => 479, 121 => 458,
+ 122 => 427, 123 => 480, 124 => 496, 125 => 480, 126 => 667,
+ 17601 => 500,
+);
+$this->Big5_widths=$cw;
+
+
+// GB
+$cw = array(
+ 32 => 207, 33 => 270, 34 => 342, 35 => 467, 36 => 462, 37 => 797, 38 => 710, 39 => 239, 40 => 374, 41 => 374,
+ 42 => 423, 43 => 605, 44 => 238, 45 => 375, 46 => 238, 47 => 334, 48 => 462, 49 => 462, 50 => 462, 51 => 462,
+ 52 => 462, 53 => 462, 54 => 462, 55 => 462, 56 => 462, 57 => 462, 58 => 238, 59 => 238, 60 => 605, 61 => 605,
+ 62 => 605, 63 => 344, 64 => 748, 65 => 684, 66 => 560, 67 => 695, 68 => 739, 69 => 563, 70 => 511, 71 => 729,
+ 72 => 793, 73 => 318, 74 => 312, 75 => 666, 76 => 526, 77 => 896, 78 => 758, 79 => 772, 80 => 544, 81 => 772,
+ 82 => 628, 83 => 465, 84 => 607, 85 => 753, 86 => 711, 87 => 972, 88 => 647, 89 => 620, 90 => 607, 91 => 374,
+ 92 => 333, 93 => 374, 94 => 606, 95 => 500, 96 => 239, 97 => 417, 98 => 503, 99 => 427, 100 => 529, 101 => 415,
+ 102 => 264, 103 => 444, 104 => 518, 105 => 241, 106 => 230, 107 => 495, 108 => 228, 109 => 793, 110 => 527, 111 => 524,
+ 112 => 524, 113 => 504, 114 => 338, 115 => 336, 116 => 277, 117 => 517, 118 => 450, 119 => 652, 120 => 466, 121 => 452,
+ 122 => 407, 123 => 370, 124 => 258, 125 => 370, 126 => 605,
+);
+$this->GB_widths=$cw;
+
+// Japanese
+$cw = array(
+ 32 => 278, 33 => 299, 34 => 353, 35 => 614, 36 => 614, 37 => 721, 38 => 735, 39 => 216, 40 => 323, 41 => 323,
+ 42 => 449, 43 => 529, 44 => 219, 45 => 306, 46 => 219, 47 => 453, 48 => 614, 49 => 614, 50 => 614, 51 => 614,
+ 52 => 614, 53 => 614, 54 => 614, 55 => 614, 56 => 614, 57 => 614, 58 => 219, 59 => 219, 60 => 529, 61 => 529,
+ 62 => 529, 63 => 486, 64 => 744, 65 => 646, 66 => 604, 67 => 617, 68 => 681, 69 => 567, 70 => 537, 71 => 647,
+ 72 => 738, 73 => 320, 74 => 433, 75 => 637, 76 => 566, 77 => 904, 78 => 710, 79 => 716, 80 => 605, 81 => 716,
+ 82 => 623, 83 => 517, 84 => 601, 85 => 690, 86 => 668, 87 => 990, 88 => 681, 89 => 634, 90 => 578, 91 => 316,
+ 92 => 614, 93 => 316, 94 => 529, 95 => 500, 96 => 387, 97 => 509, 98 => 566, 99 => 478, 100 => 565, 101 => 503,
+ 102 => 337, 103 => 549, 104 => 580, 105 => 275, 106 => 266, 107 => 544, 108 => 276, 109 => 854, 110 => 579, 111 => 550,
+ 112 => 578, 113 => 566, 114 => 410, 115 => 444, 116 => 340, 117 => 575, 118 => 512, 119 => 760, 120 => 503, 121 => 529,
+ 122 => 453, 123 => 326, 124 => 380, 125 => 326, 126 => 387, 127 => 216, 128 => 453, 129 => 216, 130 => 380, 131 => 529,
+ 132 => 299, 133 => 614, 134 => 614, 135 => 265, 136 => 614, 137 => 475, 138 => 614, 139 => 353, 140 => 451, 141 => 291,
+ 142 => 291, 143 => 588, 144 => 589, 145 => 500, 146 => 476, 147 => 476, 148 => 219, 149 => 494, 150 => 452, 151 => 216,
+ 152 => 353, 153 => 353, 154 => 451, 156 => 1075, 157 => 486, 158 => 387, 159 => 387, 160 => 387, 161 => 387,
+ 162 => 387, 163 => 387, 164 => 387, 165 => 387, 166 => 387, 167 => 387, 168 => 387, 170 => 880, 171 => 448,
+ 172 => 566, 173 => 716, 174 => 903, 175 => 460, 176 => 805, 177 => 275, 178 => 276, 179 => 550, 180 => 886, 181 => 582,
+ 182 => 529, 183 => 738, 184 => 529, 185 => 738, 186 => 357, 187 => 529, 188 => 406, 189 => 406, 190 => 575, 191 => 406,
+ 192 => 934, 193 => 934, 194 => 934, 195 => 646, 196 => 646, 197 => 646, 198 => 646, 199 => 646, 200 => 646, 201 => 617,
+ 202 => 567, 203 => 567, 204 => 567, 205 => 567, 206 => 320, 207 => 320, 208 => 320, 209 => 320, 210 => 681, 211 => 710,
+ 212 => 716, 213 => 716, 214 => 716, 215 => 716, 216 => 716, 217 => 529, 218 => 690, 219 => 690, 220 => 690, 221 => 690,
+ 222 => 634, 223 => 605, 224 => 509, 225 => 509, 226 => 509, 227 => 509, 228 => 509, 229 => 509, 230 => 478, 231 => 503,
+ 232 => 503, 233 => 503, 234 => 503, 235 => 275, 236 => 275, 237 => 275, 238 => 275, 239 => 550, 240 => 579, 241 => 550,
+ 242 => 550, 243 => 550, 244 => 550, 245 => 550, 246 => 529, 247 => 575, 248 => 575, 249 => 575, 250 => 575, 251 => 529,
+ 252 => 578, 253 => 529, 254 => 517, 255 => 634, 256 => 578, 257 => 445, 258 => 444, 259 => 842, 260 => 453, 261 => 614,
+);
+
+
+$_cr = array(
+ array(231, 632, 500), // half-width
+ array(8718, 8718, 500),
+ array(9738, 9757, 250), // quarter-width
+ array(9758, 9778, 333), // third-width
+ array(12063, 12087, 500),
+);
+foreach($_cr as $_r) {
+ for($i = $_r[0]; $i <= $_r[1]; $i++) {
+ $cw[$i+31] = $_r[2];
+ }
+}
+$this->SJIS_widths=$cw;
+
+// Korean
+$cw = array(
+ 32 => 333, 33 => 416, 34 => 416, 35 => 833, 36 => 625, 37 => 916, 38 => 833, 39 => 250, 40 => 500, 41 => 500,
+ 42 => 500, 43 => 833, 44 => 291, 45 => 450, 46 => 291, 47 => 375, 48 => 625, 49 => 625, 50 => 625, 51 => 625,
+ 52 => 625, 53 => 625, 54 => 625, 55 => 625, 56 => 625, 57 => 625, 58 => 333, 59 => 333, 60 => 833, 61 => 833,
+ 62 => 916, 63 => 500, 64 => 1000, 65 => 791, 66 => 708, 67 => 708, 68 => 750, 69 => 708, 70 => 666, 71 => 750,
+ 72 => 791, 73 => 375, 74 => 500, 75 => 791, 76 => 666, 77 => 916, 78 => 791, 79 => 750, 80 => 666, 81 => 750,
+ 82 => 708, 83 => 666, 84 => 791, 85 => 791, 86 => 750, 87 => 1000, 88 => 708, 89 => 708, 90 => 666, 91 => 500,
+ 92 => 375, 93 => 500, 94 => 500, 95 => 500, 96 => 333, 97 => 541, 98 => 583, 99 => 541, 100 => 583, 101 => 583,
+ 102 => 375, 103 => 583, 104 => 583, 105 => 291, 106 => 333, 107 => 583, 108 => 291, 109 => 875, 110 => 583, 111 => 583,
+ 112 => 583, 113 => 583, 114 => 458, 115 => 541, 116 => 375, 117 => 583, 118 => 583, 119 => 833, 120 => 625, 121 => 625,
+ 122 => 500, 123 => 583, 124 => 583, 125 => 583, 126 => 750,
+);
+$_cr = array(
+ array(8094, 8190, 500)
+);
+foreach($_cr as $_r) {
+ for($i = $_r[0]; $i <= $_r[1]; $i++) {
+ $cw[$i+31] = $_r[2];
+ }
+}
+$this->UHC_widths=$cw;
+
+?>
\ No newline at end of file
diff --git a/mpdf/includes/functions.php b/mpdf/includes/functions.php
new file mode 100644
index 0000000..fdc5dea
--- /dev/null
+++ b/mpdf/includes/functions.php
@@ -0,0 +1,172 @@
+=5.5.0
+if(!function_exists('imagepalettetotruecolor')) {
+ function imagepalettetotruecolor(&$src) {
+ if(imageistruecolor($src)) {
+ return(true);
+ }
+ $dst = imagecreatetruecolor(imagesx($src), imagesy($src));
+
+ imagecopy($dst, $src, 0, 0, 0, 0, imagesx($src), imagesy($src));
+ imagedestroy($src);
+
+ $src = $dst;
+
+ return(true);
+ }
+}
+
+// mPDF 5.7
+// Replace a section of an array with the elements in reverse
+function array_splice_reverse(&$arr, $offset, $length) {
+ $tmp = (array_reverse(array_slice($arr, $offset, $length)));
+ array_splice($arr, $offset, $length, $tmp);
+}
+
+
+function array_insert(&$array, $value, $offset) {
+ if (is_array($array)) {
+ $array = array_values($array);
+ $offset = intval($offset);
+ if ($offset < 0 || $offset >= count($array)) { array_push($array, $value); }
+ else if ($offset == 0) { array_unshift($array, $value); }
+ else {
+ $temp = array_slice($array, 0, $offset);
+ array_push($temp, $value);
+ $array = array_slice($array, $offset);
+ $array = array_merge($temp, $array);
+ }
+ }
+ else { $array = array($value); }
+ return count($array);
+}
+
+// mPDF 5.7.4 URLs
+function urldecode_parts($url) {
+ $file=$url;
+ $query='';
+ if (preg_match('/[?]/',$url)) {
+ $bits = preg_split('/[?]/',$url,2);
+ $file=$bits[0];
+ $query='?'.$bits[1];
+ }
+ $file = rawurldecode($file);
+ $query = urldecode($query);
+ return $file.$query;
+}
+
+
+function _strspn($str1, $str2, $start=null, $length=null) {
+ $numargs = func_num_args();
+ if ($numargs == 2) {
+ return strspn($str1, $str2);
+ }
+ else if ($numargs == 3) {
+ return strspn($str1, $str2, $start);
+ }
+ else {
+ return strspn($str1, $str2, $start, $length);
+ }
+}
+
+
+function _strcspn($str1, $str2, $start=null, $length=null) {
+ $numargs = func_num_args();
+ if ($numargs == 2) {
+ return strcspn($str1, $str2);
+ }
+ else if ($numargs == 3) {
+ return strcspn($str1, $str2, $start);
+ }
+ else {
+ return strcspn($str1, $str2, $start, $length);
+ }
+}
+
+function _fgets (&$h, $force=false) {
+ $startpos = ftell($h);
+ $s = fgets($h, 1024);
+ if ($force && preg_match("/^([^\r\n]*[\r\n]{1,2})(.)/",trim($s), $ns)) {
+ $s = $ns[1];
+ fseek($h,$startpos+strlen($s));
+ }
+ return $s;
+}
+
+
+// For PHP4 compatability
+if(!function_exists('str_ireplace')) {
+ function str_ireplace($search,$replace,$subject) {
+ $search = preg_quote($search, "/");
+ return preg_replace("/".$search."/i", $replace, $subject);
+ }
+}
+if(!function_exists('htmlspecialchars_decode')) {
+ function htmlspecialchars_decode ($str) {
+ return strtr($str, array_flip(get_html_translation_table(HTML_SPECIALCHARS)));
+ }
+}
+
+function PreparePreText($text,$ff='//FF//') {
+ $text = htmlspecialchars($text);
+ if ($ff) { $text = str_replace($ff,'',$text); }
+ return (''.$text.' ');
+}
+
+if(!function_exists('strcode2utf')){
+ function strcode2utf($str,$lo=true) {
+ //converts all the nnn; and hhh; in a string to Unicode
+ // mPDF 5.7
+ if ($lo) {
+ $str = preg_replace_callback('/\&\#([0-9]+)\;/m', 'code2utf_lo_callback', $str);
+ $str = preg_replace_callback('/\&\#x([0-9a-fA-F]+)\;/m', 'codeHex2utf_lo_callback', $str);
+ }
+ else {
+ $str = preg_replace_callback('/\&\#([0-9]+)\;/m', 'code2utf_callback', $str);
+ $str = preg_replace_callback('/\&\#x([0-9a-fA-F]+)\;/m', 'codeHex2utf_callback', $str);
+ }
+ return $str;
+ }
+}
+function code2utf_callback($matches) {
+ return code2utf($matches[1], 0);
+}
+function code2utf_lo_callback($matches) {
+ return code2utf($matches[1], 1);
+}
+function codeHex2utf_callback($matches) {
+ return codeHex2utf($matches[1], 0);
+}
+function codeHex2utf_lo_callback($matches) {
+ return codeHex2utf($matches[1], 1);
+}
+
+
+if(!function_exists('code2utf')){
+ function code2utf($num,$lo=true){
+ //Returns the utf string corresponding to the unicode value
+ if ($num<128) {
+ if ($lo) return chr($num);
+ else return ''.$num.';';
+ }
+ if ($num<2048) return chr(($num>>6)+192).chr(($num&63)+128);
+ if ($num<65536) return chr(($num>>12)+224).chr((($num>>6)&63)+128).chr(($num&63)+128);
+ if ($num<2097152) return chr(($num>>18)+240).chr((($num>>12)&63)+128).chr((($num>>6)&63)+128) .chr(($num&63)+128);
+ return '?';
+ }
+}
+
+
+if(!function_exists('codeHex2utf')){
+ function codeHex2utf($hex,$lo=true){
+ $num = hexdec($hex);
+ if (($num<128) && !$lo) return ''.$hex.';';
+ return code2utf($num,$lo);
+ }
+}
+
+
+?>
\ No newline at end of file
diff --git a/mpdf/includes/linebrdictK.dat b/mpdf/includes/linebrdictK.dat
new file mode 100644
index 0000000..c186b1d
Binary files /dev/null and b/mpdf/includes/linebrdictK.dat differ
diff --git a/mpdf/includes/linebrdictL.dat b/mpdf/includes/linebrdictL.dat
new file mode 100644
index 0000000..9dfbac0
Binary files /dev/null and b/mpdf/includes/linebrdictL.dat differ
diff --git a/mpdf/includes/linebrdictT.dat b/mpdf/includes/linebrdictT.dat
new file mode 100644
index 0000000..a152857
Binary files /dev/null and b/mpdf/includes/linebrdictT.dat differ
diff --git a/mpdf/includes/no_image.jpg b/mpdf/includes/no_image.jpg
new file mode 100644
index 0000000..a690485
Binary files /dev/null and b/mpdf/includes/no_image.jpg differ
diff --git a/mpdf/includes/out.php b/mpdf/includes/out.php
new file mode 100644
index 0000000..75da455
--- /dev/null
+++ b/mpdf/includes/out.php
@@ -0,0 +1,59 @@
+Error('Some data has already been output to browser, can\'t send PDF file');
+ header('Content-Transfer-Encoding: binary');
+ header('Cache-Control: public, must-revalidate, max-age=0');
+ header('Pragma: public');
+ header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
+ header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
+ header('Content-Type: application/force-download');
+ header('Content-Type: application/octet-stream', false);
+ header('Content-Type: application/download', false);
+ header('Content-Type: application/pdf', false);
+ header('Content-disposition: attachment; filename="'.$name.'"');
+ }
+ $filesize = filesize($path.$tempfilename);
+ if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
+ // don't use length if server using compression
+ header('Content-Length: '.$filesize);
+ }
+ $fd=fopen($path.$tempfilename,'rb');
+ fpassthru($fd);
+ fclose($fd);
+ unlink($path.$tempfilename);
+ // ====================== DELETE OLD FILES - Housekeeping =========================================
+ // Clear any files in directory that are >24 hrs old
+ $interval = 86400;
+ if ($handle = opendir(dirname($path.'dummy'))) {
+ while (false !== ($file = readdir($handle))) {
+ if (((filemtime($path.$file)+$interval) < time()) && ($file != "..") && ($file != ".") && substr($file, -3)=='pdf') {
+ unlink($path.$file);
+ }
+ }
+ closedir($handle);
+ }
+ exit;
+ }
+?>
\ No newline at end of file
diff --git a/mpdf/includes/subs_core.php b/mpdf/includes/subs_core.php
new file mode 100644
index 0000000..326a3f4
--- /dev/null
+++ b/mpdf/includes/subs_core.php
@@ -0,0 +1,454 @@
+ 160,
+161 => 161,
+162 => 162,
+163 => 163,
+164 => 164,
+165 => 165,
+166 => 166,
+167 => 167,
+168 => 168,
+169 => 169,
+170 => 170,
+171 => 171,
+172 => 172,
+173 => 173,
+174 => 174,
+175 => 175,
+176 => 176,
+177 => 177,
+178 => 178,
+179 => 179,
+180 => 180,
+181 => 181,
+182 => 182,
+183 => 183,
+184 => 184,
+185 => 185,
+186 => 186,
+187 => 187,
+188 => 188,
+189 => 189,
+190 => 190,
+191 => 191,
+192 => 192,
+193 => 193,
+194 => 194,
+195 => 195,
+196 => 196,
+197 => 197,
+198 => 198,
+199 => 199,
+200 => 200,
+201 => 201,
+202 => 202,
+203 => 203,
+204 => 204,
+205 => 205,
+206 => 206,
+207 => 207,
+208 => 208,
+209 => 209,
+210 => 210,
+211 => 211,
+212 => 212,
+213 => 213,
+214 => 214,
+215 => 215,
+216 => 216,
+217 => 217,
+218 => 218,
+219 => 219,
+220 => 220,
+221 => 221,
+222 => 222,
+223 => 223,
+224 => 224,
+225 => 225,
+226 => 226,
+227 => 227,
+228 => 228,
+229 => 229,
+230 => 230,
+231 => 231,
+232 => 232,
+233 => 233,
+234 => 234,
+235 => 235,
+236 => 236,
+237 => 237,
+238 => 238,
+239 => 239,
+240 => 240,
+241 => 241,
+242 => 242,
+243 => 243,
+244 => 244,
+245 => 245,
+246 => 246,
+247 => 247,
+248 => 248,
+249 => 249,
+250 => 250,
+251 => 251,
+252 => 252,
+253 => 253,
+254 => 254,
+255 => 255,
+338 => 140,
+339 => 156,
+352 => 138,
+353 => 154,
+376 => 159,
+381 => 142,
+382 => 158,
+402 => 131,
+710 => 136,
+732 => 152,
+8211 => 150,
+8212 => 151,
+8216 => 145,
+8217 => 146,
+8218 => 130,
+8220 => 147,
+8221 => 148,
+8222 => 132,
+8224 => 134,
+8225 => 135,
+8226 => 149,
+8230 => 133,
+8240 => 137,
+8249 => 139,
+8250 => 155,
+8364 => 128,
+8482 => 153
+);
+
+$zarr = array(
+8594 => 213,
+8596 => 214,
+8597 => 215,
+9312 => 172,
+9313 => 173,
+9314 => 174,
+9315 => 175,
+9316 => 176,
+9317 => 177,
+9318 => 178,
+9319 => 179,
+9320 => 180,
+9321 => 181,
+9632 => 110,
+9650 => 115,
+9660 => 116,
+9670 => 117,
+9679 => 108,
+9687 => 119,
+9733 => 72,
+9742 => 37,
+9755 => 42,
+9758 => 43,
+9824 => 171,
+9827 => 168,
+9829 => 170,
+9830 => 169,
+9985 => 33,
+9986 => 34,
+9987 => 35,
+9988 => 36,
+9990 => 38,
+9991 => 39,
+9992 => 40,
+9993 => 41,
+9996 => 44,
+9997 => 45,
+9998 => 46,
+9999 => 47,
+10000 => 48,
+10001 => 49,
+10002 => 50,
+10003 => 51,
+10004 => 52,
+10005 => 53,
+10006 => 54,
+10007 => 55,
+10008 => 56,
+10009 => 57,
+10010 => 58,
+10011 => 59,
+10012 => 60,
+10013 => 61,
+10014 => 62,
+10015 => 63,
+10016 => 64,
+10017 => 65,
+10018 => 66,
+10019 => 67,
+10020 => 68,
+10021 => 69,
+10022 => 70,
+10023 => 71,
+10025 => 73,
+10026 => 74,
+10027 => 75,
+10028 => 76,
+10029 => 77,
+10030 => 78,
+10031 => 79,
+10032 => 80,
+10033 => 81,
+10034 => 82,
+10035 => 83,
+10036 => 84,
+10037 => 85,
+10038 => 86,
+10039 => 87,
+10040 => 88,
+10041 => 89,
+10042 => 90,
+10043 => 91,
+10044 => 92,
+10045 => 93,
+10046 => 94,
+10047 => 95,
+10048 => 96,
+10049 => 97,
+10050 => 98,
+10051 => 99,
+10052 => 100,
+10053 => 101,
+10054 => 102,
+10055 => 103,
+10056 => 104,
+10057 => 105,
+10058 => 106,
+10059 => 107,
+10061 => 109,
+10063 => 111,
+10064 => 112,
+10065 => 113,
+10066 => 114,
+10070 => 118,
+10072 => 120,
+10073 => 121,
+10074 => 122,
+10075 => 123,
+10076 => 124,
+10077 => 125,
+10078 => 126,
+10081 => 161,
+10082 => 162,
+10083 => 163,
+10084 => 164,
+10085 => 165,
+10086 => 166,
+10087 => 167,
+10102 => 182,
+10103 => 183,
+10104 => 184,
+10105 => 185,
+10106 => 186,
+10107 => 187,
+10108 => 188,
+10109 => 189,
+10110 => 190,
+10111 => 191,
+10112 => 192,
+10113 => 193,
+10114 => 194,
+10115 => 195,
+10116 => 196,
+10117 => 197,
+10118 => 198,
+10119 => 199,
+10120 => 200,
+10121 => 201,
+10122 => 202,
+10123 => 203,
+10124 => 204,
+10125 => 205,
+10126 => 206,
+10127 => 207,
+10128 => 208,
+10129 => 209,
+10130 => 210,
+10131 => 211,
+10132 => 212,
+10136 => 216,
+10137 => 217,
+10138 => 218,
+10139 => 219,
+10140 => 220,
+10141 => 221,
+10142 => 222,
+10143 => 223,
+10144 => 224,
+10145 => 225,
+10146 => 226,
+10147 => 227,
+10148 => 228,
+10149 => 229,
+10150 => 230,
+10151 => 231,
+10152 => 232,
+10153 => 233,
+10154 => 234,
+10155 => 235,
+10156 => 236,
+10157 => 237,
+10158 => 238,
+10159 => 239,
+10161 => 241,
+10162 => 242,
+10163 => 243,
+10164 => 244,
+10165 => 245,
+10166 => 246,
+10167 => 247,
+10168 => 248,
+10169 => 249,
+10170 => 250,
+10171 => 251,
+10172 => 252,
+10173 => 253,
+10174 => 254
+);
+
+$sarr = array(
+169 => 227,
+172 => 216,
+174 => 226,
+176 => 176,
+177 => 177,
+181 => 109,
+215 => 180,
+247 => 184,
+402 => 166,
+913 => 65,
+914 => 66,
+915 => 71,
+916 => 68,
+917 => 69,
+918 => 90,
+919 => 72,
+920 => 81,
+921 => 73,
+922 => 75,
+923 => 76,
+924 => 77,
+925 => 78,
+926 => 88,
+927 => 79,
+928 => 80,
+929 => 82,
+931 => 83,
+932 => 84,
+933 => 85,
+934 => 70,
+935 => 67,
+936 => 89,
+937 => 87,
+945 => 97,
+946 => 98,
+947 => 103,
+948 => 100,
+949 => 101,
+950 => 122,
+951 => 104,
+952 => 113,
+953 => 105,
+954 => 107,
+955 => 108,
+956 => 109,
+957 => 110,
+958 => 120,
+959 => 111,
+960 => 112,
+961 => 114,
+962 => 86,
+963 => 115,
+964 => 116,
+965 => 117,
+966 => 102,
+967 => 99,
+968 => 121,
+969 => 119,
+977 => 74,
+978 => 161,
+981 => 106,
+982 => 118,
+8226 => 183,
+8230 => 188,
+8242 => 162,
+8243 => 178,
+8260 => 164,
+8465 => 193,
+8472 => 195,
+8476 => 194,
+8482 => 228,
+8486 => 87,
+8501 => 192,
+8592 => 172,
+8593 => 173,
+8594 => 174,
+8595 => 175,
+8596 => 171,
+8629 => 191,
+8656 => 220,
+8657 => 221,
+8658 => 222,
+8659 => 223,
+8660 => 219,
+8704 => 34,
+8706 => 182,
+8707 => 36,
+8709 => 198,
+8710 => 68,
+8711 => 209,
+8712 => 206,
+8713 => 207,
+8715 => 39,
+8719 => 213,
+8721 => 229,
+8722 => 45,
+8725 => 164,
+8727 => 42,
+8730 => 214,
+8733 => 181,
+8734 => 165,
+8736 => 208,
+8743 => 217,
+8744 => 218,
+8745 => 199,
+8746 => 200,
+8747 => 242,
+8756 => 92,
+8764 => 126,
+8773 => 64,
+8776 => 187,
+8800 => 185,
+8801 => 186,
+8804 => 163,
+8805 => 179,
+8834 => 204,
+8835 => 201,
+8836 => 203,
+8838 => 205,
+8839 => 202,
+8853 => 197,
+8855 => 196,
+8869 => 94,
+8901 => 215,
+8992 => 243,
+8993 => 245,
+9001 => 225,
+9002 => 241,
+9674 => 224,
+9824 => 170,
+9827 => 167,
+9829 => 169,
+9830 => 168
+);
+
+?>
\ No newline at end of file
diff --git a/mpdf/includes/subs_win-1252.php b/mpdf/includes/subs_win-1252.php
new file mode 100644
index 0000000..6658ff7
--- /dev/null
+++ b/mpdf/includes/subs_win-1252.php
@@ -0,0 +1,308 @@
+ '65',
+ 914 => '66',
+ 915 => '71',
+ 916 => '68',
+ 917 => '69',
+ 918 => '90',
+ 919 => '72',
+ 920 => '81',
+ 921 => '73',
+ 922 => '75',
+ 923 => '76',
+ 924 => '77',
+ 925 => '78',
+ 926 => '88',
+ 927 => '79',
+ 928 => '80',
+ 929 => '82',
+ 931 => '83',
+ 932 => '84',
+ 933 => '85',
+ 934 => '70',
+ 935 => '67',
+ 936 => '89',
+ 937 => '87',
+ 945 => '97',
+ 946 => '98',
+ 947 => '103',
+ 948 => '100',
+ 949 => '101',
+ 950 => '122',
+ 951 => '104',
+ 952 => '113',
+ 953 => '105',
+ 954 => '107',
+ 955 => '108',
+ 956 => '109',
+ 957 => '110',
+ 958 => '120',
+ 959 => '111',
+ 960 => '112',
+ 961 => '114',
+ 962 => '86',
+ 963 => '115',
+ 964 => '116',
+ 965 => '117',
+ 966 => '102',
+ 967 => '99',
+ 968 => '121',
+ 969 => '119',
+ 977 => '74',
+ 978 => '161',
+ 981 => '106',
+ 982 => '118',
+ 8242 => '162',
+ 8243 => '178',
+ 8260 => '164',
+ 8465 => '193',
+ 8472 => '195',
+ 8476 => '194',
+ 8486 => '87',
+ 8501 => '192',
+ 8592 => '172',
+ 8593 => '173',
+ 8594 => '174',
+ 8595 => '175',
+ 8596 => '171',
+ 8597 => '215',
+ 8629 => '191',
+ 8656 => '220',
+ 8657 => '221',
+ 8658 => '222',
+ 8659 => '223',
+ 8660 => '219',
+ 8704 => '34',
+ 8706 => '182',
+ 8707 => '36',
+ 8709 => '198',
+ 8710 => '68',
+ 8711 => '209',
+ 8712 => '206',
+ 8713 => '207',
+ 8715 => '39',
+ 8719 => '213',
+ 8721 => '229',
+ 8722 => '45',
+ 8725 => '164',
+ 8727 => '42',
+ 8730 => '214',
+ 8733 => '181',
+ 8734 => '165',
+ 8736 => '208',
+ 8743 => '217',
+ 8744 => '218',
+ 8745 => '199',
+ 8746 => '200',
+ 8747 => '242',
+ 8756 => '92',
+ 8764 => '126',
+ 8773 => '64',
+ 8776 => '187',
+ 8800 => '185',
+ 8801 => '186',
+ 8804 => '163',
+ 8805 => '179',
+ 8834 => '204',
+ 8835 => '201',
+ 8836 => '203',
+ 8838 => '205',
+ 8839 => '202',
+ 8853 => '197',
+ 8855 => '196',
+ 8869 => '94',
+ 8901 => '215',
+ 8992 => '243',
+ 8993 => '245',
+ 9001 => '225',
+ 9002 => '241',
+ 9312 => '172',
+ 9313 => '173',
+ 9314 => '174',
+ 9315 => '175',
+ 9316 => '176',
+ 9317 => '177',
+ 9318 => '178',
+ 9319 => '179',
+ 9320 => '180',
+ 9321 => '181',
+ 9632 => '110',
+ 9650 => '115',
+ 9660 => '116',
+ 9670 => '117',
+ 9674 => '224',
+ 9679 => '108',
+ 9687 => '119',
+ 9733 => '72',
+ 9742 => '37',
+ 9755 => '42',
+ 9758 => '43',
+ 9824 => '170',
+ 9827 => '167',
+ 9829 => '169',
+ 9830 => '168',
+ 9985 => '33',
+ 9986 => '34',
+ 9987 => '35',
+ 9988 => '36',
+ 9990 => '38',
+ 9991 => '39',
+ 9992 => '40',
+ 9993 => '41',
+ 9996 => '44',
+ 9997 => '45',
+ 9998 => '46',
+ 9999 => '47',
+ 10000 => '48',
+ 10001 => '49',
+ 10002 => '50',
+ 10003 => '51',
+ 10004 => '52',
+ 10005 => '53',
+ 10006 => '54',
+ 10007 => '55',
+ 10008 => '56',
+ 10009 => '57',
+ 10010 => '58',
+ 10011 => '59',
+ 10012 => '60',
+ 10013 => '61',
+ 10014 => '62',
+ 10015 => '63',
+ 10016 => '64',
+ 10017 => '65',
+ 10018 => '66',
+ 10019 => '67',
+ 10020 => '68',
+ 10021 => '69',
+ 10022 => '70',
+ 10023 => '71',
+ 10025 => '73',
+ 10026 => '74',
+ 10027 => '75',
+ 10028 => '76',
+ 10029 => '77',
+ 10030 => '78',
+ 10031 => '79',
+ 10032 => '80',
+ 10033 => '81',
+ 10034 => '82',
+ 10035 => '83',
+ 10036 => '84',
+ 10037 => '85',
+ 10038 => '86',
+ 10039 => '87',
+ 10040 => '88',
+ 10041 => '89',
+ 10042 => '90',
+ 10043 => '91',
+ 10044 => '92',
+ 10045 => '93',
+ 10046 => '94',
+ 10047 => '95',
+ 10048 => '96',
+ 10049 => '97',
+ 10050 => '98',
+ 10051 => '99',
+ 10052 => '100',
+ 10053 => '101',
+ 10054 => '102',
+ 10055 => '103',
+ 10056 => '104',
+ 10057 => '105',
+ 10058 => '106',
+ 10059 => '107',
+ 10061 => '109',
+ 10063 => '111',
+ 10064 => '112',
+ 10065 => '113',
+ 10066 => '114',
+ 10070 => '118',
+ 10072 => '120',
+ 10073 => '121',
+ 10074 => '122',
+ 10075 => '123',
+ 10076 => '124',
+ 10077 => '125',
+ 10078 => '126',
+ 10081 => '161',
+ 10082 => '162',
+ 10083 => '163',
+ 10084 => '164',
+ 10085 => '165',
+ 10086 => '166',
+ 10087 => '167',
+ 10102 => '182',
+ 10103 => '183',
+ 10104 => '184',
+ 10105 => '185',
+ 10106 => '186',
+ 10107 => '187',
+ 10108 => '188',
+ 10109 => '189',
+ 10110 => '190',
+ 10111 => '191',
+ 10112 => '192',
+ 10113 => '193',
+ 10114 => '194',
+ 10115 => '195',
+ 10116 => '196',
+ 10117 => '197',
+ 10118 => '198',
+ 10119 => '199',
+ 10120 => '200',
+ 10121 => '201',
+ 10122 => '202',
+ 10123 => '203',
+ 10124 => '204',
+ 10125 => '205',
+ 10126 => '206',
+ 10127 => '207',
+ 10128 => '208',
+ 10129 => '209',
+ 10130 => '210',
+ 10131 => '211',
+ 10132 => '212',
+ 10136 => '216',
+ 10137 => '217',
+ 10138 => '218',
+ 10139 => '219',
+ 10140 => '220',
+ 10141 => '221',
+ 10142 => '222',
+ 10143 => '223',
+ 10144 => '224',
+ 10145 => '225',
+ 10146 => '226',
+ 10147 => '227',
+ 10148 => '228',
+ 10149 => '229',
+ 10150 => '230',
+ 10151 => '231',
+ 10152 => '232',
+ 10153 => '233',
+ 10154 => '234',
+ 10155 => '235',
+ 10156 => '236',
+ 10157 => '237',
+ 10158 => '238',
+ 10159 => '239',
+ 10161 => '241',
+ 10162 => '242',
+ 10163 => '243',
+ 10164 => '244',
+ 10165 => '245',
+ 10166 => '246',
+ 10167 => '247',
+ 10168 => '248',
+ 10169 => '249',
+ 10170 => '250',
+ 10171 => '251',
+ 10172 => '252',
+ 10173 => '253',
+ 10174 => '254',
+);
+
+?>
\ No newline at end of file
diff --git a/mpdf/includes/upperCase.php b/mpdf/includes/upperCase.php
new file mode 100644
index 0000000..020f426
--- /dev/null
+++ b/mpdf/includes/upperCase.php
@@ -0,0 +1,975 @@
+upperCase=array (
+ 97 => 65,
+ 98 => 66,
+ 99 => 67,
+ 100 => 68,
+ 101 => 69,
+ 102 => 70,
+ 103 => 71,
+ 104 => 72,
+ 105 => 73,
+ 106 => 74,
+ 107 => 75,
+ 108 => 76,
+ 109 => 77,
+ 110 => 78,
+ 111 => 79,
+ 112 => 80,
+ 113 => 81,
+ 114 => 82,
+ 115 => 83,
+ 116 => 84,
+ 117 => 85,
+ 118 => 86,
+ 119 => 87,
+ 120 => 88,
+ 121 => 89,
+ 122 => 90,
+ 181 => 924,
+ 224 => 192,
+ 225 => 193,
+ 226 => 194,
+ 227 => 195,
+ 228 => 196,
+ 229 => 197,
+ 230 => 198,
+ 231 => 199,
+ 232 => 200,
+ 233 => 201,
+ 234 => 202,
+ 235 => 203,
+ 236 => 204,
+ 237 => 205,
+ 238 => 206,
+ 239 => 207,
+ 240 => 208,
+ 241 => 209,
+ 242 => 210,
+ 243 => 211,
+ 244 => 212,
+ 245 => 213,
+ 246 => 214,
+ 248 => 216,
+ 249 => 217,
+ 250 => 218,
+ 251 => 219,
+ 252 => 220,
+ 253 => 221,
+ 254 => 222,
+ 255 => 376,
+ 257 => 256,
+ 259 => 258,
+ 261 => 260,
+ 263 => 262,
+ 265 => 264,
+ 267 => 266,
+ 269 => 268,
+ 271 => 270,
+ 273 => 272,
+ 275 => 274,
+ 277 => 276,
+ 279 => 278,
+ 281 => 280,
+ 283 => 282,
+ 285 => 284,
+ 287 => 286,
+ 289 => 288,
+ 291 => 290,
+ 293 => 292,
+ 295 => 294,
+ 297 => 296,
+ 299 => 298,
+ 301 => 300,
+ 303 => 302,
+ 305 => 73,
+ 307 => 306,
+ 309 => 308,
+ 311 => 310,
+ 314 => 313,
+ 316 => 315,
+ 318 => 317,
+ 320 => 319,
+ 322 => 321,
+ 324 => 323,
+ 326 => 325,
+ 328 => 327,
+ 331 => 330,
+ 333 => 332,
+ 335 => 334,
+ 337 => 336,
+ 339 => 338,
+ 341 => 340,
+ 343 => 342,
+ 345 => 344,
+ 347 => 346,
+ 349 => 348,
+ 351 => 350,
+ 353 => 352,
+ 355 => 354,
+ 357 => 356,
+ 359 => 358,
+ 361 => 360,
+ 363 => 362,
+ 365 => 364,
+ 367 => 366,
+ 369 => 368,
+ 371 => 370,
+ 373 => 372,
+ 375 => 374,
+ 378 => 377,
+ 380 => 379,
+ 382 => 381,
+ 383 => 83,
+ 384 => 579,
+ 387 => 386,
+ 389 => 388,
+ 392 => 391,
+ 396 => 395,
+ 402 => 401,
+ 405 => 502,
+ 409 => 408,
+ 410 => 573,
+ 414 => 544,
+ 417 => 416,
+ 419 => 418,
+ 421 => 420,
+ 424 => 423,
+ 429 => 428,
+ 432 => 431,
+ 436 => 435,
+ 438 => 437,
+ 441 => 440,
+ 445 => 444,
+ 447 => 503,
+ 453 => 452,
+ 454 => 452,
+ 456 => 455,
+ 457 => 455,
+ 459 => 458,
+ 460 => 458,
+ 462 => 461,
+ 464 => 463,
+ 466 => 465,
+ 468 => 467,
+ 470 => 469,
+ 472 => 471,
+ 474 => 473,
+ 476 => 475,
+ 477 => 398,
+ 479 => 478,
+ 481 => 480,
+ 483 => 482,
+ 485 => 484,
+ 487 => 486,
+ 489 => 488,
+ 491 => 490,
+ 493 => 492,
+ 495 => 494,
+ 498 => 497,
+ 499 => 497,
+ 501 => 500,
+ 505 => 504,
+ 507 => 506,
+ 509 => 508,
+ 511 => 510,
+ 513 => 512,
+ 515 => 514,
+ 517 => 516,
+ 519 => 518,
+ 521 => 520,
+ 523 => 522,
+ 525 => 524,
+ 527 => 526,
+ 529 => 528,
+ 531 => 530,
+ 533 => 532,
+ 535 => 534,
+ 537 => 536,
+ 539 => 538,
+ 541 => 540,
+ 543 => 542,
+ 547 => 546,
+ 549 => 548,
+ 551 => 550,
+ 553 => 552,
+ 555 => 554,
+ 557 => 556,
+ 559 => 558,
+ 561 => 560,
+ 563 => 562,
+ 572 => 571,
+ 575 => 11390,
+ 576 => 11391,
+ 578 => 577,
+ 583 => 582,
+ 585 => 584,
+ 587 => 586,
+ 589 => 588,
+ 591 => 590,
+ 592 => 11375,
+ 593 => 11373,
+ 594 => 11376,
+ 595 => 385,
+ 596 => 390,
+ 598 => 393,
+ 599 => 394,
+ 601 => 399,
+ 603 => 400,
+ 608 => 403,
+ 611 => 404,
+ 616 => 407,
+ 617 => 406,
+ 619 => 11362,
+ 623 => 412,
+ 625 => 11374,
+ 626 => 413,
+ 629 => 415,
+ 637 => 11364,
+ 640 => 422,
+ 643 => 425,
+ 648 => 430,
+ 649 => 580,
+ 650 => 433,
+ 651 => 434,
+ 652 => 581,
+ 658 => 439,
+ 837 => 921,
+ 881 => 880,
+ 883 => 882,
+ 887 => 886,
+ 891 => 1021,
+ 892 => 1022,
+ 893 => 1023,
+ 940 => 902,
+ 941 => 904,
+ 942 => 905,
+ 943 => 906,
+ 945 => 913,
+ 946 => 914,
+ 947 => 915,
+ 948 => 916,
+ 949 => 917,
+ 950 => 918,
+ 951 => 919,
+ 952 => 920,
+ 953 => 921,
+ 954 => 922,
+ 955 => 923,
+ 956 => 924,
+ 957 => 925,
+ 958 => 926,
+ 959 => 927,
+ 960 => 928,
+ 961 => 929,
+ 962 => 931,
+ 963 => 931,
+ 964 => 932,
+ 965 => 933,
+ 966 => 934,
+ 967 => 935,
+ 968 => 936,
+ 969 => 937,
+ 970 => 938,
+ 971 => 939,
+ 972 => 908,
+ 973 => 910,
+ 974 => 911,
+ 976 => 914,
+ 977 => 920,
+ 981 => 934,
+ 982 => 928,
+ 983 => 975,
+ 985 => 984,
+ 987 => 986,
+ 989 => 988,
+ 991 => 990,
+ 993 => 992,
+ 995 => 994,
+ 997 => 996,
+ 999 => 998,
+ 1001 => 1000,
+ 1003 => 1002,
+ 1005 => 1004,
+ 1007 => 1006,
+ 1008 => 922,
+ 1009 => 929,
+ 1010 => 1017,
+ 1013 => 917,
+ 1016 => 1015,
+ 1019 => 1018,
+ 1072 => 1040,
+ 1073 => 1041,
+ 1074 => 1042,
+ 1075 => 1043,
+ 1076 => 1044,
+ 1077 => 1045,
+ 1078 => 1046,
+ 1079 => 1047,
+ 1080 => 1048,
+ 1081 => 1049,
+ 1082 => 1050,
+ 1083 => 1051,
+ 1084 => 1052,
+ 1085 => 1053,
+ 1086 => 1054,
+ 1087 => 1055,
+ 1088 => 1056,
+ 1089 => 1057,
+ 1090 => 1058,
+ 1091 => 1059,
+ 1092 => 1060,
+ 1093 => 1061,
+ 1094 => 1062,
+ 1095 => 1063,
+ 1096 => 1064,
+ 1097 => 1065,
+ 1098 => 1066,
+ 1099 => 1067,
+ 1100 => 1068,
+ 1101 => 1069,
+ 1102 => 1070,
+ 1103 => 1071,
+ 1104 => 1024,
+ 1105 => 1025,
+ 1106 => 1026,
+ 1107 => 1027,
+ 1108 => 1028,
+ 1109 => 1029,
+ 1110 => 1030,
+ 1111 => 1031,
+ 1112 => 1032,
+ 1113 => 1033,
+ 1114 => 1034,
+ 1115 => 1035,
+ 1116 => 1036,
+ 1117 => 1037,
+ 1118 => 1038,
+ 1119 => 1039,
+ 1121 => 1120,
+ 1123 => 1122,
+ 1125 => 1124,
+ 1127 => 1126,
+ 1129 => 1128,
+ 1131 => 1130,
+ 1133 => 1132,
+ 1135 => 1134,
+ 1137 => 1136,
+ 1139 => 1138,
+ 1141 => 1140,
+ 1143 => 1142,
+ 1145 => 1144,
+ 1147 => 1146,
+ 1149 => 1148,
+ 1151 => 1150,
+ 1153 => 1152,
+ 1163 => 1162,
+ 1165 => 1164,
+ 1167 => 1166,
+ 1169 => 1168,
+ 1171 => 1170,
+ 1173 => 1172,
+ 1175 => 1174,
+ 1177 => 1176,
+ 1179 => 1178,
+ 1181 => 1180,
+ 1183 => 1182,
+ 1185 => 1184,
+ 1187 => 1186,
+ 1189 => 1188,
+ 1191 => 1190,
+ 1193 => 1192,
+ 1195 => 1194,
+ 1197 => 1196,
+ 1199 => 1198,
+ 1201 => 1200,
+ 1203 => 1202,
+ 1205 => 1204,
+ 1207 => 1206,
+ 1209 => 1208,
+ 1211 => 1210,
+ 1213 => 1212,
+ 1215 => 1214,
+ 1218 => 1217,
+ 1220 => 1219,
+ 1222 => 1221,
+ 1224 => 1223,
+ 1226 => 1225,
+ 1228 => 1227,
+ 1230 => 1229,
+ 1231 => 1216,
+ 1233 => 1232,
+ 1235 => 1234,
+ 1237 => 1236,
+ 1239 => 1238,
+ 1241 => 1240,
+ 1243 => 1242,
+ 1245 => 1244,
+ 1247 => 1246,
+ 1249 => 1248,
+ 1251 => 1250,
+ 1253 => 1252,
+ 1255 => 1254,
+ 1257 => 1256,
+ 1259 => 1258,
+ 1261 => 1260,
+ 1263 => 1262,
+ 1265 => 1264,
+ 1267 => 1266,
+ 1269 => 1268,
+ 1271 => 1270,
+ 1273 => 1272,
+ 1275 => 1274,
+ 1277 => 1276,
+ 1279 => 1278,
+ 1281 => 1280,
+ 1283 => 1282,
+ 1285 => 1284,
+ 1287 => 1286,
+ 1289 => 1288,
+ 1291 => 1290,
+ 1293 => 1292,
+ 1295 => 1294,
+ 1297 => 1296,
+ 1299 => 1298,
+ 1301 => 1300,
+ 1303 => 1302,
+ 1305 => 1304,
+ 1307 => 1306,
+ 1309 => 1308,
+ 1311 => 1310,
+ 1313 => 1312,
+ 1315 => 1314,
+ 1317 => 1316,
+ 1377 => 1329,
+ 1378 => 1330,
+ 1379 => 1331,
+ 1380 => 1332,
+ 1381 => 1333,
+ 1382 => 1334,
+ 1383 => 1335,
+ 1384 => 1336,
+ 1385 => 1337,
+ 1386 => 1338,
+ 1387 => 1339,
+ 1388 => 1340,
+ 1389 => 1341,
+ 1390 => 1342,
+ 1391 => 1343,
+ 1392 => 1344,
+ 1393 => 1345,
+ 1394 => 1346,
+ 1395 => 1347,
+ 1396 => 1348,
+ 1397 => 1349,
+ 1398 => 1350,
+ 1399 => 1351,
+ 1400 => 1352,
+ 1401 => 1353,
+ 1402 => 1354,
+ 1403 => 1355,
+ 1404 => 1356,
+ 1405 => 1357,
+ 1406 => 1358,
+ 1407 => 1359,
+ 1408 => 1360,
+ 1409 => 1361,
+ 1410 => 1362,
+ 1411 => 1363,
+ 1412 => 1364,
+ 1413 => 1365,
+ 1414 => 1366,
+ 7545 => 42877,
+ 7549 => 11363,
+ 7681 => 7680,
+ 7683 => 7682,
+ 7685 => 7684,
+ 7687 => 7686,
+ 7689 => 7688,
+ 7691 => 7690,
+ 7693 => 7692,
+ 7695 => 7694,
+ 7697 => 7696,
+ 7699 => 7698,
+ 7701 => 7700,
+ 7703 => 7702,
+ 7705 => 7704,
+ 7707 => 7706,
+ 7709 => 7708,
+ 7711 => 7710,
+ 7713 => 7712,
+ 7715 => 7714,
+ 7717 => 7716,
+ 7719 => 7718,
+ 7721 => 7720,
+ 7723 => 7722,
+ 7725 => 7724,
+ 7727 => 7726,
+ 7729 => 7728,
+ 7731 => 7730,
+ 7733 => 7732,
+ 7735 => 7734,
+ 7737 => 7736,
+ 7739 => 7738,
+ 7741 => 7740,
+ 7743 => 7742,
+ 7745 => 7744,
+ 7747 => 7746,
+ 7749 => 7748,
+ 7751 => 7750,
+ 7753 => 7752,
+ 7755 => 7754,
+ 7757 => 7756,
+ 7759 => 7758,
+ 7761 => 7760,
+ 7763 => 7762,
+ 7765 => 7764,
+ 7767 => 7766,
+ 7769 => 7768,
+ 7771 => 7770,
+ 7773 => 7772,
+ 7775 => 7774,
+ 7777 => 7776,
+ 7779 => 7778,
+ 7781 => 7780,
+ 7783 => 7782,
+ 7785 => 7784,
+ 7787 => 7786,
+ 7789 => 7788,
+ 7791 => 7790,
+ 7793 => 7792,
+ 7795 => 7794,
+ 7797 => 7796,
+ 7799 => 7798,
+ 7801 => 7800,
+ 7803 => 7802,
+ 7805 => 7804,
+ 7807 => 7806,
+ 7809 => 7808,
+ 7811 => 7810,
+ 7813 => 7812,
+ 7815 => 7814,
+ 7817 => 7816,
+ 7819 => 7818,
+ 7821 => 7820,
+ 7823 => 7822,
+ 7825 => 7824,
+ 7827 => 7826,
+ 7829 => 7828,
+ 7835 => 7776,
+ 7841 => 7840,
+ 7843 => 7842,
+ 7845 => 7844,
+ 7847 => 7846,
+ 7849 => 7848,
+ 7851 => 7850,
+ 7853 => 7852,
+ 7855 => 7854,
+ 7857 => 7856,
+ 7859 => 7858,
+ 7861 => 7860,
+ 7863 => 7862,
+ 7865 => 7864,
+ 7867 => 7866,
+ 7869 => 7868,
+ 7871 => 7870,
+ 7873 => 7872,
+ 7875 => 7874,
+ 7877 => 7876,
+ 7879 => 7878,
+ 7881 => 7880,
+ 7883 => 7882,
+ 7885 => 7884,
+ 7887 => 7886,
+ 7889 => 7888,
+ 7891 => 7890,
+ 7893 => 7892,
+ 7895 => 7894,
+ 7897 => 7896,
+ 7899 => 7898,
+ 7901 => 7900,
+ 7903 => 7902,
+ 7905 => 7904,
+ 7907 => 7906,
+ 7909 => 7908,
+ 7911 => 7910,
+ 7913 => 7912,
+ 7915 => 7914,
+ 7917 => 7916,
+ 7919 => 7918,
+ 7921 => 7920,
+ 7923 => 7922,
+ 7925 => 7924,
+ 7927 => 7926,
+ 7929 => 7928,
+ 7931 => 7930,
+ 7933 => 7932,
+ 7935 => 7934,
+ 7936 => 7944,
+ 7937 => 7945,
+ 7938 => 7946,
+ 7939 => 7947,
+ 7940 => 7948,
+ 7941 => 7949,
+ 7942 => 7950,
+ 7943 => 7951,
+ 7952 => 7960,
+ 7953 => 7961,
+ 7954 => 7962,
+ 7955 => 7963,
+ 7956 => 7964,
+ 7957 => 7965,
+ 7968 => 7976,
+ 7969 => 7977,
+ 7970 => 7978,
+ 7971 => 7979,
+ 7972 => 7980,
+ 7973 => 7981,
+ 7974 => 7982,
+ 7975 => 7983,
+ 7984 => 7992,
+ 7985 => 7993,
+ 7986 => 7994,
+ 7987 => 7995,
+ 7988 => 7996,
+ 7989 => 7997,
+ 7990 => 7998,
+ 7991 => 7999,
+ 8000 => 8008,
+ 8001 => 8009,
+ 8002 => 8010,
+ 8003 => 8011,
+ 8004 => 8012,
+ 8005 => 8013,
+ 8017 => 8025,
+ 8019 => 8027,
+ 8021 => 8029,
+ 8023 => 8031,
+ 8032 => 8040,
+ 8033 => 8041,
+ 8034 => 8042,
+ 8035 => 8043,
+ 8036 => 8044,
+ 8037 => 8045,
+ 8038 => 8046,
+ 8039 => 8047,
+ 8048 => 8122,
+ 8049 => 8123,
+ 8050 => 8136,
+ 8051 => 8137,
+ 8052 => 8138,
+ 8053 => 8139,
+ 8054 => 8154,
+ 8055 => 8155,
+ 8056 => 8184,
+ 8057 => 8185,
+ 8058 => 8170,
+ 8059 => 8171,
+ 8060 => 8186,
+ 8061 => 8187,
+ 8064 => 8072,
+ 8065 => 8073,
+ 8066 => 8074,
+ 8067 => 8075,
+ 8068 => 8076,
+ 8069 => 8077,
+ 8070 => 8078,
+ 8071 => 8079,
+ 8080 => 8088,
+ 8081 => 8089,
+ 8082 => 8090,
+ 8083 => 8091,
+ 8084 => 8092,
+ 8085 => 8093,
+ 8086 => 8094,
+ 8087 => 8095,
+ 8096 => 8104,
+ 8097 => 8105,
+ 8098 => 8106,
+ 8099 => 8107,
+ 8100 => 8108,
+ 8101 => 8109,
+ 8102 => 8110,
+ 8103 => 8111,
+ 8112 => 8120,
+ 8113 => 8121,
+ 8115 => 8124,
+ 8126 => 921,
+ 8131 => 8140,
+ 8144 => 8152,
+ 8145 => 8153,
+ 8160 => 8168,
+ 8161 => 8169,
+ 8165 => 8172,
+ 8179 => 8188,
+ 8526 => 8498,
+ 8560 => 8544,
+ 8561 => 8545,
+ 8562 => 8546,
+ 8563 => 8547,
+ 8564 => 8548,
+ 8565 => 8549,
+ 8566 => 8550,
+ 8567 => 8551,
+ 8568 => 8552,
+ 8569 => 8553,
+ 8570 => 8554,
+ 8571 => 8555,
+ 8572 => 8556,
+ 8573 => 8557,
+ 8574 => 8558,
+ 8575 => 8559,
+ 8580 => 8579,
+ 9424 => 9398,
+ 9425 => 9399,
+ 9426 => 9400,
+ 9427 => 9401,
+ 9428 => 9402,
+ 9429 => 9403,
+ 9430 => 9404,
+ 9431 => 9405,
+ 9432 => 9406,
+ 9433 => 9407,
+ 9434 => 9408,
+ 9435 => 9409,
+ 9436 => 9410,
+ 9437 => 9411,
+ 9438 => 9412,
+ 9439 => 9413,
+ 9440 => 9414,
+ 9441 => 9415,
+ 9442 => 9416,
+ 9443 => 9417,
+ 9444 => 9418,
+ 9445 => 9419,
+ 9446 => 9420,
+ 9447 => 9421,
+ 9448 => 9422,
+ 9449 => 9423,
+ 11312 => 11264,
+ 11313 => 11265,
+ 11314 => 11266,
+ 11315 => 11267,
+ 11316 => 11268,
+ 11317 => 11269,
+ 11318 => 11270,
+ 11319 => 11271,
+ 11320 => 11272,
+ 11321 => 11273,
+ 11322 => 11274,
+ 11323 => 11275,
+ 11324 => 11276,
+ 11325 => 11277,
+ 11326 => 11278,
+ 11327 => 11279,
+ 11328 => 11280,
+ 11329 => 11281,
+ 11330 => 11282,
+ 11331 => 11283,
+ 11332 => 11284,
+ 11333 => 11285,
+ 11334 => 11286,
+ 11335 => 11287,
+ 11336 => 11288,
+ 11337 => 11289,
+ 11338 => 11290,
+ 11339 => 11291,
+ 11340 => 11292,
+ 11341 => 11293,
+ 11342 => 11294,
+ 11343 => 11295,
+ 11344 => 11296,
+ 11345 => 11297,
+ 11346 => 11298,
+ 11347 => 11299,
+ 11348 => 11300,
+ 11349 => 11301,
+ 11350 => 11302,
+ 11351 => 11303,
+ 11352 => 11304,
+ 11353 => 11305,
+ 11354 => 11306,
+ 11355 => 11307,
+ 11356 => 11308,
+ 11357 => 11309,
+ 11358 => 11310,
+ 11361 => 11360,
+ 11365 => 570,
+ 11366 => 574,
+ 11368 => 11367,
+ 11370 => 11369,
+ 11372 => 11371,
+ 11379 => 11378,
+ 11382 => 11381,
+ 11393 => 11392,
+ 11395 => 11394,
+ 11397 => 11396,
+ 11399 => 11398,
+ 11401 => 11400,
+ 11403 => 11402,
+ 11405 => 11404,
+ 11407 => 11406,
+ 11409 => 11408,
+ 11411 => 11410,
+ 11413 => 11412,
+ 11415 => 11414,
+ 11417 => 11416,
+ 11419 => 11418,
+ 11421 => 11420,
+ 11423 => 11422,
+ 11425 => 11424,
+ 11427 => 11426,
+ 11429 => 11428,
+ 11431 => 11430,
+ 11433 => 11432,
+ 11435 => 11434,
+ 11437 => 11436,
+ 11439 => 11438,
+ 11441 => 11440,
+ 11443 => 11442,
+ 11445 => 11444,
+ 11447 => 11446,
+ 11449 => 11448,
+ 11451 => 11450,
+ 11453 => 11452,
+ 11455 => 11454,
+ 11457 => 11456,
+ 11459 => 11458,
+ 11461 => 11460,
+ 11463 => 11462,
+ 11465 => 11464,
+ 11467 => 11466,
+ 11469 => 11468,
+ 11471 => 11470,
+ 11473 => 11472,
+ 11475 => 11474,
+ 11477 => 11476,
+ 11479 => 11478,
+ 11481 => 11480,
+ 11483 => 11482,
+ 11485 => 11484,
+ 11487 => 11486,
+ 11489 => 11488,
+ 11491 => 11490,
+ 11500 => 11499,
+ 11502 => 11501,
+ 11520 => 4256,
+ 11521 => 4257,
+ 11522 => 4258,
+ 11523 => 4259,
+ 11524 => 4260,
+ 11525 => 4261,
+ 11526 => 4262,
+ 11527 => 4263,
+ 11528 => 4264,
+ 11529 => 4265,
+ 11530 => 4266,
+ 11531 => 4267,
+ 11532 => 4268,
+ 11533 => 4269,
+ 11534 => 4270,
+ 11535 => 4271,
+ 11536 => 4272,
+ 11537 => 4273,
+ 11538 => 4274,
+ 11539 => 4275,
+ 11540 => 4276,
+ 11541 => 4277,
+ 11542 => 4278,
+ 11543 => 4279,
+ 11544 => 4280,
+ 11545 => 4281,
+ 11546 => 4282,
+ 11547 => 4283,
+ 11548 => 4284,
+ 11549 => 4285,
+ 11550 => 4286,
+ 11551 => 4287,
+ 11552 => 4288,
+ 11553 => 4289,
+ 11554 => 4290,
+ 11555 => 4291,
+ 11556 => 4292,
+ 11557 => 4293,
+ 42561 => 42560,
+ 42563 => 42562,
+ 42565 => 42564,
+ 42567 => 42566,
+ 42569 => 42568,
+ 42571 => 42570,
+ 42573 => 42572,
+ 42575 => 42574,
+ 42577 => 42576,
+ 42579 => 42578,
+ 42581 => 42580,
+ 42583 => 42582,
+ 42585 => 42584,
+ 42587 => 42586,
+ 42589 => 42588,
+ 42591 => 42590,
+ 42595 => 42594,
+ 42597 => 42596,
+ 42599 => 42598,
+ 42601 => 42600,
+ 42603 => 42602,
+ 42605 => 42604,
+ 42625 => 42624,
+ 42627 => 42626,
+ 42629 => 42628,
+ 42631 => 42630,
+ 42633 => 42632,
+ 42635 => 42634,
+ 42637 => 42636,
+ 42639 => 42638,
+ 42641 => 42640,
+ 42643 => 42642,
+ 42645 => 42644,
+ 42647 => 42646,
+ 42787 => 42786,
+ 42789 => 42788,
+ 42791 => 42790,
+ 42793 => 42792,
+ 42795 => 42794,
+ 42797 => 42796,
+ 42799 => 42798,
+ 42803 => 42802,
+ 42805 => 42804,
+ 42807 => 42806,
+ 42809 => 42808,
+ 42811 => 42810,
+ 42813 => 42812,
+ 42815 => 42814,
+ 42817 => 42816,
+ 42819 => 42818,
+ 42821 => 42820,
+ 42823 => 42822,
+ 42825 => 42824,
+ 42827 => 42826,
+ 42829 => 42828,
+ 42831 => 42830,
+ 42833 => 42832,
+ 42835 => 42834,
+ 42837 => 42836,
+ 42839 => 42838,
+ 42841 => 42840,
+ 42843 => 42842,
+ 42845 => 42844,
+ 42847 => 42846,
+ 42849 => 42848,
+ 42851 => 42850,
+ 42853 => 42852,
+ 42855 => 42854,
+ 42857 => 42856,
+ 42859 => 42858,
+ 42861 => 42860,
+ 42863 => 42862,
+ 42874 => 42873,
+ 42876 => 42875,
+ 42879 => 42878,
+ 42881 => 42880,
+ 42883 => 42882,
+ 42885 => 42884,
+ 42887 => 42886,
+ 42892 => 42891,
+);
+?>
\ No newline at end of file
diff --git a/mpdf/lang2fonts.css b/mpdf/lang2fonts.css
new file mode 100644
index 0000000..e60b784
--- /dev/null
+++ b/mpdf/lang2fonts.css
@@ -0,0 +1,394 @@
+/* European */
+:lang("en"), :lang("eng"), /* English */ /* LATIN */
+:lang("eu"), :lang("eus"), /* Basque */
+:lang("br"), :lang("bre"), /* Breton */
+:lang("ca"), :lang("cat"), /* Catalan */
+:lang("co"), :lang("cos"), /* Corsican */
+:lang("kw"), :lang("cor"), /* Cornish */
+:lang("cy"), :lang("cym"), /* Welsh */
+:lang("cs"), :lang("ces"), /* Czech */
+:lang("da"), :lang("dan"), /* Danish */
+:lang("nl"), :lang("nld"), /* Dutch */
+:lang("et"), :lang("est"), /* Estonian */
+:lang("fo"), :lang("fao"), /* Faroese */
+:lang("fi"), :lang("fin"), /* Finnish */
+:lang("fr"), :lang("fra"), /* French */
+:lang("gl"), :lang("glg"), /* Galician */
+:lang("de"), :lang("deu"), /* German */
+:lang("ht"), :lang("hat"), /* Haitian; Haitian Creole */
+:lang("hu"), :lang("hun"), /* Hungarian */
+:lang("ga"), :lang("gle"), /* Irish */
+:lang("is"), :lang("isl"), /* Icelandic */
+:lang("it"), :lang("ita"), /* Italian */
+:lang("la"), :lang("lat"), /* Latin */
+:lang("lb"), :lang("ltz"), /* Luxembourgish */
+:lang("li"), :lang("lim"), /* Limburgish */
+:lang("lt"), :lang("lit"), /* Lithuanian */
+:lang("lv"), :lang("lav"), /* Latvian */
+:lang("gv"), :lang("glv"), /* Manx */
+:lang("no"), :lang("nor"), /* Norwegian */
+:lang("nn"), :lang("nno"), /* Norwegian Nynorsk */
+:lang("nb"), :lang("nob"), /* Norwegian Bokmal */
+:lang("pl"), :lang("pol"), /* Polish */
+:lang("pt"), :lang("por"), /* Portuguese */
+:lang("ro"), :lang("ron"), /* Romanian */
+:lang("gd"), :lang("gla"), /* Scottish Gaelic */
+:lang("es"), :lang("spa"), /* Spanish */
+:lang("sv"), :lang("swe"), /* Swedish */
+:lang("sl"), :lang("slv"), /* Slovene */
+:lang("sk"), :lang("slk") { /* Slovak */
+ font-family: dejavusanscondensed;
+}
+
+
+:lang("el"), :lang("ell") { /* GREEK */
+ font-family: dejavusanscondensed;
+}
+
+:lang("ru"), :lang("rus"), /* Russian */ /* CYRILLIC */
+:lang("ab"), :lang("abk"), /* Abkhaz */
+:lang("av"), :lang("ava"), /* Avaric */
+:lang("ba"), :lang("bak"), /* Bashkir */
+:lang("be"), :lang("bel"), /* Belarusian */
+:lang("bg"), :lang("bul"), /* Bulgarian */
+:lang("ce"), :lang("che"), /* Chechen */
+:lang("cv"), :lang("chv"), /* Chuvash */
+:lang("kk"), :lang("kaz"), /* Kazakh */
+:lang("kv"), :lang("kom"), /* Komi */
+:lang("ky"), :lang("kir"), /* Kyrgyz */
+:lang("mk"), :lang("mkd"), /* Macedonian */
+:lang("cu"), :lang("chu"), /* Old Church Slavonic */
+:lang("os"), :lang("oss"), /* Ossetian */
+:lang("sr"), :lang("srp"), /* Serbian */
+:lang("tg"), :lang("tgk"), /* Tajik */
+:lang("tt"), :lang("tat"), /* Tatar */
+:lang("tk"), :lang("tuk"), /* Turkmen */
+:lang("uk"), :lang("ukr") { /* Ukrainian */
+ font-family: dejavusanscondensed;
+}
+
+
+
+:lang("hy"), :lang("hye") { /* ARMENIAN */
+ font-family: dejavusanscondensed;
+}
+:lang("ka"), :lang("kat") { /* GEORGIAN */
+ font-family: dejavusanscondensed;
+}
+:lang("cop") { /* COPTIC */
+ font-family: quivira;
+}
+:lang("got") { /* GOTHIC */
+ font-family: freeserif;
+}
+:lang("und-Latn") { /* LATIN */
+ font-family: dejavusanscondensed;
+}
+:lang("und-Cyrl") { /* CYRILLIC */
+ font-family: dejavusanscondensed;
+}
+:lang("und-Cprt") { /* CYPRIOT */
+ font-family: aegean;
+}
+:lang("und-Glag") { /* GLAGOLITIC */
+ font-family: mph2bdamase;
+}
+:lang("und-Linb") { /* LINEAR_B */
+ font-family: aegean;
+}
+:lang("und-Ogam") { /* OGHAM */
+ font-family: dejavusanscondensed;
+}
+:lang("und-Ital") { /* OLD_ITALIC */
+ font-family: aegean;
+}
+:lang("und-Runr") { /* RUNIC */
+ font-family: sun-exta;
+}
+:lang("und-Shaw") { /* SHAVIAN */
+ font-family: mph2bdamase;
+}
+
+
+
+
+/* African */
+:lang("am"), :lang("amh") { /* Amharic ETHIOPIC */
+ font-family: abyssinicasil;
+}
+:lang("ti"), :lang("tir") { /* Tigrinya ETHIOPIC */
+ font-family: abyssinicasil;
+}
+:lang("nqo") { /* NKO */
+ font-family: dejavusanscondensed;
+}
+:lang("vai") { /* VAI */
+ font-family: freesans;
+}
+:lang("und-Egyp") { /* EGYPTIAN_HIEROGLYPHS */
+ font-family: aegyptus;
+}
+:lang("und-Ethi") { /* ETHIOPIC */
+ font-family: abyssinicasil;
+}
+:lang("und-Osma") { /* OSMANYA */
+ font-family: mph2bdamase;
+}
+:lang("und-Tfng") { /* TIFINAGH */
+ font-family: dejavusanscondensed;
+}
+
+
+
+
+
+/* Middle Eastern */
+:lang("ar"), :lang("ara") { /* Arabic */
+ font-family: xbriyaz;
+}
+:lang("fa"), :lang("fas") { /* Persian (Farsi) */
+ font-family: xbriyaz;
+}
+:lang("ku"), :lang("kur") { /* Kurdish */
+ font-family: xbriyaz;
+}
+:lang("ps"), :lang("pus") { /* Pashto */
+ font-family: xbriyaz;
+}
+:lang("ur"), :lang("urd") { /* Urdu */
+ font-family: xbriyaz;
+}
+:lang("he"), :lang("heb") { /* HEBREW */
+ font-family: taameydavidclm;
+}
+:lang("yi"), :lang("yid") { /* Yiddish */
+ font-family: taameydavidclm;
+}
+:lang("syr") { /* SYRIAC */
+ font-family: estrangeloedessa;
+}
+
+:lang("xcr") { /* CARIAN */
+ font-family: aegean;
+}
+:lang("xlc") { /* LYCIAN */
+ font-family: aegean;
+}
+:lang("xld") { /* LYDIAN */
+ font-family: aegean;
+}
+:lang("phn") { /* PHOENICIAN */
+ font-family: aegean;
+}
+:lang("uga") { /* UGARITIC */
+ font-family: aegean;
+}
+
+:lang("und-Arab") { /* ARABIC */
+ font-family: xbriyaz;
+}
+:lang("und-Xsux") { /* CUNEIFORM */
+ font-family: akkadian;
+}
+
+
+
+
+/* Central Asian */
+:lang("bo"), :lang("bod"), /* TIBETAN */
+:lang("dz"), :lang("dzo") { /* Dzongkha */
+ font-family: jomolhari;
+}
+
+
+
+/* South Asian */
+:lang("as"), :lang("asm") { /* Assamese */
+ font-family: freeserif;
+}
+:lang("bn"), :lang("ben") { /* BENGALI; Bangla */
+ font-family: freeserif;
+}
+:lang("ks"), :lang("kas") { /* Kashmiri */
+ font-family: freeserif;
+}
+:lang("hi"), :lang("hin"), /* Hindi DEVANAGARI */
+:lang("bh"), :lang("bih"), /* Bihari (Bhojpuri, Magahi, and Maithili) */
+:lang("sa"), :lang("san") { /* Sanskrit */
+ font-family: freeserif;
+}
+:lang("gu"), :lang("guj") { /* Gujarati */
+ font-family: freeserif;
+}
+:lang("pa"), :lang("pan") { /* Panjabi, Punjabi GURMUKHI */
+ font-family: freeserif;
+}
+:lang("kn"), :lang("kan") { /* Kannada */
+ font-family: lohitkannada;
+}
+:lang("mr"), :lang("mar") { /* Marathi */
+ font-family: freeserif;
+}
+:lang("ml"), :lang("mal") { /* MALAYALAM */
+ font-family: freeserif;
+}
+:lang("ne"), :lang("nep") { /* Nepali */
+ font-family: freeserif;
+}
+:lang("or"), :lang("ori") { /* ORIYA */
+ font-family: freeserif;
+}
+:lang("si"), :lang("sin") { /* SINHALA */
+ font-family: kaputaunicode;
+}
+:lang("ta"), :lang("tam") { /* TAMIL */
+ font-family: freeserif;
+}
+:lang("te"), :lang("tel") { /* TELUGU */
+ font-family: pothana2000;
+}
+:lang("sd"), :lang("snd") { /* Sindhi */
+ font-family: lateef;
+}
+:lang("sd-IN") { /* Sindhi */
+ font-family: freeserif;
+}
+:lang("sd-PK") { /* Sindhi */
+ font-family: lateef;
+}
+
+:lang("lif") { /* LIMBU */
+ font-family: sun-exta;
+}
+:lang("syl") { /* SYLOTI_NAGRI */
+ font-family: mph2bdamase;
+}
+:lang("dv"), :lang("div") { /* Divehi; Maldivian THAANA */
+ font-family: freeserif;
+}
+:lang("und-Khar") { /* KHAROSHTHI */
+ font-family: mph2bdamase;
+}
+:lang("und-Mtei") { /* MEETEI_MAYEK */
+ font-family: eeyekunicode;
+}
+
+
+
+
+/* South East Asian */
+:lang("km"), :lang("khm") { /* KHMER */
+ font-family: khmeros;
+}
+:lang("lo"), :lang("lao") { /* LAO */
+ font-family: dhyana;
+}
+:lang("my"), :lang("mya") { /* MYANMAR Burmese */
+ font-family: tharlon; /* zawgyi-one is non-unicode compliant but in wide usage ; ayar is also not strictly compliant */
+}
+:lang("th"), :lang("tha") { /* THAI */
+ font-family: garuda;
+}
+
+
+:lang("vi"), :lang("vie") { /* Vietnamese */
+ font-family: dejavusanscondensed;
+}
+
+
+:lang("bug") { /* BUGINESE */
+ font-family: freeserif;
+}
+:lang("su") { /* SUNDANESE */
+ font-family: sundaneseunicode;
+}
+:lang("tdd") { /* TAI_LE */
+ font-family: tharlon;
+}
+:lang("blt") { /* TAI_VIET */
+ font-family: taiheritagepro;
+}
+:lang("und-Kali") { /* KAYAH_LI */
+ font-family: freemono;
+}
+:lang("und-Lana") { /* TAI_THAM */
+ font-family: lannaalif;
+}
+:lang("und-Talu") { /* NEW_TAI_LUE */
+ font-family: daibannasilbook;
+}
+
+
+
+/* Phillipine */
+:lang("bku") { /* BUHID */
+ font-family: quivira;
+}
+:lang("hnn") { /* HANUNOO */
+ font-family: quivira;
+}
+:lang("tl") { /* TAGALOG */
+ font-family: quivira;
+}
+:lang("tbw") { /* TAGBANWA */
+ font-family: quivira;
+}
+
+
+
+
+/* East Asian */
+:lang("zh"), :lang("zho") { /* Chinese */
+ font-family: sun-exta, gb;
+}
+:lang("zh-HK") { /* Hong Kong */
+ font-family: sun-exta, big5;
+}
+:lang("zh-TW") { /* Taiwan */
+ font-family: sun-exta, big5;
+}
+:lang("zh-CN") { /* Chinese */
+ font-family: sun-exta, gb;
+}
+:lang("ko"), :lang("kor") { /* HANGUL Korean */
+ font-family: unbatang, uhc;
+}
+:lang("ja"), :lang("jpn") { /* Japanese HIRAGANA KATAKANA */
+ font-family: sun-exta, sjis;
+}
+:lang("lis") { /* LISU */
+ font-family: quivira;
+}
+:lang("und-Hans") { /* HAN (SIMPLIFIED) */
+ font-family: sun-exta, gb;
+}
+:lang("und-Bopo") { /* BOPOMOFO */
+ font-family: sun-exta;
+}
+:lang("ii"), :lang("iii"), /* Nuosu; Yi */
+:lang("und-Yiii") { /* YI */
+ font-family: sun-exta;
+}
+
+
+
+/* American */
+:lang("chr") { /* CHEROKEE */
+ font-family: aboriginalsans;
+}
+:lang("oj"), :lang("oji"), /* Ojibwe; Chippewa */
+:lang("iu"), :lang("iku"), /* Inuktitut */
+:lang("cr"), :lang("cre") { /* Cree CANADIAN_ABORIGINAL */
+ font-family: aboriginalsans;
+}
+:lang("und-Dsrt") { /* DESERET */
+ font-family: mph2bdamase;
+}
+
+
+
+
+/* Other */
+:lang("und-Brai") { /* BRAILLE */
+ font-family: dejavusans;
+}
diff --git a/mpdf/mpdf.css b/mpdf/mpdf.css
new file mode 100644
index 0000000..c7422f3
--- /dev/null
+++ b/mpdf/mpdf.css
@@ -0,0 +1,83 @@
+
+
+
+/* LISTS */
+
+/*
+A default margin-top/bottom for lists is NOT set in config.php - (standard browsers give outermost list a top and bottom margin).
+[mPDF default CSS set in config.php only works on basic elements, cannot do selectors such as "ol ol"]
+Need to add the following to do this, but also prevent margins in nested lists as per default HTML in most browsers:
+*/
+
+ul, ol { margin-top: 0.83em; margin-bottom: 0.83em; }
+ul ul, ul ol, ol ul, ol ol { margin-top: 0; margin-bottom: 0; }
+
+
+
+
+/* INDEXES */
+div.mpdf_index_main {
+ font-family: sans-serif;
+ line-height: normal;
+}
+div.mpdf_index_entry {
+ line-height: normal;
+ text-indent: -1.5em;
+}
+div.mpdf_index_letter {
+ font-family: sans-serif;
+ font-size: 1.8em;
+ font-weight: bold;
+ line-height: normal;
+ text-transform: uppercase;
+ page-break-after: avoid;
+ margin-top: 0.3em;
+ margin-collapse: collapse;
+}
+a.mpdf_index_link {
+ color: #000000;
+ text-decoration: none;
+}
+
+
+
+/* TABLE OF CONTENTS */
+div.mpdf_toc {
+ font-family: sans-serif;
+ line-height: normal;
+}
+a.mpdf_toc_a {
+ text-decoration: none;
+ color: black;
+}
+div.mpdf_toc_level_0 { /* Whole line level 0 */
+ line-height: 1.5;
+ margin-left: 0;
+ padding-right: 0em; /* should match the outdent specified for ToC; 0 is default; suggested value 2em */
+}
+span.mpdf_toc_t_level_0 { /* Title level 0 - may be inside */
+ font-weight: bold;
+}
+span.mpdf_toc_p_level_0 { /* Page no. level 0 - may be inside */
+}
+div.mpdf_toc_level_1 { /* Whole line level 1 */
+ margin-left: 2em;
+ text-indent: -2em;
+ padding-right: 0em; /* should match the outdent specified for ToC; 0 is default; suggested value 2em */
+}
+span.mpdf_toc_t_level_1 { /* Title level 1 */
+ font-style: italic;
+ font-weight: bold;
+}
+span.mpdf_toc_p_level_1 { /* Page no. level 1 - may be inside */
+}
+div.mpdf_toc_level_2 { /* Whole line level 2 */
+ margin-left: 4em;
+ text-indent: -2em;
+ padding-right: 0em; /* should match the outdent specified for ToC; 0 is default; suggested value 2em */
+}
+span.mpdf_toc_t_level_2 { /* Title level 2 */
+}
+span.mpdf_toc_p_level_2 { /* Page no. level 2 - may be inside */
+}
+
diff --git a/mpdf/mpdf.php b/mpdf/mpdf.php
new file mode 100644
index 0000000..7e15831
--- /dev/null
+++ b/mpdf/mpdf.php
@@ -0,0 +1,32752 @@
+ *
+// License: GPL *
+// *
+// Changes: See changelog.txt *
+// ******************************************************************************
+
+
+define('mPDF_VERSION','6.0');
+
+//Scale factor
+define('_MPDFK', (72/25.4));
+
+
+// Specify which font metrics to use:
+// 'winTypo' uses sTypoAscender etc from the OS/2 table and is the one usually recommended - BUT
+// 'win' use WinAscent etc from OS/2 and inpractice seems to be used more commonly in Windows environment
+// 'mac' uses Ascender etc from hhea table, and is used on Mac/OSX environment
+if (!defined('_FONT_DESCRIPTOR')) define("_FONT_DESCRIPTOR", 'win'); // Values: '' [BLANK] or 'win', 'mac', 'winTypo'
+
+
+/*-- HTML-CSS --*/
+
+define('_BORDER_ALL',15);
+define('_BORDER_TOP',8);
+define('_BORDER_RIGHT',4);
+define('_BORDER_BOTTOM',2);
+define('_BORDER_LEFT',1);
+/*-- END HTML-CSS --*/
+
+// mPDF 6.0
+// Used for $textvars - user settings via CSS
+define('FD_UNDERLINE',1); // font-decoration
+define('FD_LINETHROUGH',2);
+define('FD_OVERLINE',4);
+define('FA_SUPERSCRIPT',8); // font-(vertical)-align
+define('FA_SUBSCRIPT',16);
+define('FT_UPPERCASE',32); // font-transform
+define('FT_LOWERCASE',64);
+define('FT_CAPITALIZE',128);
+define('FC_KERNING',256); // font-(other)-controls
+define('FC_SMALLCAPS',512);
+
+
+if (!defined('_MPDF_PATH')) define('_MPDF_PATH', dirname(preg_replace('/\\\\/','/',__FILE__)) . '/');
+if (!defined('_MPDF_URI')) define('_MPDF_URI',_MPDF_PATH);
+
+require_once(_MPDF_PATH.'includes/functions.php');
+require_once(_MPDF_PATH.'config_lang2fonts.php');
+
+require_once(_MPDF_PATH.'classes/ucdn.php'); // mPDF 6.0
+
+/*-- OTL --*/
+require_once(_MPDF_PATH.'classes/indic.php'); // mPDF 6.0
+require_once(_MPDF_PATH.'classes/myanmar.php'); // mPDF 6.0
+require_once(_MPDF_PATH.'classes/sea.php'); // mPDF 6.0
+/*-- END OTL --*/
+
+
+if (!defined('_JPGRAPH_PATH')) define("_JPGRAPH_PATH", _MPDF_PATH.'jpgraph/');
+
+if (!defined('_MPDF_TEMP_PATH')) define("_MPDF_TEMP_PATH", _MPDF_PATH.'tmp/');
+
+if (!defined('_MPDF_TTFONTPATH')) { define('_MPDF_TTFONTPATH',_MPDF_PATH.'ttfonts/'); }
+if (!defined('_MPDF_TTFONTDATAPATH')) { define('_MPDF_TTFONTDATAPATH',_MPDF_PATH.'ttfontdata/'); }
+
+$errorlevel=error_reporting();
+$errorlevel=error_reporting($errorlevel & ~E_NOTICE);
+
+//error_reporting(E_ALL);
+
+if(function_exists("date_default_timezone_set")) {
+ if (ini_get("date.timezone")=="") { date_default_timezone_set("Europe/London"); }
+}
+if (!function_exists("mb_strlen")) { die("Error - mPDF requires mb_string functions. Ensure that PHP is compiled with php_mbstring.dll enabled."); }
+
+if (!defined('PHP_VERSION_ID')) {
+ $version = explode('.', PHP_VERSION);
+ define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
+}
+
+class mPDF
+{
+
+///////////////////////////////
+// EXTERNAL (PUBLIC) VARIABLES
+// Define these in config.php
+///////////////////////////////
+var $useFixedNormalLineHeight; // mPDF 6
+var $useFixedTextBaseline; // mPDF 6
+var $adjustFontDescLineheight; // mPDF 6
+var $interpolateImages; // mPDF 6
+var $defaultPagebreakType; // mPDF 6 pagebreaktype
+
+var $indexUseSubentries; // mPDF 6
+
+var $autoScriptToLang; // mPDF 6
+var $baseScript; // mPDF 6
+var $autoVietnamese; // mPDF 6
+var $autoArabic; // mPDF 6
+
+var $CJKforceend;
+var $h2bookmarks;
+var $h2toc;
+var $decimal_align;
+var $margBuffer;
+var $splitTableBorderWidth;
+
+var $bookmarkStyles;
+var $useActiveForms;
+
+var $repackageTTF;
+var $allowCJKorphans;
+var $allowCJKoverflow;
+
+var $useKerning;
+var $restrictColorSpace;
+var $bleedMargin;
+var $crossMarkMargin;
+var $cropMarkMargin;
+var $cropMarkLength;
+var $nonPrintMargin;
+
+var $PDFX;
+var $PDFXauto;
+
+var $PDFA;
+var $PDFAauto;
+var $ICCProfile;
+
+var $printers_info;
+var $iterationCounter;
+var $smCapsScale;
+var $smCapsStretch;
+
+var $backupSubsFont;
+var $backupSIPFont;
+var $debugfonts;
+var $useAdobeCJK;
+var $percentSubset;
+var $maxTTFFilesize;
+var $BMPonly;
+
+var $tableMinSizePriority;
+
+var $dpi;
+var $watermarkImgAlphaBlend;
+var $watermarkImgBehind;
+var $justifyB4br;
+var $packTableData;
+var $pgsIns;
+var $simpleTables;
+var $enableImports;
+
+var $debug;
+var $showStats;
+var $setAutoTopMargin;
+var $setAutoBottomMargin;
+var $autoMarginPadding;
+var $collapseBlockMargins;
+var $falseBoldWeight;
+var $normalLineheight;
+var $progressBar;
+var $incrementFPR1;
+var $incrementFPR2;
+var $incrementFPR3;
+var $incrementFPR4;
+
+var $SHYlang;
+var $SHYleftmin;
+var $SHYrightmin;
+var $SHYcharmin;
+var $SHYcharmax;
+var $SHYlanguages;
+// PageNumber Conditional Text
+var $pagenumPrefix;
+var $pagenumSuffix;
+var $nbpgPrefix;
+var $nbpgSuffix;
+var $showImageErrors;
+var $allow_output_buffering;
+var $autoPadding;
+var $useGraphs;
+var $tabSpaces;
+var $autoLangToFont;
+var $watermarkTextAlpha;
+var $watermarkImageAlpha;
+var $watermark_size;
+var $watermark_pos;
+var $annotSize;
+var $annotMargin;
+var $annotOpacity;
+var $title2annots;
+var $keepColumns;
+var $keep_table_proportions;
+var $ignore_table_widths;
+var $ignore_table_percents;
+var $list_number_suffix;
+var $list_auto_mode; // mPDF 6
+var $list_indent_first_level; // mPDF 6
+var $list_indent_default; // mPDF 6
+var $list_marker_offset; // mPDF 6
+var $useSubstitutions;
+var $CSSselectMedia;
+
+var $forcePortraitHeaders;
+var $forcePortraitMargins;
+var $displayDefaultOrientation;
+var $ignore_invalid_utf8;
+var $allowedCSStags;
+var $onlyCoreFonts;
+var $allow_charset_conversion;
+
+var $jSWord;
+var $jSmaxChar;
+var $jSmaxCharLast;
+var $jSmaxWordLast;
+
+var $max_colH_correction;
+
+
+var $table_error_report;
+var $table_error_report_param;
+var $biDirectional;
+var $text_input_as_HTML;
+var $anchor2Bookmark;
+var $shrink_tables_to_fit;
+
+var $allow_html_optional_endtags;
+
+var $img_dpi;
+
+var $defaultheaderfontsize;
+var $defaultheaderfontstyle;
+var $defaultheaderline;
+var $defaultfooterfontsize;
+var $defaultfooterfontstyle;
+var $defaultfooterline;
+var $header_line_spacing;
+var $footer_line_spacing;
+
+var $pregCJKchars;
+var $pregRTLchars;
+var $pregCURSchars; // mPDF 6
+
+var $mirrorMargins;
+var $watermarkText;
+var $watermarkImage;
+var $showWatermarkText;
+var $showWatermarkImage;
+
+var $fontsizes;
+
+var $defaultPageNumStyle; // mPDF 6
+
+//////////////////////
+// CLASS OBJECTS
+//////////////////////
+var $otl; // mPDF 5.7.1
+var $cssmgr;
+var $grad;
+var $bmp;
+var $wmf;
+var $tocontents;
+var $mpdfform;
+var $directw;
+
+//////////////////////
+// INTERNAL VARIABLES
+//////////////////////
+var $script2lang;
+var $viet;
+var $pashto;
+var $urdu;
+var $persian;
+var $sindhi;
+
+var $extrapagebreak; // mPDF 6 pagebreaktype
+var $uniqstr; // mPDF 5.7.2
+var $hasOC;
+
+var $textvar; // mPDF 5.7.1
+var $fontLanguageOverride; // mPDF 5.7.1
+var $OTLtags; // mPDF 5.7.1
+var $OTLdata; // mPDF 5.7.1
+var $writingToC;
+var $layers;
+var $current_layer;
+var $open_layer_pane;
+var $decimal_offset;
+var $inMeter;
+
+var $CJKleading;
+var $CJKfollowing;
+var $CJKoverflow;
+
+var $textshadow;
+
+var $colsums;
+var $spanborder;
+var $spanborddet;
+
+var $visibility;
+
+var $useRC128encryption;
+var $uniqid;
+
+var $kerning;
+var $fixedlSpacing;
+var $minwSpacing;
+var $lSpacingCSS;
+var $wSpacingCSS;
+
+var $spotColorIDs;
+var $SVGcolors;
+var $spotColors;
+var $defTextColor;
+var $defDrawColor;
+var $defFillColor;
+
+var $tableBackgrounds;
+var $inlineDisplayOff;
+var $kt_y00;
+var $kt_p00;
+var $upperCase;
+var $checkSIP;
+var $checkSMP;
+var $checkCJK;
+
+var $watermarkImgAlpha;
+var $PDFAXwarnings;
+var $MetadataRoot;
+var $OutputIntentRoot;
+var $InfoRoot;
+var $current_filename;
+var $parsers;
+var $current_parser;
+var $_obj_stack;
+var $_don_obj_stack;
+var $_current_obj_id;
+var $tpls;
+var $tpl;
+var $tplprefix;
+var $_res;
+
+var $pdf_version;
+var $noImageFile;
+var $lastblockbottommargin;
+var $baselineC;
+// mPDF 5.7.3 inline text-decoration parameters
+var $baselineSup;
+var $baselineSub;
+var $baselineS;
+var $subPos;
+var $subArrMB;
+var $ReqFontStyle;
+var $tableClipPath ;
+
+var $fullImageHeight;
+var $inFixedPosBlock; // Internal flag for position:fixed block
+var $fixedPosBlock; // Buffer string for position:fixed block
+var $fixedPosBlockDepth;
+var $fixedPosBlockBBox;
+var $fixedPosBlockSave;
+var $maxPosL;
+var $maxPosR;
+
+var $loaded;
+
+var $extraFontSubsets;
+var $docTemplateStart; // Internal flag for page (page no. -1) that docTemplate starts on
+var $time0;
+
+// Classes
+var $indic;
+var $barcode;
+
+var $SHYpatterns;
+var $loadedSHYpatterns;
+var $loadedSHYdictionary;
+var $SHYdictionary;
+var $SHYdictionaryWords;
+
+var $spanbgcolorarray;
+var $default_font;
+var $headerbuffer;
+var $lastblocklevelchange;
+var $nestedtablejustfinished;
+var $linebreakjustfinished;
+var $cell_border_dominance_L;
+var $cell_border_dominance_R;
+var $cell_border_dominance_T;
+var $cell_border_dominance_B;
+var $table_keep_together;
+var $plainCell_properties;
+var $shrin_k1;
+var $outerfilled;
+
+var $blockContext;
+var $floatDivs;
+
+
+var $patterns;
+var $pageBackgrounds;
+
+var $bodyBackgroundGradient;
+var $bodyBackgroundImage;
+var $bodyBackgroundColor;
+
+var $writingHTMLheader; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
+var $writingHTMLfooter;
+var $angle;
+
+var $gradients;
+
+var $kwt_Reference;
+var $kwt_BMoutlines;
+var $kwt_toc;
+
+var $tbrot_BMoutlines;
+var $tbrot_toc;
+
+var $col_BMoutlines;
+var $col_toc;
+
+var $currentGraphId;
+var $graphs;
+
+var $floatbuffer;
+var $floatmargins;
+
+var $bullet;
+var $bulletarray;
+
+
+var $currentLang;
+var $default_lang;
+var $default_available_fonts;
+var $pageTemplate;
+var $docTemplate;
+var $docTemplateContinue;
+
+var $arabGlyphs;
+var $arabHex;
+var $persianGlyphs;
+var $persianHex;
+var $arabVowels;
+var $arabPrevLink;
+var $arabNextLink;
+
+
+var $formobjects; // array of Form Objects for WMF
+var $InlineProperties;
+var $InlineAnnots;
+var $InlineBDF; // mPDF 6 Bidirectional formatting
+var $InlineBDFctr; // mPDF 6
+var $ktAnnots;
+var $tbrot_Annots;
+var $kwt_Annots;
+var $columnAnnots;
+var $columnForms;
+
+var $PageAnnots;
+
+var $pageDim; // Keep track of page wxh for orientation changes - set in _beginpage, used in _putannots
+
+var $breakpoints;
+
+var $tableLevel;
+var $tbctr;
+var $innermostTableLevel;
+var $saveTableCounter;
+var $cellBorderBuffer;
+
+var $saveHTMLFooter_height;
+var $saveHTMLFooterE_height;
+
+var $firstPageBoxHeader;
+var $firstPageBoxHeaderEven;
+var $firstPageBoxFooter;
+var $firstPageBoxFooterEven;
+
+var $page_box;
+var $show_marks; // crop or cross marks
+
+var $basepathIsLocal;
+
+var $use_kwt;
+var $kwt;
+var $kwt_height;
+var $kwt_y0;
+var $kwt_x0;
+var $kwt_buffer;
+var $kwt_Links;
+var $kwt_moved;
+var $kwt_saved;
+
+var $PageNumSubstitutions;
+
+var $table_borders_separate;
+var $base_table_properties;
+var $borderstyles;
+
+var $blockjustfinished;
+
+var $orig_bMargin;
+var $orig_tMargin;
+var $orig_lMargin;
+var $orig_rMargin;
+var $orig_hMargin;
+var $orig_fMargin;
+
+var $pageHTMLheaders;
+var $pageHTMLfooters;
+
+var $saveHTMLHeader;
+var $saveHTMLFooter;
+
+var $HTMLheaderPageLinks;
+var $HTMLheaderPageAnnots;
+var $HTMLheaderPageForms;
+
+// See config_fonts.php for these next 5 values
+var $available_unifonts;
+var $sans_fonts;
+var $serif_fonts;
+var $mono_fonts;
+var $defaultSubsFont;
+
+// List of ALL available CJK fonts (incl. styles) (Adobe add-ons) hw removed
+var $available_CJK_fonts;
+
+var $HTMLHeader;
+var $HTMLFooter;
+var $HTMLHeaderE;
+var $HTMLFooterE;
+var $bufferoutput;
+
+
+// CJK fonts
+var $Big5_widths;
+var $GB_widths;
+var $SJIS_widths;
+var $UHC_widths;
+
+// SetProtection
+var $encrypted; //whether document is protected
+var $Uvalue; //U entry in pdf document
+var $Ovalue; //O entry in pdf document
+var $Pvalue; //P entry in pdf document
+var $enc_obj_id; //encryption object id
+var $last_rc4_key; //last RC4 key encrypted (cached for optimisation)
+var $last_rc4_key_c; //last RC4 computed key
+var $encryption_key;
+var $padding; //used for encryption
+
+
+// Bookmark
+var $BMoutlines;
+var $OutlineRoot;
+// INDEX
+var $ColActive;
+var $Reference;
+var $CurrCol;
+var $NbCol;
+var $y0; //Top ordinate of columns
+var $ColL;
+var $ColWidth;
+var $ColGap;
+// COLUMNS
+var $ColR;
+var $ChangeColumn;
+var $columnbuffer;
+var $ColDetails;
+var $columnLinks;
+var $colvAlign;
+// Substitutions
+var $substitute; // Array of substitution strings e.g. 112
+var $entsearch; // Array of HTML entities (>ASCII 127) to substitute
+var $entsubstitute; // Array of substitution decimal unicode for the Hi entities
+
+
+// Default values if no style sheet offered (cf. http://www.w3.org/TR/CSS21/sample.html)
+var $defaultCSS;
+
+var $lastoptionaltag; // Save current block item which HTML specifies optionsl endtag
+var $pageoutput;
+var $charset_in;
+var $blk;
+var $blklvl;
+var $ColumnAdjust;
+var $ws; // Word spacing
+var $HREF;
+var $pgwidth;
+var $fontlist;
+var $oldx;
+var $oldy;
+var $B;
+var $I;
+
+var $tdbegin;
+var $table;
+var $cell;
+var $col;
+var $row;
+
+var $divbegin;
+var $divwidth;
+var $divheight;
+var $spanbgcolor;
+
+// mPDF 6 Used for table cell (block-type) properties
+var $cellTextAlign;
+var $cellLineHeight;
+var $cellLineStackingStrategy;
+var $cellLineStackingShift;
+
+// mPDF 6 Lists
+var $listcounter;
+var $listlvl;
+var $listtype;
+var $listitem;
+
+var $pjustfinished;
+var $ignorefollowingspaces;
+var $SMALL;
+var $BIG;
+var $dash_on;
+var $dotted_on;
+
+var $textbuffer;
+var $currentfontstyle;
+var $currentfontfamily;
+var $currentfontsize;
+var $colorarray;
+var $bgcolorarray;
+var $internallink;
+var $enabledtags;
+
+var $lineheight;
+var $basepath;
+var $textparam;
+
+var $specialcontent;
+var $selectoption;
+var $objectbuffer;
+
+// Table Rotation
+var $table_rotate;
+var $tbrot_maxw;
+var $tbrot_maxh;
+var $tablebuffer;
+var $tbrot_align;
+var $tbrot_Links;
+
+var $keep_block_together; // Keep a Block from page-break-inside: avoid
+
+var $tbrot_y0;
+var $tbrot_x0;
+var $tbrot_w;
+var $tbrot_h;
+
+var $mb_enc;
+var $directionality;
+
+var $extgstates; // Used for alpha channel - Transparency (Watermark)
+var $mgl;
+var $mgt;
+var $mgr;
+var $mgb;
+
+var $tts;
+var $ttz;
+var $tta;
+
+// Best to alter the below variables using default stylesheet above
+var $page_break_after_avoid;
+var $margin_bottom_collapse;
+var $default_font_size; // in pts
+var $original_default_font_size; // used to save default sizes when using table default
+var $original_default_font;
+var $watermark_font;
+var $defaultAlign;
+
+// TABLE
+var $defaultTableAlign;
+var $tablethead;
+var $thead_font_weight;
+var $thead_font_style;
+var $thead_font_smCaps;
+var $thead_valign_default;
+var $thead_textalign_default;
+var $tabletfoot;
+var $tfoot_font_weight;
+var $tfoot_font_style;
+var $tfoot_font_smCaps;
+var $tfoot_valign_default;
+var $tfoot_textalign_default;
+
+var $trow_text_rotate;
+
+var $cellPaddingL;
+var $cellPaddingR;
+var $cellPaddingT;
+var $cellPaddingB;
+var $table_border_attr_set;
+var $table_border_css_set;
+
+var $shrin_k; // factor with which to shrink tables - used internally - do not change
+var $shrink_this_table_to_fit; // 0 or false to disable; value (if set) gives maximum factor to reduce fontsize
+var $MarginCorrection; // corrects for OddEven Margins
+var $margin_footer;
+var $margin_header;
+
+var $tabletheadjustfinished;
+var $usingCoreFont;
+var $charspacing;
+
+//Private properties FROM FPDF
+var $DisplayPreferences;
+var $flowingBlockAttr;
+var $page; //current page number
+var $n; //current object number
+var $offsets; //array of object offsets
+var $buffer; //buffer holding in-memory PDF
+var $pages; //array containing pages
+var $state; //current document state
+var $compress; //compression flag
+var $DefOrientation; //default orientation
+var $CurOrientation; //current orientation
+var $OrientationChanges; //array indicating orientation changes
+var $k; //scale factor (number of points in user unit)
+var $fwPt;
+var $fhPt; //dimensions of page format in points
+var $fw;
+var $fh; //dimensions of page format in user unit
+var $wPt;
+var $hPt; //current dimensions of page in points
+var $w;
+var $h; //current dimensions of page in user unit
+var $lMargin; //left margin
+var $tMargin; //top margin
+var $rMargin; //right margin
+var $bMargin; //page break margin
+var $cMarginL; //cell margin Left
+var $cMarginR; //cell margin Right
+var $cMarginT; //cell margin Left
+var $cMarginB; //cell margin Right
+var $DeflMargin; //Default left margin
+var $DefrMargin; //Default right margin
+var $x;
+var $y; //current position in user unit for cell positioning
+var $lasth; //height of last cell printed
+var $LineWidth; //line width in user unit
+var $CoreFonts; //array of standard font names
+var $fonts; //array of used fonts
+var $FontFiles; //array of font files
+var $images; //array of used images
+var $PageLinks; //array of links in pages
+var $links; //array of internal links
+var $FontFamily; //current font family
+var $FontStyle; //current font style
+var $CurrentFont; //current font info
+var $FontSizePt; //current font size in points
+var $FontSize; //current font size in user unit
+var $DrawColor; //commands for drawing color
+var $FillColor; //commands for filling color
+var $TextColor; //commands for text color
+var $ColorFlag; //indicates whether fill and text colors are different
+var $autoPageBreak; //automatic page breaking
+var $PageBreakTrigger; //threshold used to trigger page breaks
+var $InFooter; //flag set when processing footer
+var $InHTMLFooter;
+
+var $processingFooter; //flag set when processing footer - added for columns
+var $processingHeader; //flag set when processing header - added for columns
+var $ZoomMode; //zoom display mode
+var $LayoutMode; //layout display mode
+var $title; //title
+var $subject; //subject
+var $author; //author
+var $keywords; //keywords
+var $creator; //creator
+
+var $aliasNbPg; //alias for total number of pages
+var $aliasNbPgGp; //alias for total number of pages in page group
+//var $aliasNbPgHex; // mPDF 6 deleted
+//var $aliasNbPgGpHex; // mPDF 6 deleted
+
+var $ispre;
+
+var $outerblocktags;
+var $innerblocktags;
+
+
+// **********************************
+// **********************************
+// **********************************
+// **********************************
+// **********************************
+// **********************************
+// **********************************
+// **********************************
+// **********************************
+
+function mPDF($mode='',$format='A4',$default_font_size=0,$default_font='',$mgl=15,$mgr=15,$mgt=16,$mgb=16,$mgh=9,$mgf=9, $orientation='P') {
+
+/*-- BACKGROUNDS --*/
+ if (!class_exists('grad', false)) { include(_MPDF_PATH.'classes/grad.php'); }
+ if (empty($this->grad)) { $this->grad = new grad($this); }
+/*-- END BACKGROUNDS --*/
+/*-- FORMS --*/
+ if (!class_exists('mpdfform', false)) { include(_MPDF_PATH.'classes/mpdfform.php'); }
+ if (empty($this->mpdfform)) { $this->mpdfform = new mpdfform($this); }
+/*-- END FORMS --*/
+
+ $this->time0 = microtime(true);
+ //Some checks
+ $this->_dochecks();
+
+ $this->writingToC = false;
+ $this->layers = array();
+ $this->current_layer = 0;
+ $this->open_layer_pane = false;
+
+ $this->visibility='visible';
+
+ //Initialization of properties
+ $this->spotColors=array();
+ $this->spotColorIDs = array();
+ $this->tableBackgrounds = array();
+ $this->uniqstr = '20110230'; // mPDF 5.7.2
+ $this->kt_y00 = '';
+ $this->kt_p00 = '';
+ $this->iterationCounter = false;
+ $this->BMPonly = array();
+ $this->page=0;
+ $this->n=2;
+ $this->buffer='';
+ $this->objectbuffer = array();
+ $this->pages=array();
+ $this->OrientationChanges=array();
+ $this->state=0;
+ $this->fonts=array();
+ $this->FontFiles=array();
+ $this->images=array();
+ $this->links=array();
+ $this->InFooter=false;
+ $this->processingFooter=false;
+ $this->processingHeader=false;
+ $this->lasth=0;
+ $this->FontFamily='';
+ $this->FontStyle='';
+ $this->FontSizePt=9;
+ $this->U=false;
+ // Small Caps
+ $this->upperCase = array();
+ $this->smCapsScale = 1;
+ $this->smCapsStretch = 100;
+ $this->margBuffer = 0;
+ $this->inMeter = false;
+ $this->decimal_offset = 0;
+
+ $this->defTextColor = $this->TextColor = $this->SetTColor($this->ConvertColor(0),true);
+ $this->defDrawColor = $this->DrawColor = $this->SetDColor($this->ConvertColor(0),true);
+ $this->defFillColor = $this->FillColor = $this->SetFColor($this->ConvertColor(255),true);
+
+ //SVG color names array
+ //http://www.w3schools.com/css/css_colornames.asp
+ $this->SVGcolors = 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');
+
+ // Uppercase alternatives (for Small Caps)
+ if (empty($this->upperCase)) { @include(_MPDF_PATH.'includes/upperCase.php'); }
+ $this->extrapagebreak = true; // mPDF 6 pagebreaktype
+
+ $this->ColorFlag=false;
+ $this->extgstates = array();
+
+ $this->mb_enc='windows-1252';
+ $this->directionality='ltr';
+ $this->defaultAlign = 'L';
+ $this->defaultTableAlign = 'L';
+
+ $this->fixedPosBlockSave = array();
+ $this->extraFontSubsets = 0;
+
+ $this->SHYpatterns = array();
+ $this->loadedSHYdictionary = false;
+ $this->SHYdictionary = array();
+ $this->SHYdictionaryWords = array();
+ $this->blockContext = 1;
+ $this->floatDivs = array();
+ $this->DisplayPreferences='';
+
+ $this->patterns = array(); // Tiling patterns used for backgrounds
+ $this->pageBackgrounds = array();
+ $this->writingHTMLheader = false; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
+ $this->writingHTMLfooter = false; // internal flag - used both for writing HTMLHeaders/Footers and FixedPos block
+ $this->gradients = array();
+
+ $this->kwt_Reference = array();
+ $this->kwt_BMoutlines = array();
+ $this->kwt_toc = array();
+
+ $this->tbrot_BMoutlines = array();
+ $this->tbrot_toc = array();
+
+ $this->col_BMoutlines = array();
+ $this->col_toc = array();
+ $this->graphs = array();
+
+ $this->pgsIns = array();
+ $this->PDFAXwarnings = array();
+ $this->inlineDisplayOff = false;
+ $this->lSpacingCSS = '';
+ $this->wSpacingCSS = '';
+ $this->fixedlSpacing = false;
+ $this->minwSpacing = 0;
+
+
+ $this->baselineC = 0.35; // Baseline for text
+ // mPDF 5.7.3 inline text-decoration parameters
+ $this->baselineSup = 0.5; // Sets default change in baseline for text as factor of preceeding fontsize
+ // 0.35 has been recommended; 0.5 matches applications like MS Word
+ $this->baselineSub = -0.2; // Sets default change in baseline for text as factor of preceeding fontsize
+ $this->baselineS = 0.3; // Sets default height for text as factor of fontsize
+ $this->baselineO = 1.1; // Sets default height for overline text as factor of fontsize
+
+ $this->noImageFile = str_replace("\\","/",dirname(__FILE__)) . '/includes/no_image.jpg';
+ $this->subPos = 0;
+ $this->normalLineheight = 1.3; // This should be overridden in config.php - but it is so important a default value is put here
+ // These are intended as configuration variables, and should be set in config.php - which will override these values;
+ // set here as failsafe as will cause an error if not defined
+ $this->incrementFPR1 = 10;
+ $this->incrementFPR2 = 10;
+ $this->incrementFPR3 = 10;
+ $this->incrementFPR4 = 10;
+
+ $this->fullImageHeight = false;
+ $this->floatbuffer = array();
+ $this->floatmargins = array();
+ $this->formobjects=array(); // array of Form Objects for WMF
+ $this->InlineProperties=array();
+ $this->InlineAnnots=array();
+ $this->InlineBDF=array(); // mPDF 6
+ $this->InlineBDFctr= 0; // mPDF 6
+ $this->tbrot_Annots=array();
+ $this->kwt_Annots=array();
+ $this->columnAnnots=array();
+ $this->pageDim=array();
+ $this->breakpoints = array(); // used in columnbuffer
+ $this->tableLevel=0;
+ $this->tbctr=array(); // counter for nested tables at each level
+ $this->page_box = array();
+ $this->show_marks = ''; // crop or cross marks
+ $this->kwt = false;
+ $this->kwt_height = 0;
+ $this->kwt_y0 = 0;
+ $this->kwt_x0 = 0;
+ $this->kwt_buffer = array();
+ $this->kwt_Links = array();
+ $this->kwt_moved = false;
+ $this->kwt_saved = false;
+ $this->PageNumSubstitutions = array();
+ $this->base_table_properties=array();
+ $this->borderstyles = array('inset','groove','outset','ridge','dotted','dashed','solid','double');
+ $this->tbrot_align = 'C';
+
+ $this->pageHTMLheaders=array();
+ $this->pageHTMLfooters=array();
+ $this->HTMLheaderPageLinks = array();
+ $this->HTMLheaderPageAnnots = array();
+
+ $this->HTMLheaderPageForms = array();
+ $this->columnForms = array();
+ $this->tbrotForms = array();
+ $this->useRC128encryption = false;
+ $this->uniqid = '';
+
+ $this->pageoutput = array();
+
+ $this->bufferoutput = false;
+ $this->encrypted=false; //whether document is protected
+ $this->BMoutlines=array();
+ $this->ColActive=0; //Flag indicating that columns are on (the index is being processed)
+ $this->Reference=array(); //Array containing the references
+ $this->CurrCol=0; //Current column number
+ $this->ColL = array(0); // Array of Left pos of columns - absolute - needs Margin correction for Odd-Even
+ $this->ColR = array(0); // Array of Right pos of columns - absolute pos - needs Margin correction for Odd-Even
+ $this->ChangeColumn = 0;
+ $this->columnbuffer = array();
+ $this->ColDetails = array(); // Keeps track of some column details
+ $this->columnLinks = array(); // Cross references PageLinks
+ $this->substitute = array(); // Array of substitution strings e.g. 112
+ $this->entsearch = array(); // Array of HTML entities (>ASCII 127) to substitute
+ $this->entsubstitute = array(); // Array of substitution decimal unicode for the Hi entities
+ $this->lastoptionaltag = '';
+ $this->charset_in = '';
+ $this->blk = array();
+ $this->blklvl = 0;
+ $this->tts = false;
+ $this->ttz = false;
+ $this->tta = false;
+ $this->ispre=false;
+
+ $this->checkSIP = false;
+ $this->checkSMP = false;
+ $this->checkCJK = false;
+
+ $this->page_break_after_avoid = false;
+ $this->margin_bottom_collapse = false;
+ $this->tablethead = 0;
+ $this->tabletfoot = 0;
+ $this->table_border_attr_set = 0;
+ $this->table_border_css_set = 0;
+ $this->shrin_k = 1.0;
+ $this->shrink_this_table_to_fit = 0;
+ $this->MarginCorrection = 0;
+
+ $this->tabletheadjustfinished = false;
+ $this->usingCoreFont = false;
+ $this->charspacing=0;
+
+ $this->autoPageBreak = true;
+
+ require(_MPDF_PATH.'config.php'); // config data
+
+ $this->_setPageSize($format, $orientation);
+ $this->DefOrientation=$orientation;
+
+ $this->margin_header=$mgh;
+ $this->margin_footer=$mgf;
+
+ $bmargin=$mgb;
+
+ $this->DeflMargin = $mgl;
+ $this->DefrMargin = $mgr;
+
+ $this->orig_tMargin = $mgt;
+ $this->orig_bMargin = $bmargin;
+ $this->orig_lMargin = $this->DeflMargin;
+ $this->orig_rMargin = $this->DefrMargin;
+ $this->orig_hMargin = $this->margin_header;
+ $this->orig_fMargin = $this->margin_footer;
+
+ if ($this->setAutoTopMargin=='pad') { $mgt += $this->margin_header; }
+ if ($this->setAutoBottomMargin=='pad') { $mgb += $this->margin_footer; }
+ $this->SetMargins($this->DeflMargin,$this->DefrMargin,$mgt); // sets l r t margin
+ //Automatic page break
+ $this->SetAutoPageBreak($this->autoPageBreak,$bmargin); // sets $this->bMargin & PageBreakTrigger
+
+ $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
+
+ //Interior cell margin (1 mm) ? not used
+ $this->cMarginL = 1;
+ $this->cMarginR = 1;
+ //Line width (0.2 mm)
+ $this->LineWidth=.567/_MPDFK;
+
+ //To make the function Footer() work - replaces {nb} with page number
+ $this->AliasNbPages();
+ $this->AliasNbPageGroups();
+
+ //$this->aliasNbPgHex = '{nbHEXmarker}'; // mPDF 6 deleted
+ //$this->aliasNbPgGpHex = '{nbpgHEXmarker}'; // mPDF 6 deleted
+
+ //Enable all tags as default
+ $this->DisableTags();
+ //Full width display mode
+ $this->SetDisplayMode(100); // fullwidth? 'fullpage'
+ //Compression
+ $this->SetCompression(true);
+ //Set default display preferences
+ $this->SetDisplayPreferences('');
+
+ // Font data
+ require(_MPDF_PATH.'config_fonts.php');
+ // Available fonts
+ $this->available_unifonts = array();
+ foreach ($this->fontdata AS $f => $fs) {
+ if (isset($fs['R']) && $fs['R']) { $this->available_unifonts[] = $f; }
+ if (isset($fs['B']) && $fs['B']) { $this->available_unifonts[] = $f.'B'; }
+ if (isset($fs['I']) && $fs['I']) { $this->available_unifonts[] = $f.'I'; }
+ if (isset($fs['BI']) && $fs['BI']) { $this->available_unifonts[] = $f.'BI'; }
+ }
+
+ $this->default_available_fonts = $this->available_unifonts;
+
+ $optcore = false;
+ $onlyCoreFonts = false;
+ if (preg_match('/([\-+])aCJK/i',$mode, $m)) {
+ $mode = preg_replace('/([\-+])aCJK/i','',$mode); // mPDF 6
+ if ($m[1]=='+') { $this->useAdobeCJK = true; }
+ else { $this->useAdobeCJK = false; }
+ }
+
+ if (strlen($mode)==1) {
+ if ($mode=='s') { $this->percentSubset = 100; $mode = ''; }
+ else if ($mode=='c') { $onlyCoreFonts = true; $mode = ''; }
+ }
+ else if (substr($mode,-2)=='-s') {
+ $this->percentSubset = 100;
+ $mode = substr($mode,0,strlen($mode)-2);
+ }
+ else if (substr($mode,-2)=='-c') {
+ $onlyCoreFonts = true;
+ $mode = substr($mode,0,strlen($mode)-2);
+ }
+ else if (substr($mode,-2)=='-x') {
+ $optcore = true;
+ $mode = substr($mode,0,strlen($mode)-2);
+ }
+
+ // Autodetect if mode is a language_country string (en-GB or en_GB or en)
+ if ($mode && $mode != 'UTF-8') { // mPDF 6
+ list ($coreSuitable,$mpdf_pdf_unifont) = GetLangOpts($mode, $this->useAdobeCJK, $this->fontdata);
+ if ($coreSuitable && $optcore) { $onlyCoreFonts = true; }
+ if ($mpdf_pdf_unifont) { // mPDF 6
+ $default_font = $mpdf_pdf_unifont;
+ }
+ $this->currentLang = $mode;
+ $this->default_lang = $mode;
+ }
+
+ $this->onlyCoreFonts = $onlyCoreFonts;
+
+ if ($this->onlyCoreFonts) {
+ $this->setMBencoding('windows-1252'); // sets $this->mb_enc
+ }
+ else {
+ $this->setMBencoding('UTF-8'); // sets $this->mb_enc
+ }
+ @mb_regex_encoding('UTF-8'); // required only for mb_ereg... and mb_split functions
+
+
+ // Adobe CJK fonts
+ $this->available_CJK_fonts = array('gb','big5','sjis','uhc','gbB','big5B','sjisB','uhcB','gbI','big5I','sjisI','uhcI',
+ 'gbBI','big5BI','sjisBI','uhcBI');
+
+
+ //Standard fonts
+ $this->CoreFonts=array('ccourier'=>'Courier','ccourierB'=>'Courier-Bold','ccourierI'=>'Courier-Oblique','ccourierBI'=>'Courier-BoldOblique',
+ 'chelvetica'=>'Helvetica','chelveticaB'=>'Helvetica-Bold','chelveticaI'=>'Helvetica-Oblique','chelveticaBI'=>'Helvetica-BoldOblique',
+ 'ctimes'=>'Times-Roman','ctimesB'=>'Times-Bold','ctimesI'=>'Times-Italic','ctimesBI'=>'Times-BoldItalic',
+ 'csymbol'=>'Symbol','czapfdingbats'=>'ZapfDingbats');
+ $this->fontlist=array("ctimes","ccourier","chelvetica","csymbol","czapfdingbats");
+
+ // Substitutions
+ $this->setHiEntitySubstitutions();
+
+ if ($this->onlyCoreFonts) {
+ $this->useSubstitutions = true;
+ $this->SetSubstitutions();
+ }
+ else { $this->useSubstitutions = false; }
+
+/*-- HTML-CSS --*/
+
+ if (!class_exists('cssmgr', false)) { include(_MPDF_PATH .'classes/cssmgr.php'); }
+ $this->cssmgr = new cssmgr($this);
+ // mPDF 6
+ if (file_exists(_MPDF_PATH.'mpdf.css')) {
+ $css = file_get_contents(_MPDF_PATH.'mpdf.css');
+ $this->cssmgr->ReadCSS('');
+ }
+/*-- END HTML-CSS --*/
+
+ if ($default_font=='') {
+ if ($this->onlyCoreFonts) {
+ if (in_array(strtolower($this->defaultCSS['BODY']['FONT-FAMILY']),$this->mono_fonts)) { $default_font = 'ccourier'; }
+ else if (in_array(strtolower($this->defaultCSS['BODY']['FONT-FAMILY']),$this->sans_fonts)) { $default_font = 'chelvetica'; }
+ else { $default_font = 'ctimes'; }
+ }
+ else { $default_font = $this->defaultCSS['BODY']['FONT-FAMILY']; }
+ }
+ if (!$default_font_size) {
+ $mmsize = $this->ConvertSize($this->defaultCSS['BODY']['FONT-SIZE']);
+ $default_font_size = $mmsize*(_MPDFK);
+ }
+
+ if ($default_font) { $this->SetDefaultFont($default_font); }
+ if ($default_font_size) { $this->SetDefaultFontSize($default_font_size); }
+
+ $this->SetLineHeight(); // lineheight is in mm
+
+ $this->SetFColor($this->ConvertColor(255));
+ $this->HREF='';
+ $this->oldy=-1;
+ $this->B=0;
+ $this->I=0;
+
+ // mPDF 6 Lists
+ $this->listlvl=0;
+ $this->listtype=array();
+ $this->listitem=array();
+ $this->listcounter=array();
+
+ $this->tdbegin=false;
+ $this->table=array();
+ $this->cell=array();
+ $this->col=-1;
+ $this->row=-1;
+ $this->cellBorderBuffer = array();
+
+ $this->divbegin=false;
+ // mPDF 6
+ $this->cellTextAlign='';
+ $this->cellLineHeight = '';
+ $this->cellLineStackingStrategy = '';
+ $this->cellLineStackingShift = '';
+
+ $this->divwidth=0;
+ $this->divheight=0;
+ $this->spanbgcolor=false;
+ $this->spanborder=false;
+ $this->spanborddet=array();
+
+ $this->blockjustfinished=false;
+ $this->ignorefollowingspaces = true; //in order to eliminate exceeding left-side spaces
+ $this->dash_on=false;
+ $this->dotted_on=false;
+ $this->textshadow='';
+
+ $this->currentfontfamily='';
+ $this->currentfontsize='';
+ $this->currentfontstyle='';
+ $this->colorarray=''; // mPDF 6
+ $this->spanbgcolorarray=''; // mPDF 6
+ $this->textbuffer=array();
+ $this->internallink=array();
+ $this->basepath = "";
+
+ $this->SetBasePath('');
+
+ $this->textparam = array();
+
+ $this->specialcontent = '';
+ $this->selectoption = array();
+
+/*-- IMPORTS --*/
+
+ $this->tpls = array();
+ $this->tpl = 0;
+ $this->tplprefix = "/TPL";
+ $this->res = array();
+ if ($this->enableImports) {
+ $this->SetImportUse();
+ }
+/*-- END IMPORTS --*/
+
+ if ($this->progressBar) { $this->StartProgressBarOutput($this->progressBar) ; } // *PROGRESS-BAR*
+}
+
+
+
+function _setPageSize($format, &$orientation) {
+ //Page format
+ if(is_string($format))
+ {
+ if ($format=='') { $format = 'A4'; }
+ $pfo = 'P';
+ if(preg_match('/([0-9a-zA-Z]*)-L/i',$format,$m)) { // e.g. A4-L = A4 landscape
+ $format=$m[1];
+ $pfo='L';
+ }
+ $format = $this->_getPageFormat($format);
+ if (!$format) { $this->Error('Unknown page format: '.$format); }
+ else { $orientation = $pfo; }
+
+ $this->fwPt=$format[0];
+ $this->fhPt=$format[1];
+ }
+ else
+ {
+ if (!$format[0] || !$format[1]) { $this->Error('Invalid page format: '.$format[0].' '.$format[1]); }
+ $this->fwPt=$format[0]*_MPDFK;
+ $this->fhPt=$format[1]*_MPDFK;
+ }
+ $this->fw=$this->fwPt/_MPDFK;
+ $this->fh=$this->fhPt/_MPDFK;
+ //Page orientation
+ $orientation=strtolower($orientation);
+ if($orientation=='p' or $orientation=='portrait')
+ {
+ $orientation='P';
+ $this->wPt=$this->fwPt;
+ $this->hPt=$this->fhPt;
+ }
+ elseif($orientation=='l' or $orientation=='landscape')
+ {
+ $orientation='L';
+ $this->wPt=$this->fhPt;
+ $this->hPt=$this->fwPt;
+ }
+ else $this->Error('Incorrect orientation: '.$orientation);
+ $this->CurOrientation=$orientation;
+
+ $this->w=$this->wPt/_MPDFK;
+ $this->h=$this->hPt/_MPDFK;
+}
+
+function _getPageFormat($format) {
+ switch (strtoupper($format)) {
+ case '4A0': {$format = array(4767.87,6740.79); break;}
+ case '2A0': {$format = array(3370.39,4767.87); break;}
+ case 'A0': {$format = array(2383.94,3370.39); break;}
+ case 'A1': {$format = array(1683.78,2383.94); break;}
+ case 'A2': {$format = array(1190.55,1683.78); break;}
+ case 'A3': {$format = array(841.89,1190.55); break;}
+ case 'A4': {$format = array(595.28,841.89); break;}
+ case 'A5': {$format = array(419.53,595.28); break;}
+ case 'A6': {$format = array(297.64,419.53); break;}
+ case 'A7': {$format = array(209.76,297.64); break;}
+ case 'A8': {$format = array(147.40,209.76); break;}
+ case 'A9': {$format = array(104.88,147.40); break;}
+ case 'A10': {$format = array(73.70,104.88); break;}
+ case 'B0': {$format = array(2834.65,4008.19); break;}
+ case 'B1': {$format = array(2004.09,2834.65); break;}
+ case 'B2': {$format = array(1417.32,2004.09); break;}
+ case 'B3': {$format = array(1000.63,1417.32); break;}
+ case 'B4': {$format = array(708.66,1000.63); break;}
+ case 'B5': {$format = array(498.90,708.66); break;}
+ case 'B6': {$format = array(354.33,498.90); break;}
+ case 'B7': {$format = array(249.45,354.33); break;}
+ case 'B8': {$format = array(175.75,249.45); break;}
+ case 'B9': {$format = array(124.72,175.75); break;}
+ case 'B10': {$format = array(87.87,124.72); break;}
+ case 'C0': {$format = array(2599.37,3676.54); break;}
+ case 'C1': {$format = array(1836.85,2599.37); break;}
+ case 'C2': {$format = array(1298.27,1836.85); break;}
+ case 'C3': {$format = array(918.43,1298.27); break;}
+ case 'C4': {$format = array(649.13,918.43); break;}
+ case 'C5': {$format = array(459.21,649.13); break;}
+ case 'C6': {$format = array(323.15,459.21); break;}
+ case 'C7': {$format = array(229.61,323.15); break;}
+ case 'C8': {$format = array(161.57,229.61); break;}
+ case 'C9': {$format = array(113.39,161.57); break;}
+ case 'C10': {$format = array(79.37,113.39); break;}
+ case 'RA0': {$format = array(2437.80,3458.27); break;}
+ case 'RA1': {$format = array(1729.13,2437.80); break;}
+ case 'RA2': {$format = array(1218.90,1729.13); break;}
+ case 'RA3': {$format = array(864.57,1218.90); break;}
+ case 'RA4': {$format = array(609.45,864.57); break;}
+ case 'SRA0': {$format = array(2551.18,3628.35); break;}
+ case 'SRA1': {$format = array(1814.17,2551.18); break;}
+ case 'SRA2': {$format = array(1275.59,1814.17); break;}
+ case 'SRA3': {$format = array(907.09,1275.59); break;}
+ case 'SRA4': {$format = array(637.80,907.09); break;}
+ case 'LETTER': {$format = array(612.00,792.00); break;}
+ case 'LEGAL': {$format = array(612.00,1008.00); break;}
+ case 'LEDGER': {$format = array(279.00,432.00); break;}
+ case 'TABLOID': {$format = array(279.00,432.00); break;}
+ case 'EXECUTIVE': {$format = array(521.86,756.00); break;}
+ case 'FOLIO': {$format = array(612.00,936.00); break;}
+ case 'B': {$format=array(362.83,561.26 ); break;} // 'B' format paperback size 128x198mm
+ case 'A': {$format=array(314.65,504.57 ); break;} // 'A' format paperback size 111x178mm
+ case 'DEMY': {$format=array(382.68,612.28 ); break;} // 'Demy' format paperback size 135x216mm
+ case 'ROYAL': {$format=array(433.70,663.30 ); break;} // 'Royal' format paperback size 153x234mm
+ default: {$format = array(595.28,841.89); break;}
+ }
+ return $format;
+}
+
+
+/*-- PROGRESS-BAR --*/
+function StartProgressBarOutput($mode=1) {
+ // must be relative path, or URI (not a file system path)
+ if (!defined('_MPDF_URI')) {
+ $this->progressBar = false;
+ if ($this->debug) { $this->Error("You need to define _MPDF_URI to use the progress bar!"); }
+ else return false;
+ }
+ $this->progressBar = $mode;
+ if ($this->progbar_altHTML) {
+ echo $this->progbar_altHTML;
+ }
+ else {
+ echo '
+
+ mPDF File Progress
+
+
+
+
+
+ '.$this->progbar_heading.'
+
+ ';
+ if ($this->progressBar==2) { echo '
+ Writing HTML code
+
+
+
+ |
+ Autosizing elements
+
+
+
+ Writing Tables
+
+
+ |
+
| |
+
+ '; }
+ echo ' Writing PDF file
+
+
+ ';
+ if ($this->progressBar==2) { echo '
+ |
+ Memory usage
+
+ 0 '.ini_get("memory_limit").'
+
+ Memory usage (peak)
+
+ 0 '.ini_get("memory_limit").'
+ |
+
+ '; }
+ echo '
+
+
+
+ ';
+ }
+ ob_flush();
+ flush();
+}
+
+function UpdateProgressBar($el,$val,$txt='') {
+ // $val should be a string - 5 = actual value, +15 = increment
+
+ if ($this->progressBar<2) {
+ if ($el>3) { return; }
+ else if ($el ==1) { $el = 2; }
+ }
+ echo ''."\n";
+ ob_flush();
+ flush();
+}
+/*-- END PROGRESS-BAR --*/
+
+
+
+function RestrictUnicodeFonts($res) {
+ // $res = array of (Unicode) fonts to restrict to: e.g. norasi|norasiB - language specific
+ if (count($res)) { // Leave full list of available fonts if passed blank array
+ $this->available_unifonts = $res;
+ }
+ else { $this->available_unifonts = $this->default_available_fonts; }
+ if (count($this->available_unifonts) == 0) { $this->available_unifonts[] = $this->default_available_fonts[0]; }
+ $this->available_unifonts = array_values($this->available_unifonts);
+}
+
+
+function setMBencoding($enc) {
+ if ($this->mb_enc != $enc) {
+ $this->mb_enc = $enc;
+ mb_internal_encoding($this->mb_enc);
+ }
+}
+
+
+function SetMargins($left,$right,$top) {
+ //Set left, top and right margins
+ $this->lMargin=$left;
+ $this->rMargin=$right;
+ $this->tMargin=$top;
+}
+
+function ResetMargins() {
+ //ReSet left, top margins
+ if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation=='P' && $this->CurOrientation=='L') {
+ if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
+ $this->tMargin=$this->orig_rMargin;
+ $this->bMargin=$this->orig_lMargin;
+ }
+ else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS
+ $this->tMargin=$this->orig_lMargin;
+ $this->bMargin=$this->orig_rMargin;
+ }
+ $this->lMargin=$this->DeflMargin;
+ $this->rMargin=$this->DefrMargin;
+ $this->MarginCorrection = 0;
+ $this->PageBreakTrigger=$this->h-$this->bMargin;
+ }
+ else if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
+ $this->lMargin=$this->DefrMargin;
+ $this->rMargin=$this->DeflMargin;
+ $this->MarginCorrection = $this->DefrMargin-$this->DeflMargin;
+
+ }
+ else { // ODD // OR NOT MIRRORING MARGINS/FOOTERS
+ $this->lMargin=$this->DeflMargin;
+ $this->rMargin=$this->DefrMargin;
+ if ($this->mirrorMargins) { $this->MarginCorrection = $this->DeflMargin-$this->DefrMargin; }
+ }
+ $this->x=$this->lMargin;
+
+}
+
+function SetLeftMargin($margin) {
+ //Set left margin
+ $this->lMargin=$margin;
+ if($this->page>0 and $this->x<$margin) $this->x=$margin;
+}
+
+function SetTopMargin($margin) {
+ //Set top margin
+ $this->tMargin=$margin;
+}
+
+function SetRightMargin($margin) {
+ //Set right margin
+ $this->rMargin=$margin;
+}
+
+function SetAutoPageBreak($auto,$margin=0) {
+ //Set auto page break mode and triggering margin
+ $this->autoPageBreak=$auto;
+ $this->bMargin=$margin;
+ $this->PageBreakTrigger=$this->h-$margin;
+}
+
+function SetDisplayMode($zoom,$layout='continuous') {
+ //Set display mode in viewer
+ if($zoom=='fullpage' or $zoom=='fullwidth' or $zoom=='real' or $zoom=='default' or !is_string($zoom))
+ $this->ZoomMode=$zoom;
+ else
+ $this->Error('Incorrect zoom display mode: '.$zoom);
+ if($layout=='single' or $layout=='continuous' or $layout=='two' or $layout=='twoleft' or $layout=='tworight' or $layout=='default')
+ $this->LayoutMode=$layout;
+ else
+ $this->Error('Incorrect layout display mode: '.$layout);
+}
+
+function SetCompression($compress) {
+ //Set page compression
+ if(function_exists('gzcompress')) $this->compress=$compress;
+ else $this->compress=false;
+}
+
+function SetTitle($title) {
+ //Title of document // Arrives as UTF-8
+ $this->title = $title;
+}
+
+function SetSubject($subject) {
+ //Subject of document
+ $this->subject= $subject;
+}
+
+function SetAuthor($author) {
+ //Author of document
+ $this->author= $author;
+}
+
+function SetKeywords($keywords) {
+ //Keywords of document
+ $this->keywords= $keywords;
+}
+
+function SetCreator($creator) {
+ //Creator of document
+ $this->creator= $creator;
+}
+
+
+function SetAnchor2Bookmark($x) {
+ $this->anchor2Bookmark = $x;
+}
+
+function AliasNbPages($alias='{nb}') {
+ //Define an alias for total number of pages
+ $this->aliasNbPg=$alias;
+}
+
+function AliasNbPageGroups($alias='{nbpg}') {
+ //Define an alias for total number of pages in a group
+ $this->aliasNbPgGp=$alias;
+}
+
+function SetAlpha($alpha, $bm='Normal', $return=false, $mode='B') {
+// alpha: real value from 0 (transparent) to 1 (opaque)
+// bm: blend mode, one of the following:
+// Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn,
+// HardLight, SoftLight, Difference, Exclusion, Hue, Saturation, Color, Luminosity
+// set alpha for stroking (CA) and non-stroking (ca) operations
+// mode determines F (fill) S (stroke) B (both)
+ if (($this->PDFA || $this->PDFX) && $alpha!=1) {
+ if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "Image opacity must be 100% (Opacity changed to 100%)"; }
+ $alpha = 1;
+ }
+ $a = array('BM'=>'/'.$bm);
+ if ($mode=='F' || $mode=='B') $a['ca'] = $alpha; // mPDF 5.7.2
+ if ($mode=='S' || $mode=='B') $a['CA'] = $alpha; // mPDF 5.7.2
+ $gs = $this->AddExtGState($a);
+ if ($return) { return sprintf('/GS%d gs', $gs); }
+ else { $this->_out(sprintf('/GS%d gs', $gs)); }
+}
+
+function AddExtGState($parms) {
+ $n = count($this->extgstates);
+ // check if graphics state already exists
+ for ($i=1; $i<=$n; $i++) {
+ if (count($this->extgstates[$i]['parms']) == count($parms)) {
+ $same = true;
+ foreach($this->extgstates[$i]['parms'] AS $k=>$v) {
+ if (!isset($parms[$k]) || $parms[$k] != $v) { $same = false; break; }
+ }
+ if ($same) { return $i; }
+ }
+ }
+ $n++;
+ $this->extgstates[$n]['parms'] = $parms;
+ return $n;
+}
+
+function SetVisibility($v) {
+ if (($this->PDFA || $this->PDFX) && $this->visibility!='visible') { $this->PDFAXwarnings[] = "Cannot set visibility to anything other than full when using PDFA or PDFX"; return ''; }
+ else if (!$this->PDFA && !$this->PDFX)
+ $this->pdf_version='1.5';
+ if($this->visibility!='visible') {
+ $this->_out('EMC');
+ $this->hasOC=intval($this->hasOC );
+ }
+ if($v=='printonly') {
+ $this->_out('/OC /OC1 BDC');
+ $this->hasOC=($this->hasOC | 1);
+ }
+ elseif($v=='screenonly') {
+ $this->_out('/OC /OC2 BDC');
+ $this->hasOC=($this->hasOC | 2);
+ }
+ elseif($v=='hidden') {
+ $this->_out('/OC /OC3 BDC');
+ $this->hasOC=($this->hasOC | 4);
+ }
+ elseif($v!='visible')
+ $this->Error('Incorrect visibility: '.$v);
+ $this->visibility=$v;
+}
+
+function Error($msg) {
+ //Fatal error
+ header('Content-Type: text/html; charset=utf-8');
+ die(' mPDF error: '.$msg);
+}
+
+function Open() {
+ //Begin document
+ if($this->state==0) {
+ // Was is function _begindoc()
+ // Start document
+ $this->state=1;
+ $this->_out('%PDF-'.$this->pdf_version);
+ $this->_out('%'.chr(226).chr(227).chr(207).chr(211)); // 4 chars > 128 to show binary file
+ }
+}
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// DEPRACATED but included for backwards compatability
+// Depracated - can use AddPage for all
+function AddPages($a='',$b='', $c='', $d='', $e='',$f='',$g='',$h='',$i='',$j='',$k='',$l='',$m='',$n='',$o='',$p=0,$q=0,$r=0,$s=0,$t='',$u='') {
+ $this->Error('function AddPages is depracated as of mPDF 6. Please use AddPage or HTML code methods instead.');
+}
+
+function startPageNums() { $this->Error('function startPageNums is depracated as of mPDF 6.'); }
+
+function setUnvalidatedText($a='', $b=-1) { $this->Error('function setUnvalidatedText is depracated as of mPDF 6. Please use SetWatermarkText instead.'); }
+
+function SetAutoFont($a) { $this->Error('function SetAutoFont is depracated as of mPDF 6. Please use autoScriptToLang instead. See config.php'); }
+
+function Reference($a) { $this->Error('function Reference is depracated as of mPDF 6. Please use IndexEntry instead.'); }
+
+function ReferenceSee($a,$b) { $this->Error('function ReferenceSee is depracated as of mPDF 6. Please use IndexEntrySee instead.'); }
+
+function CreateReference($a=1, $b='', $c='', $d=3, $e=1, $f='', $g=5, $h='',$i='', $j=false) { $this->Error('function CreateReference is depracated as of mPDF 6. Please use InsertIndex instead.'); }
+
+function CreateIndex($a=1, $b='', $c='', $d=3, $e=1, $f='', $g=5, $h='',$i='', $j=false) { $this->Error('function CreateIndex is depracated as of mPDF 6. Please use InsertIndex instead.'); }
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+function Close() {
+ // Check old Aliases - now depracated mPDF 6
+ if (isset($this->UnvalidatedText)) { $this->Error('$mpdf->UnvalidatedText is depracated as of mPDF 6. Please use $mpdf->watermarkText instead.'); }
+ if (isset($this->TopicIsUnvalidated)) { $this->Error('$mpdf->TopicIsUnvalidated is depracated as of mPDF 6. Please use $mpdf->showWatermarkText instead.'); }
+ if (isset($this->AliasNbPg)) { $this->Error('$mpdf->AliasNbPg is depracated as of mPDF 6. Please use $mpdf->aliasNbPg instead.'); }
+ if (isset($this->AliasNbPgGp)) { $this->Error('$mpdf->AliasNbPgGp is depracated as of mPDF 6. Please use $mpdf->aliasNbPgGp instead.'); }
+ if (isset($this->BiDirectional)) { $this->Error('$mpdf->BiDirectional is depracated as of mPDF 6. Please use $mpdf->biDirectional instead.'); }
+ if (isset($this->Anchor2Bookmark)) { $this->Error('$mpdf->Anchor2Bookmark is depracated as of mPDF 6. Please use $mpdf->anchor2Bookmark instead.'); }
+ if (isset($this->KeepColumns)) { $this->Error('$mpdf->KeepColumns is depracated as of mPDF 6. Please use $mpdf->keepColumns instead.'); }
+ if (isset($this->useOddEven)) { $this->Error('$mpdf->useOddEven is depracated as of mPDF 6. Please use $mpdf->mirrorMargins instead.'); }
+ if (isset($this->useSubstitutionsMB)) { $this->Error('$mpdf->useSubstitutionsMB is depracated as of mPDF 6. Please use $mpdf->useSubstitutions instead.'); }
+ if (isset($this->useLang)) { $this->Error('$mpdf->useLang is depracated as of mPDF 6. Please use $mpdf->autoLangToFont instead.'); }
+ if (isset($this->useAutoFont)) { $this->Error('$mpdf->useAutoFont is depracated. Please use $mpdf->autoScriptToLang instead.'); }
+
+ if ($this->progressBar) { $this->UpdateProgressBar(2,'2','Closing last page'); } // *PROGRESS-BAR*
+ //Terminate document
+ if($this->state==3) return;
+ if($this->page==0) $this->AddPage($this->CurOrientation);
+ if (count($this->cellBorderBuffer)) { $this->printcellbuffer(); } // *TABLES*
+ if ($this->tablebuffer) { $this->printtablebuffer(); } // *TABLES*
+/*-- COLUMNS --*/
+
+ if ($this->ColActive) {
+ $this->SetColumns(0);
+ $this->ColActive = 0;
+ if (count($this->columnbuffer)) { $this->printcolumnbuffer(); }
+ }
+/*-- END COLUMNS --*/
+
+ // BODY Backgrounds
+ $s = '';
+
+ $s .= $this->PrintBodyBackgrounds();
+
+ $s .= $this->PrintPageBackgrounds();
+ $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', "\n".$s."\n".'\\1', $this->pages[$this->page]);
+ $this->pageBackgrounds = array();
+
+ if($this->visibility!='visible')
+ $this->SetVisibility('visible');
+ $this->EndLayer();
+
+ if (!$this->tocontents || !$this->tocontents->TOCmark) { //Page footer
+ $this->InFooter=true;
+ $this->Footer();
+ $this->InFooter=false;
+ }
+ if ($this->tocontents && ($this->tocontents->TOCmark || count($this->tocontents->m_TOC))) { $this->tocontents->insertTOC(); } // *TOC*
+
+ //Close page
+ $this->_endpage();
+
+ //Close document
+ $this->_enddoc();
+}
+
+/*-- BACKGROUNDS --*/
+function _resizeBackgroundImage($imw, $imh, $cw, $ch, $resize=0, $repx, $repy, $pba=array(), $size=array()) {
+ // pba is background positioning area (from CSS background-origin) may not always be set [x,y,w,h]
+ // size is from CSS3 background-size - takes precendence over old resize
+ // $w - absolute length or % or auto or cover | contain
+ // $h - absolute length or % or auto or cover | contain
+ if (isset($pba['w'])) $cw = $pba['w'];
+ if (isset($pba['h'])) $ch = $pba['h'];
+
+ $cw = $cw*_MPDFK;
+ $ch = $ch*_MPDFK;
+ if (empty($size) && !$resize) { return array($imw, $imh, $repx, $repy); }
+
+ if (isset($size['w']) && $size['w']) {
+ if ($size['w']=='contain') {
+ // Scale the image, while preserving its intrinsic aspect ratio (if any), to the largest size such that both its width and its height can fit inside the background positioning area.
+ // Same as resize==3
+ $h = $imh * $cw/$imw;
+ $w = $cw;
+ if ($h > $ch) {
+ $w = $w * $ch/$h;
+ $h = $ch;
+ }
+ }
+ else if ($size['w']=='cover') {
+ // Scale the image, while preserving its intrinsic aspect ratio (if any), to the smallest size such that both its width and its height can completely cover the background positioning area.
+ $h = $imh * $cw/$imw;
+ $w = $cw;
+ if ($h < $ch) {
+ $w = $w * $h/$ch;
+ $h = $ch;
+ }
+ }
+ else {
+ if (stristr($size['w'] ,'%')) {
+ $size['w'] += 0;
+ $size['w'] /= 100;
+ $size['w'] = ($cw * $size['w']);
+ }
+ if (stristr($size['h'] ,'%')) {
+ $size['h'] += 0;
+ $size['h'] /= 100;
+ $size['h'] = ($ch * $size['h']);
+ }
+ if ($size['w']=='auto' && $size['h']=='auto') {
+ $w = $imw;
+ $h = $imh;
+ }
+ else if ($size['w']=='auto' && $size['h']!='auto') {
+ $w = $imw * $size['h']/$imh;
+ $h = $size['h'];
+ }
+ else if ($size['w']!='auto' && $size['h']=='auto') {
+ $h = $imh * $size['w']/$imw;
+ $w = $size['w'];
+ }
+ else {
+ $w = $size['w'];
+ $h = $size['h'];
+ }
+ }
+ return array($w, $h, $repx, $repy);
+ }
+ else if ($resize==1 && $imw > $cw) {
+ $h = $imh * $cw/$imw;
+ return array($cw, $h, $repx, $repy);
+ }
+ else if ($resize==2 && $imh > $ch) {
+ $w = $imw * $ch/$imh;
+ return array($w, $ch, $repx, $repy);
+ }
+ else if ($resize==3) {
+ $w = $imw;
+ $h = $imh;
+ if ($w > $cw) {
+ $h = $h * $cw/$w;
+ $w = $cw;
+ }
+ if ($h > $ch) {
+ $w = $w * $ch/$h;
+ $h = $ch;
+ }
+ return array($w, $h, $repx, $repy);
+ }
+ else if ($resize==4) {
+ $h = $imh * $cw/$imw;
+ return array($cw, $h, $repx, $repy);
+ }
+ else if ($resize==5) {
+ $w = $imw * $ch/$imh;
+ return array($w, $ch, $repx, $repy);
+ }
+ else if ($resize==6) {
+ return array($cw, $ch, $repx, $repy);
+ }
+ return array($imw, $imh, $repx, $repy);
+}
+
+
+function SetBackground(&$properties, &$maxwidth) {
+ if (isset($properties['BACKGROUND-ORIGIN']) && ($properties['BACKGROUND-ORIGIN']=='border-box' || $properties['BACKGROUND-ORIGIN']== 'content-box')) { $origin = $properties['BACKGROUND-ORIGIN']; }
+ else { $origin = 'padding-box'; }
+ if (isset($properties['BACKGROUND-SIZE'])) {
+ if (stristr($properties['BACKGROUND-SIZE'] ,'contain') ) { $bsw = $bsh = 'contain'; }
+ else if (stristr($properties['BACKGROUND-SIZE'] ,'cover') ) { $bsw = $bsh = 'cover'; }
+ else {
+ $bsw = $bsh = 'auto';
+ $sz = preg_split('/\s+/',trim($properties['BACKGROUND-SIZE']));
+ if (count($sz)==2) { $bsw = $sz[0]; $bsh = $sz[1]; }
+ else { $bsw = $sz[0]; }
+ if (!stristr($bsw ,'%') && !stristr($bsw ,'auto') ) { $bsw = $this->ConvertSize($bsw ,$maxwidth,$this->FontSize); }
+ if (!stristr($bsh ,'%') && !stristr($bsh ,'auto') ) { $bsh = $this->ConvertSize($bsh ,$maxwidth,$this->FontSize); }
+ }
+ $size = array('w'=>$bsw, 'h'=>$bsh);
+ }
+ else { $size = false; } // mPDF 6
+ if (preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/',$properties['BACKGROUND-IMAGE'])) {
+ return array('gradient'=>$properties['BACKGROUND-IMAGE'], 'origin'=>$origin, 'size'=>$size );
+ }
+ else {
+ $file = $properties['BACKGROUND-IMAGE'];
+ $sizesarray = $this->Image($file,0,0,0,0,'','',false, false, false, false, true);
+ if (isset($sizesarray['IMAGE_ID'])) {
+ $image_id = $sizesarray['IMAGE_ID'];
+ $orig_w = $sizesarray['WIDTH']*_MPDFK; // in user units i.e. mm
+ $orig_h = $sizesarray['HEIGHT']*_MPDFK; // (using $this->img_dpi)
+ if (isset($properties['BACKGROUND-IMAGE-RESOLUTION'])) {
+ if (preg_match('/from-image/i', $properties['BACKGROUND-IMAGE-RESOLUTION']) && isset($sizesarray['set-dpi']) && $sizesarray['set-dpi']>0) {
+ $orig_w *= $this->img_dpi / $sizesarray['set-dpi'];
+ $orig_h *= $this->img_dpi / $sizesarray['set-dpi'];
+ }
+ else if (preg_match('/(\d+)dpi/i', $properties['BACKGROUND-IMAGE-RESOLUTION'], $m)) {
+ $dpi = $m[1];
+ if ($dpi > 0) {
+ $orig_w *= $this->img_dpi / $dpi;
+ $orig_h *= $this->img_dpi / $dpi;
+ }
+ }
+ }
+ $x_repeat = true;
+ $y_repeat = true;
+ if (isset($properties['BACKGROUND-REPEAT'])) {
+ if ($properties['BACKGROUND-REPEAT']=='no-repeat' || $properties['BACKGROUND-REPEAT']=='repeat-x') { $y_repeat = false; }
+ if ($properties['BACKGROUND-REPEAT']=='no-repeat' || $properties['BACKGROUND-REPEAT']=='repeat-y') { $x_repeat = false; }
+ }
+ $x_pos = 0;
+ $y_pos = 0;
+ if (isset($properties['BACKGROUND-POSITION'])) {
+ $ppos = preg_split('/\s+/',$properties['BACKGROUND-POSITION']);
+ $x_pos = $ppos[0];
+ $y_pos = $ppos[1];
+ if (!stristr($x_pos ,'%') ) { $x_pos = $this->ConvertSize($x_pos ,$maxwidth,$this->FontSize); }
+ if (!stristr($y_pos ,'%') ) { $y_pos = $this->ConvertSize($y_pos ,$maxwidth,$this->FontSize); }
+ }
+ if (isset($properties['BACKGROUND-IMAGE-RESIZE'])) { $resize = $properties['BACKGROUND-IMAGE-RESIZE']; }
+ else { $resize = 0; }
+ if (isset($properties['BACKGROUND-IMAGE-OPACITY'])) { $opacity = $properties['BACKGROUND-IMAGE-OPACITY']; }
+ else { $opacity = 1; }
+ return array('image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$sizesarray['itype'], 'origin'=>$origin, 'size'=>$size );
+ }
+ }
+ return false;
+}
+/*-- END BACKGROUNDS --*/
+
+function PrintBodyBackgrounds() {
+ $s = '';
+ $clx = 0;
+ $cly = 0;
+ $clw = $this->w;
+ $clh = $this->h;
+ // If using bleed and trim margins in paged media
+ if ($this->pageDim[$this->page]['outer_width_LR'] || $this->pageDim[$this->page]['outer_width_TB']) {
+ $clx = $this->pageDim[$this->page]['outer_width_LR'] - $this->pageDim[$this->page]['bleedMargin'];
+ $cly = $this->pageDim[$this->page]['outer_width_TB'] - $this->pageDim[$this->page]['bleedMargin'];
+ $clw = $this->w - 2*$clx;
+ $clh = $this->h - 2*$cly;
+ }
+
+ if ($this->bodyBackgroundColor) {
+ $s .= 'q ' .$this->SetFColor($this->bodyBackgroundColor, true)."\n";
+ if ($this->bodyBackgroundColor{0}==5) { // RGBa
+ $s .= $this->SetAlpha(ord($this->bodyBackgroundColor{4})/100, 'Normal', true, 'F')."\n";
+ }
+ else if ($this->bodyBackgroundColor{0}==6) { // CMYKa
+ $s .= $this->SetAlpha(ord($this->bodyBackgroundColor{5})/100, 'Normal', true, 'F')."\n";
+ }
+ $s .= sprintf('%.3F %.3F %.3F %.3F re f Q', ($clx*_MPDFK), ($cly*_MPDFK),$clw*_MPDFK,$clh*_MPDFK)."\n";
+ }
+
+/*-- BACKGROUNDS --*/
+ if ($this->bodyBackgroundGradient) {
+ $g = $this->grad->parseBackgroundGradient($this->bodyBackgroundGradient);
+ if ($g) {
+ $s .= $this->grad->Gradient($clx, $cly, $clw, $clh, (isset($g['gradtype']) ? $g['gradtype'] : null), $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true);
+ }
+ }
+ if ($this->bodyBackgroundImage) {
+ if (isset($this->bodyBackgroundImage['gradient']) && $this->bodyBackgroundImage['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $this->bodyBackgroundImage['gradient'])) {
+ $g = $this->grad->parseMozGradient( $this->bodyBackgroundImage['gradient']);
+ if ($g) {
+ $s .= $this->grad->Gradient($clx, $cly, $clw, $clh, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true);
+ }
+ }
+ else if ($this->bodyBackgroundImage['image_id']) { // Background pattern
+ $n = count($this->patterns)+1;
+ // If using resize, uses TrimBox (not including the bleed)
+ list($orig_w, $orig_h, $x_repeat, $y_repeat) = $this->_resizeBackgroundImage($this->bodyBackgroundImage['orig_w'], $this->bodyBackgroundImage['orig_h'], $clw, $clh, $this->bodyBackgroundImage['resize'], $this->bodyBackgroundImage['x_repeat'], $this->bodyBackgroundImage['y_repeat']);
+
+ $this->patterns[$n] = array('x'=>$clx, 'y'=>$cly, 'w'=>$clw, 'h'=>$clh, 'pgh'=>$this->h, 'image_id'=>$this->bodyBackgroundImage['image_id'], 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$this->bodyBackgroundImage['x_pos'], 'y_pos'=>$this->bodyBackgroundImage['y_pos'], 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'itype'=>$this->bodyBackgroundImage['itype']);
+ if (($this->bodyBackgroundImage['opacity']>0 || $this->bodyBackgroundImage['opacity']==='0') && $this->bodyBackgroundImage['opacity']<1) { $opac = $this->SetAlpha($this->bodyBackgroundImage['opacity'],'Normal',true); }
+ else { $opac = ''; }
+ $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, ($clx*_MPDFK), ($cly*_MPDFK),$clw*_MPDFK, $clh*_MPDFK) ."\n";
+ }
+ }
+/*-- END BACKGROUNDS --*/
+ return $s;
+}
+
+function _setClippingPath($clx, $cly, $clw, $clh) {
+ $s = ' q 0 w '; // Line width=0
+ $s .= sprintf('%.3F %.3F m ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // start point TL before the arc
+ $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BL
+ $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly+$clh))*_MPDFK); // line to BR
+ $s .= sprintf('%.3F %.3F l ', ($clx+$clw)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TR
+ $s .= sprintf('%.3F %.3F l ', ($clx)*_MPDFK, ($this->h-($cly))*_MPDFK); // line to TL
+ $s .= ' W n '; // Ends path no-op & Sets the clipping path
+ return $s;
+}
+
+
+function PrintPageBackgrounds($adjustmenty=0) {
+ $s = '';
+
+ ksort($this->pageBackgrounds);
+ foreach($this->pageBackgrounds AS $bl=>$pbs) {
+ foreach ($pbs AS $pb) {
+ if ((!isset($pb['image_id']) && !isset($pb['gradient'])) || isset($pb['shadowonly'])) { // Background colour or boxshadow
+ if($pb['z-index']>0) {
+ $this->current_layer = $pb['z-index'];
+ $s .= "\n".'/OCBZ-index /ZI'.$pb['z-index'].' BDC'."\n";
+ }
+
+ if($pb['visibility']!='visible') {
+ if($pb['visibility']=='printonly')
+ $s .= '/OC /OC1 BDC'."\n";
+ else if($pb['visibility']=='screenonly')
+ $s .= '/OC /OC2 BDC'."\n";
+ else if($pb['visibility']=='hidden')
+ $s .= '/OC /OC3 BDC'."\n";
+ }
+ // Box shadow
+ if (isset($pb['shadow']) && $pb['shadow']) { $s .= $pb['shadow']."\n"; }
+ if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
+ $s .= 'q '.$this->SetFColor($pb['col'], true)."\n";
+ if ($pb['col']{0}==5) { // RGBa
+ $s .= $this->SetAlpha(ord($pb['col']{4})/100, 'Normal', true, 'F')."\n";
+ }
+ else if ($pb['col']{0}==6) { // CMYKa
+ $s .= $this->SetAlpha(ord($pb['col']{5})/100, 'Normal', true, 'F')."\n";
+ }
+ $s .= sprintf('%.3F %.3F %.3F %.3F re f Q',$pb['x']*_MPDFK,($this->h-$pb['y'])*_MPDFK,$pb['w']*_MPDFK,-$pb['h']*_MPDFK)."\n";
+ if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
+ if($pb['visibility']!='visible')
+ $s .= 'EMC'."\n";
+
+ if($pb['z-index']>0) {
+ $s .= "\n".'EMCBZ-index'."\n";
+ $this->current_layer = 0;
+ }
+ }
+ }
+/*-- BACKGROUNDS --*/
+ foreach ($pbs AS $pb) {
+ if ((isset($pb['gradient']) && $pb['gradient']) || (isset($pb['image_id']) && $pb['image_id'])) {
+ if($pb['z-index']>0) {
+ $this->current_layer = $pb['z-index'];
+ $s .= "\n".'/OCGZ-index /ZI'.$pb['z-index'].' BDC'."\n";
+ }
+ if($pb['visibility']!='visible') {
+ if($pb['visibility']=='printonly')
+ $s .= '/OC /OC1 BDC'."\n";
+ else if($pb['visibility']=='screenonly')
+ $s .= '/OC /OC2 BDC'."\n";
+ else if($pb['visibility']=='hidden')
+ $s .= '/OC /OC3 BDC'."\n";
+ }
+ }
+ if (isset($pb['gradient']) && $pb['gradient']) {
+ if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
+ $s .= $this->grad->Gradient($pb['x'], $pb['y'], $pb['w'], $pb['h'], $pb['gradtype'], $pb['stops'], $pb['colorspace'], $pb['coords'], $pb['extend'], true);
+ if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
+ }
+ else if (isset($pb['image_id']) && $pb['image_id']) { // Background Image
+ $pb['y'] -= $adjustmenty;
+ $pb['h'] += $adjustmenty;
+ $n = count($this->patterns)+1;
+ list($orig_w, $orig_h, $x_repeat, $y_repeat) = $this->_resizeBackgroundImage($pb['orig_w'], $pb['orig_h'], $pb['w'], $pb['h'], $pb['resize'], $pb['x_repeat'], $pb['y_repeat'], $pb['bpa'], $pb['size']);
+ $this->patterns[$n] = array('x'=>$pb['x'], 'y'=>$pb['y'], 'w'=>$pb['w'], 'h'=>$pb['h'], 'pgh'=>$this->h, 'image_id'=>$pb['image_id'], 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$pb['x_pos'], 'y_pos'=>$pb['y_pos'], 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'itype'=>$pb['itype'], 'bpa'=>$pb['bpa']);
+ $x = $pb['x']*_MPDFK;
+ $y = ($this->h - $pb['y'])*_MPDFK;
+ $w = $pb['w']*_MPDFK;
+ $h = -$pb['h']*_MPDFK;
+ if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
+ if ($this->writingHTMLfooter || $this->writingHTMLheader) { // Write each (tiles) image rather than use as a pattern
+ $iw = $pb['orig_w']/_MPDFK;
+ $ih = $pb['orig_h']/_MPDFK;
+
+ $w = $pb['w'];
+ $h = $pb['h'];
+ $x0 = $pb['x'];
+ $y0 = $pb['y'];
+
+ if (isset($pb['bpa']) && $pb['bpa']) {
+ $w = $pb['bpa']['w'];
+ $h = $pb['bpa']['h'];
+ $x0 = $pb['bpa']['x'];
+ $y0 = $pb['bpa']['y'];
+ }
+
+ if (isset($pb['size']['w']) && $pb['size']['w']) {
+ $size = $pb['size'];
+
+ if ($size['w']=='contain') {
+ // Scale the image, while preserving its intrinsic aspect ratio (if any), to the largest size such that both its width and its height can fit inside the background positioning area.
+ // Same as resize==3
+ $ih = $ih * $pb['bpa']['w']/$iw;
+ $iw = $pb['bpa']['w'];
+ if ($ih > $pb['bpa']['h']) {
+ $iw = $iw * $pb['bpa']['h']/$ih;
+ $ih = $pb['bpa']['h'];
+ }
+ }
+ else if ($size['w']=='cover') {
+ // Scale the image, while preserving its intrinsic aspect ratio (if any), to the smallest size such that both its width and its height can completely cover the background positioning area.
+ $ih = $ih * $pb['bpa']['w']/$iw;
+ $iw = $pb['bpa']['w'];
+ if ($ih < $pb['bpa']['h']) {
+ $iw = $iw * $ih/$pb['bpa']['h'];
+ $ih = $pb['bpa']['h'];
+ }
+ }
+ else {
+ if (stristr($size['w'] ,'%')) {
+ $size['w'] += 0;
+ $size['w'] /= 100;
+ $size['w'] = ($pb['bpa']['w'] * $size['w']);
+ }
+ if (stristr($size['h'] ,'%')) {
+ $size['h'] += 0;
+ $size['h'] /= 100;
+ $size['h'] = ($pb['bpa']['h'] * $size['h']);
+ }
+ if ($size['w']=='auto' && $size['h']=='auto') {
+ $iw = $iw;
+ $ih = $ih;
+ }
+ else if ($size['w']=='auto' && $size['h']!='auto') {
+ $iw = $iw * $size['h']/$ih;
+ $ih = $size['h'];
+ }
+ else if ($size['w']!='auto' && $size['h']=='auto') {
+ $ih = $ih * $size['w']/$iw;
+ $iw = $size['w'];
+ }
+ else {
+ $iw = $size['w'];
+ $ih = $size['h'];
+ }
+ }
+ }
+
+ // Number to repeat
+ if ($pb['x_repeat']) { $nx = ceil($pb['w']/$iw)+1; }
+ else { $nx = 1; }
+ if ($pb['y_repeat']) { $ny = ceil($pb['h']/$ih)+1; }
+ else { $ny = 1; }
+
+ $x_pos = $pb['x_pos'];
+ if (stristr($x_pos ,'%') ) {
+ $x_pos += 0;
+ $x_pos /= 100;
+ $x_pos = ($pb['bpa']['w'] * $x_pos) - ($iw * $x_pos);
+ }
+ $y_pos = $pb['y_pos'];
+ if (stristr($y_pos ,'%') ) {
+ $y_pos += 0;
+ $y_pos /= 100;
+ $y_pos = ($pb['bpa']['h'] * $y_pos) - ($ih * $y_pos);
+ }
+ if ($nx>1) {
+ while($x_pos>($pb['x']-$pb['bpa']['x'])) { $x_pos -= $iw; }
+ }
+ if ($ny>1) {
+ while($y_pos>($pb['y']-$pb['bpa']['y'])) { $y_pos -= $ih; }
+ }
+ for($xi=0;$xi<$nx;$xi++) {
+ for($yi=0;$yi<$ny;$yi++) {
+ $x = $x0 + $x_pos + ($iw*$xi);
+ $y = $y0 + $y_pos + ($ih*$yi);
+ if ($pb['opacity']>0 && $pb['opacity']<1) { $opac = $this->SetAlpha($pb['opacity'],'Normal',true); }
+ else { $opac = ''; }
+ $s .= sprintf("q %s %.3F 0 0 %.3F %.3F %.3F cm /I%d Do Q", $opac,$iw*_MPDFK,$ih*_MPDFK,$x*_MPDFK,($this->h-($y+$ih))*_MPDFK,$pb['image_id']) ."\n";
+ }
+ }
+ }
+ else {
+ if (($pb['opacity']>0 || $pb['opacity']==='0') && $pb['opacity']<1) { $opac = $this->SetAlpha($pb['opacity'],'Normal',true); }
+ else { $opac = ''; }
+ $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $x, $y, $w, $h) ."\n";
+ }
+ if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
+ }
+ if ((isset($pb['gradient']) && $pb['gradient']) || (isset($pb['image_id']) && $pb['image_id'])) {
+ if($pb['visibility']!='visible')
+ $s .= 'EMC'."\n";
+
+ if($pb['z-index']>0) {
+ $s .= "\n".'EMCGZ-index'."\n";
+ $this->current_layer = 0;
+ }
+ }
+
+ }
+/*-- END BACKGROUNDS --*/
+ }
+ return $s;
+}
+
+function PrintTableBackgrounds($adjustmenty=0) {
+ $s = '';
+/*-- BACKGROUNDS --*/
+ ksort($this->tableBackgrounds);
+ foreach($this->tableBackgrounds AS $bl=>$pbs) {
+ foreach ($pbs AS $pb) {
+ if ((!isset($pb['gradient']) || !$pb['gradient']) && (!isset($pb['image_id']) || !$pb['image_id'])) {
+ $s .= 'q '.$this->SetFColor($pb['col'], true)."\n";
+ if ($pb['col']{0}==5) { // RGBa
+ $s .= $this->SetAlpha(ord($pb['col']{4})/100, 'Normal', true, 'F')."\n";
+ }
+ else if ($pb['col']{0}==6) { // CMYKa
+ $s .= $this->SetAlpha(ord($pb['col']{5})/100, 'Normal', true, 'F')."\n";
+ }
+ $s .= sprintf('%.3F %.3F %.3F %.3F re %s Q',$pb['x']*_MPDFK,($this->h-$pb['y'])*_MPDFK,$pb['w']*_MPDFK,-$pb['h']*_MPDFK,'f')."\n";
+ }
+ if (isset($pb['gradient']) && $pb['gradient']) {
+ if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
+ $s .= $this->grad->Gradient($pb['x'], $pb['y'], $pb['w'], $pb['h'], $pb['gradtype'], $pb['stops'], $pb['colorspace'], $pb['coords'], $pb['extend'], true);
+ if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
+ }
+ if (isset($pb['image_id']) && $pb['image_id']) { // Background pattern
+ $pb['y'] -= $adjustmenty;
+ $pb['h'] += $adjustmenty;
+ $n = count($this->patterns)+1;
+ list($orig_w, $orig_h, $x_repeat, $y_repeat) = $this->_resizeBackgroundImage($pb['orig_w'], $pb['orig_h'], $pb['w'], $pb['h'], $pb['resize'], $pb['x_repeat'], $pb['y_repeat']);
+ $this->patterns[$n] = array('x'=>$pb['x'], 'y'=>$pb['y'], 'w'=>$pb['w'], 'h'=>$pb['h'], 'pgh'=>$this->h, 'image_id'=>$pb['image_id'], 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$pb['x_pos'], 'y_pos'=>$pb['y_pos'], 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'itype'=>$pb['itype']);
+ $x = $pb['x']*_MPDFK;
+ $y = ($this->h - $pb['y'])*_MPDFK;
+ $w = $pb['w']*_MPDFK;
+ $h = -$pb['h']*_MPDFK;
+
+ // mPDF 5.7.3
+ if (($this->writingHTMLfooter || $this->writingHTMLheader) && (!isset($pb['clippath']) || $pb['clippath']=='') ) {
+ // Set clipping path
+ $pb['clippath'] = sprintf(' q 0 w %.3F %.3F m %.3F %.3F l %.3F %.3F l %.3F %.3F l %.3F %.3F l W n ', $x, $y, $x, $y+$h, $x+$w, $y+$h, $x+$w, $y, $x, $y);
+ }
+
+ if (isset($pb['clippath']) && $pb['clippath']) { $s .= $pb['clippath']."\n"; }
+
+ // mPDF 5.7.3
+ if ($this->writingHTMLfooter || $this->writingHTMLheader) { // Write each (tiles) image rather than use as a pattern
+ $iw = $pb['orig_w']/_MPDFK;
+ $ih = $pb['orig_h']/_MPDFK;
+
+ $w = $pb['w'];
+ $h = $pb['h'];
+ $x0 = $pb['x'];
+ $y0 = $pb['y'];
+
+ if (isset($pb['bpa']) && $pb['bpa']) {
+ $w = $pb['bpa']['w'];
+ $h = $pb['bpa']['h'];
+ $x0 = $pb['bpa']['x'];
+ $y0 = $pb['bpa']['y'];
+ }
+ // At present 'bpa' (background page area) is not set for tablebackgrounds - only pagebackgrounds
+ // For now, just set it as:
+ else {
+ $pb['bpa'] = array('x'=>$x0, 'y'=>$y0, 'w'=>$w, 'h'=>$h);
+ }
+
+ if (isset($pb['size']['w']) && $pb['size']['w']) {
+ $size = $pb['size'];
+
+ if ($size['w']=='contain') {
+ // Scale the image, while preserving its intrinsic aspect ratio (if any), to the largest size such that both its width and its height can fit inside the background positioning area.
+ // Same as resize==3
+ $ih = $ih * $pb['bpa']['w']/$iw;
+ $iw = $pb['bpa']['w'];
+ if ($ih > $pb['bpa']['h']) {
+ $iw = $iw * $pb['bpa']['h']/$ih;
+ $ih = $pb['bpa']['h'];
+ }
+ }
+ else if ($size['w']=='cover') {
+ // Scale the image, while preserving its intrinsic aspect ratio (if any), to the smallest size such that both its width and its height can completely cover the background positioning area.
+ $ih = $ih * $pb['bpa']['w']/$iw;
+ $iw = $pb['bpa']['w'];
+ if ($ih < $pb['bpa']['h']) {
+ $iw = $iw * $ih/$pb['bpa']['h'];
+ $ih = $pb['bpa']['h'];
+ }
+ }
+ else {
+ if (stristr($size['w'] ,'%')) {
+ $size['w'] += 0;
+ $size['w'] /= 100;
+ $size['w'] = ($pb['bpa']['w'] * $size['w']);
+ }
+ if (stristr($size['h'] ,'%')) {
+ $size['h'] += 0;
+ $size['h'] /= 100;
+ $size['h'] = ($pb['bpa']['h'] * $size['h']);
+ }
+ if ($size['w']=='auto' && $size['h']=='auto') {
+ $iw = $iw;
+ $ih = $ih;
+ }
+ else if ($size['w']=='auto' && $size['h']!='auto') {
+ $iw = $iw * $size['h']/$ih;
+ $ih = $size['h'];
+ }
+ else if ($size['w']!='auto' && $size['h']=='auto') {
+ $ih = $ih * $size['w']/$iw;
+ $iw = $size['w'];
+ }
+ else {
+ $iw = $size['w'];
+ $ih = $size['h'];
+ }
+ }
+ }
+
+ // Number to repeat
+ if (isset($pb['x_repeat']) && $pb['x_repeat']) { $nx = ceil($pb['w']/$iw)+1; }
+ else { $nx = 1; }
+ if (isset($pb['y_repeat']) && $pb['y_repeat']) { $ny = ceil($pb['h']/$ih)+1; }
+ else { $ny = 1; }
+
+ $x_pos = $pb['x_pos'];
+ if (stristr($x_pos ,'%') ) {
+ $x_pos += 0;
+ $x_pos /= 100;
+ $x_pos = ($pb['bpa']['w'] * $x_pos) - ($iw * $x_pos);
+ }
+ $y_pos = $pb['y_pos'];
+ if (stristr($y_pos ,'%') ) {
+ $y_pos += 0;
+ $y_pos /= 100;
+ $y_pos = ($pb['bpa']['h'] * $y_pos) - ($ih * $y_pos);
+ }
+ if ($nx>1) {
+ while($x_pos>($pb['x']-$pb['bpa']['x'])) { $x_pos -= $iw; }
+ }
+ if ($ny>1) {
+ while($y_pos>($pb['y']-$pb['bpa']['y'])) { $y_pos -= $ih; }
+ }
+ for($xi=0;$xi<$nx;$xi++) {
+ for($yi=0;$yi<$ny;$yi++) {
+ $x = $x0 + $x_pos + ($iw*$xi);
+ $y = $y0 + $y_pos + ($ih*$yi);
+ if ($pb['opacity']>0 && $pb['opacity']<1) { $opac = $this->SetAlpha($pb['opacity'],'Normal',true); }
+ else { $opac = ''; }
+ $s .= sprintf("q %s %.3F 0 0 %.3F %.3F %.3F cm /I%d Do Q", $opac,$iw*_MPDFK,$ih*_MPDFK,$x*_MPDFK,($this->h-($y+$ih))*_MPDFK,$pb['image_id']) ."\n";
+ }
+ }
+ }
+ else {
+ if (($pb['opacity']>0 || $pb['opacity']==='0') && $pb['opacity']<1) { $opac = $this->SetAlpha($pb['opacity'],'Normal',true); }
+ else { $opac = ''; }
+ $s .= sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $x, $y, $w, $h) ."\n";
+ }
+
+ if (isset($pb['clippath']) && $pb['clippath']) { $s .= 'Q'."\n"; }
+ }
+ }
+ }
+/*-- END BACKGROUNDS --*/
+ return $s;
+}
+
+function BeginLayer($id) {
+ if($this->current_layer>0) $this->EndLayer();
+ if ($id < 1) { return false; }
+ if (!isset($this->layers[$id])) {
+ $this->layers[$id] = array('name'=>'Layer '.($id) );
+ if (($this->PDFA || $this->PDFX)) { $this->PDFAXwarnings[] = "Cannot use layers when using PDFA or PDFX"; return ''; }
+ else if (!$this->PDFA && !$this->PDFX) { $this->pdf_version='1.5'; }
+ }
+ $this->current_layer = $id;
+ $this->_out('/OCZ-index /ZI'.$id.' BDC');
+
+ $this->pageoutput[$this->page] = array();
+}
+
+function EndLayer() {
+ if($this->current_layer>0) {
+ $this->_out('EMCZ-index');
+ $this->current_layer = 0;
+ }
+}
+
+
+function AddPageByArray($a) {
+ if (!is_array($a)) { $a = array(); }
+ $orientation = (isset($a['orientation']) ? $a['orientation'] : '');
+ $condition = (isset($a['condition']) ? $a['condition'] : (isset($a['type']) ? $a['type'] : ''));
+ $resetpagenum = (isset($a['resetpagenum']) ? $a['resetpagenum'] : '');
+ $pagenumstyle = (isset($a['pagenumstyle']) ? $a['pagenumstyle'] : '');
+ $suppress = (isset($a['suppress']) ? $a['suppress'] : '');
+ $mgl = (isset($a['mgl']) ? $a['mgl'] : (isset($a['margin-left']) ? $a['margin-left'] : ''));
+ $mgr = (isset($a['mgr']) ? $a['mgr'] : (isset($a['margin-right']) ? $a['margin-right'] : ''));
+ $mgt = (isset($a['mgt']) ? $a['mgt'] : (isset($a['margin-top']) ? $a['margin-top'] : ''));
+ $mgb = (isset($a['mgb']) ? $a['mgb'] : (isset($a['margin-bottom']) ? $a['margin-bottom'] : ''));
+ $mgh = (isset($a['mgh']) ? $a['mgh'] : (isset($a['margin-header']) ? $a['margin-header'] : ''));
+ $mgf = (isset($a['mgf']) ? $a['mgf'] : (isset($a['margin-footer']) ? $a['margin-footer'] : ''));
+ $ohname = (isset($a['ohname']) ? $a['ohname'] : (isset($a['odd-header-name']) ? $a['odd-header-name'] : ''));
+ $ehname = (isset($a['ehname']) ? $a['ehname'] : (isset($a['even-header-name']) ? $a['even-header-name'] : ''));
+ $ofname = (isset($a['ofname']) ? $a['ofname'] : (isset($a['odd-footer-name']) ? $a['odd-footer-name'] : ''));
+ $efname = (isset($a['efname']) ? $a['efname'] : (isset($a['even-footer-name']) ? $a['even-footer-name'] : ''));
+ $ohvalue = (isset($a['ohvalue']) ? $a['ohvalue'] : (isset($a['odd-header-value']) ? $a['odd-header-value'] : 0));
+ $ehvalue = (isset($a['ehvalue']) ? $a['ehvalue'] : (isset($a['even-header-value']) ? $a['even-header-value'] : 0));
+ $ofvalue = (isset($a['ofvalue']) ? $a['ofvalue'] : (isset($a['odd-footer-value']) ? $a['odd-footer-value'] : 0));
+ $efvalue = (isset($a['efvalue']) ? $a['efvalue'] : (isset($a['even-footer-value']) ? $a['even-footer-value'] : 0));
+ $pagesel = (isset($a['pagesel']) ? $a['pagesel'] : (isset($a['pageselector']) ? $a['pageselector'] : ''));
+ $newformat = (isset($a['newformat']) ? $a['newformat'] : (isset($a['sheet-size']) ? $a['sheet-size'] : ''));
+
+ $this->AddPage($orientation,$condition,$resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue,$pagesel,$newformat);
+
+}
+
+// mPDF 6 pagebreaktype
+function _preForcedPagebreak($pagebreaktype) {
+ if ($pagebreaktype == 'cloneall') {
+ // Close any open block tags
+ $arr=array();
+ $ai=0;
+ for ($b=$this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag'],$arr,$ai); }
+ if ($this->blklvl==0 && !empty($this->textbuffer)) { //Output previously buffered content
+ $this->printbuffer($this->textbuffer, 1);
+ $this->textbuffer=array();
+ }
+ }
+ else if ($pagebreaktype == 'clonebycss') {
+ // Close open block tags whilst box-decoration-break==clone
+ $arr=array();
+ $ai=0;
+ for ($b=$this->blklvl;$b>0;$b--) {
+ if (isset($this->blk[$b]['box_decoration_break']) && $this->blk[$b]['box_decoration_break']=='clone') { $this->CloseTag($this->blk[$b]['tag'],$arr,$ai); }
+ else {
+ if ($b==$this->blklvl && !empty($this->textbuffer)) { //Output previously buffered content
+ $this->printbuffer($this->textbuffer, 1);
+ $this->textbuffer=array();
+ }
+ break;
+ }
+ }
+ }
+ else if (!empty($this->textbuffer)) { //Output previously buffered content
+ $this->printbuffer($this->textbuffer, 1);
+ $this->textbuffer=array();
+ }
+}
+
+// mPDF 6 pagebreaktype
+function _postForcedPagebreak($pagebreaktype, $startpage, $save_blk, $save_blklvl) {
+ if ($pagebreaktype == 'cloneall') {
+ $this->blk = array();
+ $this->blk[0] = $save_blk[0];
+ // Re-open block tags
+ $this->blklvl = 0;
+ $arr=array();
+ $i=0;
+ for ($b=1; $b<=$save_blklvl;$b++) {
+ $this->OpenTag($save_blk[$b]['tag'],$save_blk[$b]['attr'],$arr,$i);
+ }
+ }
+ else if ($pagebreaktype == 'clonebycss') {
+ $this->blk = array();
+ $this->blk[0] = $save_blk[0];
+ // Don't re-open tags for lowest level elements - so need to do some adjustments
+ for ($b=1; $b<=$this->blklvl;$b++) {
+ $this->blk[$b] = $save_blk[$b];
+ $this->blk[$b]['startpage']=0;
+ $this->blk[$b]['y0']=$this->y; // ?? $this->tMargin
+ if (($this->page - $startpage) % 2) {
+ if (isset($this->blk[$b]['x0'])) { $this->blk[$b]['x0'] += $this->MarginCorrection; }
+ else { $this->blk[$b]['x0'] = $this->MarginCorrection; }
+ }
+ //for Float DIV
+ $this->blk[$b]['marginCorrected'][$this->page] = true;
+ }
+
+ // Re-open block tags for any that have box_decoration_break==clone
+ $arr=array();
+ $i=0;
+ for ($b=$this->blklvl+1; $b<=$save_blklvl;$b++) {
+ if ($b<$this->blklvl) { $this->lastblocklevelchange = -1; }
+ $this->OpenTag($save_blk[$b]['tag'],$save_blk[$b]['attr'],$arr,$i);
+ }
+ if ($this->blk[$this->blklvl]['box_decoration_break']!='clone') { $this->lastblocklevelchange = -1; }
+ }
+ else { $this->lastblocklevelchange = -1; }
+}
+
+function AddPage($orientation='',$condition='', $resetpagenum='', $pagenumstyle='', $suppress='',$mgl='',$mgr='',$mgt='',$mgb='',$mgh='',$mgf='',$ohname='',$ehname='',$ofname='',$efname='',$ohvalue=0,$ehvalue=0,$ofvalue=0,$efvalue=0,$pagesel='',$newformat='') {
+
+/*-- CSS-FLOAT --*/
+ // Float DIV
+ // Cannot do with columns on, or if any change in page orientation/margins etc.
+ // If next page already exists - i.e background /headers and footers already written
+ if ($this->state > 0 && $this->page < count($this->pages)) {
+ $bak_cml = $this->cMarginL;
+ $bak_cmr = $this->cMarginR;
+ $bak_dw = $this->divwidth;
+ // Paint Div Border if necessary
+ if ($this->blklvl > 0) {
+ $save_tr = $this->table_rotate; // *TABLES*
+ $this->table_rotate = 0; // *TABLES*
+ if ($this->y == $this->blk[$this->blklvl]['y0']) { $this->blk[$this->blklvl]['startpage']++; }
+ if (($this->y > $this->blk[$this->blklvl]['y0']) || $this->flowingBlockAttr['is_table'] ) { $toplvl = $this->blklvl; }
+ else { $toplvl = $this->blklvl-1; }
+ $sy = $this->y;
+ for ($bl=1;$bl<=$toplvl;$bl++) {
+ $this->PaintDivBB('pagebottom',0,$bl);
+ }
+ $this->y = $sy;
+ $this->table_rotate = $save_tr; // *TABLES*
+ }
+ $s = $this->PrintPageBackgrounds();
+
+ // Writes after the marker so not overwritten later by page background etc.
+ $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
+ $this->pageBackgrounds = array();
+ $family=$this->FontFamily;
+ $style=$this->FontStyle;
+ $size=$this->FontSizePt;
+ $lw=$this->LineWidth;
+ $dc=$this->DrawColor;
+ $fc=$this->FillColor;
+ $tc=$this->TextColor;
+ $cf=$this->ColorFlag;
+
+ $this->printfloatbuffer();
+
+ //Move to next page
+ $this->page++;
+ $this->ResetMargins();
+ $this->SetAutoPageBreak($this->autoPageBreak,$this->bMargin);
+ $this->x=$this->lMargin;
+ $this->y=$this->tMargin;
+ $this->FontFamily='';
+ $this->_out('2 J');
+ $this->LineWidth=$lw;
+ $this->_out(sprintf('%.3F w',$lw*_MPDFK));
+ if($family) $this->SetFont($family,$style,$size,true,true);
+ $this->DrawColor=$dc;
+ if($dc!=$this->defDrawColor) $this->_out($dc);
+ $this->FillColor=$fc;
+ if($fc!=$this->defFillColor) $this->_out($fc);
+ $this->TextColor=$tc;
+ $this->ColorFlag=$cf;
+ for($bl=1;$bl<=$this->blklvl;$bl++) {
+ $this->blk[$bl]['y0'] = $this->y;
+ // Don't correct more than once for background DIV containing a Float
+ if (!isset($this->blk[$bl]['marginCorrected'][$this->page])) { $this->blk[$bl]['x0'] += $this->MarginCorrection; }
+ $this->blk[$bl]['marginCorrected'][$this->page] = true;
+ }
+ $this->cMarginL = $bak_cml;
+ $this->cMarginR = $bak_cmr;
+ $this->divwidth = $bak_dw;
+ return '';
+ }
+/*-- END CSS-FLOAT --*/
+
+ //Start a new page
+ if($this->state==0) $this->Open();
+
+ $bak_cml = $this->cMarginL;
+ $bak_cmr = $this->cMarginR;
+ $bak_dw = $this->divwidth;
+
+
+ $bak_lh = $this->lineheight;
+
+ $orientation = substr(strtoupper($orientation),0,1);
+ $condition = strtoupper($condition);
+
+
+ if ($condition == 'E') { // only adds new page if needed to create an Even page
+ if (!$this->mirrorMargins || ($this->page)%2==0) { return false; }
+ }
+ else if ($condition == 'O') { // only adds new page if needed to create an Odd page
+ if (!$this->mirrorMargins || ($this->page)%2==1) { return false; }
+ }
+ else if ($condition == 'NEXT-EVEN') { // always adds at least one new page to create an Even page
+ if (!$this->mirrorMargins) { $condition = ''; }
+ else {
+ if ($pagesel) { $pbch = $pagesel; $pagesel = ''; } // *CSS-PAGE*
+ else { $pbch = false; } // *CSS-PAGE*
+ $this->AddPage($this->CurOrientation,'O');
+ $this->extrapagebreak = true; // mPDF 6 pagebreaktype
+ if ($pbch ) { $pagesel = $pbch; } // *CSS-PAGE*
+ $condition = '';
+ }
+ }
+ else if ($condition == 'NEXT-ODD') { // always adds at least one new page to create an Odd page
+ if (!$this->mirrorMargins) { $condition = ''; }
+ else {
+ if ($pagesel) { $pbch = $pagesel; $pagesel = ''; } // *CSS-PAGE*
+ else { $pbch = false; } // *CSS-PAGE*
+ $this->AddPage($this->CurOrientation,'E');
+ $this->extrapagebreak = true; // mPDF 6 pagebreaktype
+ if ($pbch ) { $pagesel = $pbch; } // *CSS-PAGE*
+ $condition = '';
+ }
+ }
+
+
+ if ($resetpagenum || $pagenumstyle || $suppress) {
+ $this->PageNumSubstitutions[] = array('from'=>($this->page+1), 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=>$suppress);
+ }
+
+
+ $save_tr = $this->table_rotate; // *TABLES*
+ $this->table_rotate = 0; // *TABLES*
+ $save_kwt = $this->kwt;
+ $this->kwt = 0;
+ $save_layer = $this->current_layer;
+ $save_vis = $this->visibility;
+
+ if($this->visibility!='visible')
+ $this->SetVisibility('visible');
+ $this->EndLayer();
+
+ // Paint Div Border if necessary
+ //PAINTS BACKGROUND COLOUR OR BORDERS for DIV - DISABLED FOR COLUMNS (cf. AcceptPageBreak) AT PRESENT in ->PaintDivBB
+ if (!$this->ColActive && $this->blklvl > 0) {
+ if (isset($this->blk[$this->blklvl]['y0']) && $this->y == $this->blk[$this->blklvl]['y0'] && !$this->extrapagebreak ) { // mPDF 6 pagebreaktype
+ if (isset($this->blk[$this->blklvl]['startpage'])) { $this->blk[$this->blklvl]['startpage']++; }
+ else { $this->blk[$this->blklvl]['startpage'] = 1; }
+ }
+ if ((isset($this->blk[$this->blklvl]['y0']) && $this->y > $this->blk[$this->blklvl]['y0']) || $this->flowingBlockAttr['is_table'] || $this->extrapagebreak ) { $toplvl = $this->blklvl; } // mPDF 6 pagebreaktype
+ else { $toplvl = $this->blklvl-1; }
+ $sy = $this->y;
+ for ($bl=1;$bl<=$toplvl;$bl++) {
+
+ if (isset($this->blk[$bl]['z-index']) && $this->blk[$bl]['z-index']>0) {
+ $this->BeginLayer($this->blk[$bl]['z-index']);
+ }
+ if (isset($this->blk[$bl]['visibility']) && $this->blk[$bl]['visibility'] && $this->blk[$bl]['visibility']!='visible') {
+ $this->SetVisibility($this->blk[$bl]['visibility']);
+ }
+ $this->PaintDivBB('pagebottom',0,$bl);
+ }
+ $this->y = $sy;
+ // RESET block y0 and x0 - see below
+ }
+ $this->extrapagebreak = false; // mPDF 6 pagebreaktype
+
+ if($this->visibility!='visible')
+ $this->SetVisibility('visible');
+ $this->EndLayer();
+
+ // BODY Backgrounds
+ if ($this->page > 0) {
+ $s = '';
+ $s .= $this->PrintBodyBackgrounds();
+
+ $s .= $this->PrintPageBackgrounds();
+ $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', "\n".$s."\n".'\\1', $this->pages[$this->page]);
+ $this->pageBackgrounds = array();
+ }
+
+ $save_kt = $this->keep_block_together;
+ $this->keep_block_together = 0;
+
+ $save_cols = false;
+/*-- COLUMNS --*/
+ if ($this->ColActive) {
+ $save_cols = true;
+ $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
+ $this->SetColumns(0);
+ }
+/*-- END COLUMNS --*/
+
+
+ $family=$this->FontFamily;
+ $style=$this->FontStyle;
+ $size=$this->FontSizePt;
+ $this->ColumnAdjust = true; // enables column height adjustment for the page
+ $lw=$this->LineWidth;
+ $dc=$this->DrawColor;
+ $fc=$this->FillColor;
+ $tc=$this->TextColor;
+ $cf=$this->ColorFlag;
+ if($this->page>0)
+ {
+ //Page footer
+ $this->InFooter=true;
+
+ $this->Reset();
+ $this->pageoutput[$this->page] = array();
+
+ $this->Footer();
+ //Close page
+ $this->_endpage();
+ }
+
+
+ //Start new page
+ $this->_beginpage($orientation,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat);
+ if ($this->docTemplate) {
+ $pagecount = $this->SetSourceFile($this->docTemplate);
+ if (($this->page - $this->docTemplateStart) > $pagecount) {
+ if ($this->docTemplateContinue) {
+ $tplIdx = $this->ImportPage($pagecount);
+ $this->UseTemplate($tplIdx);
+ }
+ }
+ else {
+ $tplIdx = $this->ImportPage(($this->page - $this->docTemplateStart));
+ $this->UseTemplate($tplIdx);
+ }
+ }
+ if ($this->pageTemplate) {
+ $this->UseTemplate($this->pageTemplate);
+ }
+
+ // Tiling Patterns
+ $this->_out('___PAGE___START'.$this->uniqstr);
+ $this->_out('___BACKGROUND___PATTERNS'.$this->uniqstr);
+ $this->_out('___HEADER___MARKER'.$this->uniqstr);
+ $this->pageBackgrounds = array();
+
+ //Set line cap style to square
+ $this->SetLineCap(2);
+ //Set line width
+ $this->LineWidth=$lw;
+ $this->_out(sprintf('%.3F w',$lw*_MPDFK));
+ //Set font
+ if($family) $this->SetFont($family,$style,$size,true,true); // forces write
+ //Set colors
+ $this->DrawColor=$dc;
+ if($dc!=$this->defDrawColor) $this->_out($dc);
+ $this->FillColor=$fc;
+ if($fc!=$this->defFillColor) $this->_out($fc);
+ $this->TextColor=$tc;
+ $this->ColorFlag=$cf;
+
+ //Page header
+ $this->Header();
+
+ //Restore line width
+ if($this->LineWidth!=$lw)
+ {
+ $this->LineWidth=$lw;
+ $this->_out(sprintf('%.3F w',$lw*_MPDFK));
+ }
+ //Restore font
+ if($family) $this->SetFont($family,$style,$size,true,true); // forces write
+ //Restore colors
+ if($this->DrawColor!=$dc)
+ {
+ $this->DrawColor=$dc;
+ $this->_out($dc);
+ }
+ if($this->FillColor!=$fc)
+ {
+ $this->FillColor=$fc;
+ $this->_out($fc);
+ }
+ $this->TextColor=$tc;
+ $this->ColorFlag=$cf;
+ $this->InFooter=false;
+
+ if ($save_layer>0)
+ $this->BeginLayer($save_layer);
+
+ if($save_vis!='visible')
+ $this->SetVisibility($save_vis);
+
+/*-- COLUMNS --*/
+ if ($save_cols) {
+ // Restore columns
+ $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
+ }
+ if ($this->ColActive) { $this->SetCol(0); }
+/*-- END COLUMNS --*/
+
+
+ //RESET BLOCK BORDER TOP
+ if (!$this->ColActive) {
+ for($bl=1;$bl<=$this->blklvl;$bl++) {
+ $this->blk[$bl]['y0'] = $this->y;
+ if (isset($this->blk[$bl]['x0'])) { $this->blk[$bl]['x0'] += $this->MarginCorrection; }
+ else { $this->blk[$bl]['x0'] = $this->MarginCorrection; }
+ // Added mPDF 3.0 Float DIV
+ $this->blk[$bl]['marginCorrected'][$this->page] = true;
+ }
+ }
+
+
+ $this->table_rotate = $save_tr; // *TABLES*
+ $this->kwt = $save_kwt;
+
+ $this->keep_block_together = $save_kt ;
+
+ $this->cMarginL = $bak_cml;
+ $this->cMarginR = $bak_cmr;
+ $this->divwidth = $bak_dw;
+
+ $this->lineheight = $bak_lh;
+}
+
+
+function PageNo() {
+ //Get current page number
+ return $this->page;
+}
+
+function AddSpotColorsFromFile($file) {
+ $colors = @file($file) or die("Cannot load spot colors file - ".$file);
+ foreach($colors AS $sc) {
+ list($name, $c, $m, $y, $k) = preg_split("/\t/",$sc);
+ $c = intval($c);
+ $m = intval($m);
+ $y = intval($y);
+ $k = intval($k);
+ $this->AddSpotColor($name, $c, $m, $y, $k);
+ }
+}
+
+function AddSpotColor($name, $c, $m, $y, $k) {
+ $name = strtoupper(trim($name));
+ if(!isset($this->spotColors[$name])) {
+ $i=count($this->spotColors)+1;
+ $this->spotColors[$name]=array('i'=>$i,'c'=>$c,'m'=>$m,'y'=>$y,'k'=>$k);
+ $this->spotColorIDs[$i]=$name;
+ }
+}
+
+function SetColor($col, $type='') {
+ $out = '';
+ if (!$col) { return ''; } // mPDF 6
+ if ($col{0}==3 || $col{0}==5) { // RGB / RGBa
+ $out = sprintf('%.3F %.3F %.3F rg',ord($col{1})/255,ord($col{2})/255,ord($col{3})/255);
+ }
+ else if ($col{0}==1) { // GRAYSCALE
+ $out = sprintf('%.3F g',ord($col{1})/255);
+ }
+ else if ($col{0}==2) { // SPOT COLOR
+ $out = sprintf('/CS%d cs %.3F scn',ord($col{1}),ord($col{2})/100);
+ }
+ else if ($col{0}==4 || $col{0}==6) { // CMYK / CMYKa
+ $out = sprintf('%.3F %.3F %.3F %.3F k', ord($col{1})/100, ord($col{2})/100, ord($col{3})/100, ord($col{4})/100);
+ }
+ if ($type=='Draw') { $out = strtoupper($out); } // e.g. rg => RG
+ else if ($type=='CodeOnly') { $out = preg_replace('/\s(rg|g|k)/','',$out); }
+ return $out;
+}
+
+
+function SetDColor($col, $return=false) {
+ $out = $this->SetColor($col, 'Draw');
+ if ($return) { return $out; }
+ if ($out=='') { return ''; }
+ $this->DrawColor = $out;
+ if($this->page>0 && ((isset($this->pageoutput[$this->page]['DrawColor']) && $this->pageoutput[$this->page]['DrawColor'] != $this->DrawColor) || !isset($this->pageoutput[$this->page]['DrawColor']))) { $this->_out($this->DrawColor); }
+ $this->pageoutput[$this->page]['DrawColor'] = $this->DrawColor;
+}
+
+function SetFColor($col, $return=false) {
+ $out = $this->SetColor($col, 'Fill');
+ if ($return) { return $out; }
+ if ($out=='') { return ''; }
+ $this->FillColor = $out;
+ $this->ColorFlag = ($out != $this->TextColor);
+ if($this->page>0 && ((isset($this->pageoutput[$this->page]['FillColor']) && $this->pageoutput[$this->page]['FillColor'] != $this->FillColor) || !isset($this->pageoutput[$this->page]['FillColor']))) { $this->_out($this->FillColor); }
+ $this->pageoutput[$this->page]['FillColor'] = $this->FillColor;
+}
+
+function SetTColor($col, $return=false) {
+ $out = $this->SetColor($col, 'Text');
+ if ($return) { return $out; }
+ if ($out=='') { return ''; }
+ $this->TextColor = $out;
+ $this->ColorFlag = ($this->FillColor != $out);
+}
+
+
+function SetDrawColor($r,$g=-1,$b=-1,$col4=-1, $return=false) {
+ //Set color for all stroking operations
+ $col = array();
+ if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) { $col = $this->ConvertColor($r); }
+ else if ($col4 == -1) { $col = $this->ConvertColor('rgb('.$r.','.$g.','.$b.')'); }
+ else { $col = $this->ConvertColor('cmyk('.$r.','.$g.','.$b.','.$col4.')'); }
+ $out = $this->SetDColor($col, $return);
+ return $out;
+}
+
+function SetFillColor($r,$g=-1,$b=-1,$col4=-1, $return=false) {
+ //Set color for all filling operations
+ $col = array();
+ if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) { $col = $this->ConvertColor($r); }
+ else if ($col4 == -1) { $col = $this->ConvertColor('rgb('.$r.','.$g.','.$b.')'); }
+ else { $col = $this->ConvertColor('cmyk('.$r.','.$g.','.$b.','.$col4.')'); }
+ $out = $this->SetFColor($col, $return);
+ return $out;
+}
+
+function SetTextColor($r,$g=-1,$b=-1,$col4=-1, $return=false) {
+ //Set color for text
+ $col = array();
+ if(($r==0 and $g==0 and $b==0 && $col4 == -1) or $g==-1) { $col = $this->ConvertColor($r); }
+ else if ($col4 == -1) { $col = $this->ConvertColor('rgb('.$r.','.$g.','.$b.')'); }
+ else { $col = $this->ConvertColor('cmyk('.$r.','.$g.','.$b.','.$col4.')'); }
+ $out = $this->SetTColor($col, $return);
+ return $out;
+}
+
+
+function _getCharWidth(&$cw, $u, $isdef=true) {
+ $w = 0;
+ if ($u==0) { $w = false; }
+ else if (isset($cw[$u*2+1])) { $w = (ord($cw[$u*2]) << 8) + ord($cw[$u*2+1]); }
+ if ($w == 65535) { return 0; }
+ else if ($w) { return $w; }
+ else if ($isdef) { return false; }
+ else { return 0; }
+}
+
+function _charDefined(&$cw, $u) {
+ $w = 0;
+ if ($u==0) { return false; }
+ if (isset($cw[$u*2+1])) { $w = (ord($cw[$u*2]) << 8) + ord($cw[$u*2+1]); }
+ if ($w) { return true; }
+ else { return false; }
+}
+
+function GetCharWidthCore($c) {
+ //Get width of a single character in the current Core font
+ $c = (string)$c;
+ $w = 0;
+ // Soft Hyphens chr(173)
+ if ($c == chr(173) && $this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
+ return 0;
+ }
+ else if (($this->textvar & FC_SMALLCAPS) && isset($this->upperCase[ord($c)])) { // mPDF 5.7.1
+ $charw = $this->CurrentFont['cw'][chr($this->upperCase[ord($c)])];
+ if ($charw!==false) {
+ $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
+ $w+=$charw;
+ }
+ }
+ else if (isset($this->CurrentFont['cw'][$c])) {
+ $w += $this->CurrentFont['cw'][$c];
+ }
+ else if (isset($this->CurrentFont['cw'][ord($c)])) {
+ $w += $this->CurrentFont['cw'][ord($c)];
+ }
+ $w *= ($this->FontSize/ 1000);
+ if ($this->minwSpacing || $this->fixedlSpacing) {
+ if ($c==' ') $nb_spaces = 1;
+ else $nb_spaces = 0;
+ $w += $this->fixedlSpacing + ($nb_spaces * $this->minwSpacing);
+ }
+ return ($w);
+}
+
+function GetCharWidthNonCore($c, $addSubset=true) {
+ //Get width of a single character in the current Non-Core font
+ $c = (string)$c;
+ $w = 0;
+ $unicode = $this->UTF8StringToArray($c, $addSubset);
+ $char = $unicode[0];
+/*-- CJK-FONTS --*/
+ if ($this->CurrentFont['type'] == 'Type0') { // CJK Adobe fonts
+ if ($char == 173) { return 0; } // Soft Hyphens
+ elseif (isset($this->CurrentFont['cw'][$char])) { $w+=$this->CurrentFont['cw'][$char]; }
+ elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
+ else { $w += 500; }
+ }
+ else {
+/*-- END CJK-FONTS --*/
+ if ($char == 173) { return 0; } // Soft Hyphens
+ else if (($this->textvar & FC_SMALLCAPS) && isset($this->upperCase[$char])) { // mPDF 5.7.1
+ $charw = $this->_getCharWidth($this->CurrentFont['cw'],$this->upperCase[$char]);
+ if ($charw!==false) {
+ $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
+ $w+=$charw;
+ }
+ elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
+ elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
+ else { $w += 500; }
+ }
+ else {
+ $charw = $this->_getCharWidth($this->CurrentFont['cw'],$char);
+ if ($charw!==false) { $w+=$charw; }
+ elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
+ elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
+ else { $w += 500; }
+ }
+ } // *CJK-FONTS*
+ $w *= ($this->FontSize/ 1000);
+ if ($this->minwSpacing || $this->fixedlSpacing) {
+ if ($c==' ') $nb_spaces = 1;
+ else $nb_spaces = 0;
+ $w += $this->fixedlSpacing + ($nb_spaces * $this->minwSpacing);
+ }
+ return ($w);
+}
+
+
+function GetCharWidth($c, $addSubset=true) {
+ if (!$this->usingCoreFont) {
+ return $this->GetCharWidthNonCore($c, $addSubset);
+ }
+ else {
+ return $this->GetCharWidthCore($c);
+ }
+}
+
+function GetStringWidth($s, $addSubset=true, $OTLdata=false, $textvar=0, $includeKashida=false) { // mPDF 5.7.1
+ //Get width of a string in the current font
+ $s = (string)$s;
+ $cw = &$this->CurrentFont['cw'];
+ $w = 0;
+ $kerning = 0;
+ $lastchar = 0;
+ $nb_carac = 0;
+ $nb_spaces = 0;
+ $kashida = 0;
+ // mPDF ITERATION
+ if ($this->iterationCounter) $s = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/', '\\1', $s);
+ if (!$this->usingCoreFont) {
+ $discards = substr_count($s,"\xc2\xad"); // mPDF 6 soft hyphens [U+00AD]
+ $unicode = $this->UTF8StringToArray($s, $addSubset);
+ if ($this->minwSpacing || $this->fixedlSpacing) {
+ $nb_spaces = mb_substr_count($s,' ', $this->mb_enc);
+ $nb_carac = count($unicode) - $discards ; // mPDF 6
+ // mPDF 5.7.1
+ // Use GPOS OTL
+ if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
+ if (isset($OTLdata['group']) && $OTLdata['group']) {
+ $nb_carac -= substr_count($OTLdata['group'], 'M');
+ }
+ }
+ }
+/*-- CJK-FONTS --*/
+ if ($this->CurrentFont['type'] == 'Type0') { // CJK Adobe fonts
+ foreach($unicode as $char) {
+ if ($char == 0x00AD) { continue; } // mPDF 6 soft hyphens [U+00AD]
+ if (isset($cw[$char])) { $w+=$cw[$char]; }
+ elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
+ else { $w += 500; }
+ }
+ }
+ else {
+/*-- END CJK-FONTS --*/
+ foreach($unicode as $i=>$char) {
+ if ($char == 0x00AD) { continue; } // mPDF 6 soft hyphens [U+00AD]
+ if (($textvar & FC_SMALLCAPS) && isset($this->upperCase[$char])) {
+ $charw = $this->_getCharWidth($cw,$this->upperCase[$char]);
+ if ($charw!==false) {
+ $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
+ $w+=$charw;
+ }
+ elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
+ elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
+ else { $w += 500; }
+ }
+ else {
+ $charw = $this->_getCharWidth($cw,$char);
+ if ($charw!==false) { $w+=$charw; }
+ elseif(isset($this->CurrentFont['desc']['MissingWidth'])) { $w += $this->CurrentFont['desc']['MissingWidth']; }
+ elseif(isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; }
+ else { $w += 500; }
+ // mPDF 5.7.1
+ // Use GPOS OTL
+ // ...GetStringWidth...
+ if (isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF) && !empty($OTLdata)) {
+ if (isset($OTLdata['GPOSinfo'][$i]['wDir']) && $OTLdata['GPOSinfo'][$i]['wDir']=='RTL') {
+ if (isset($OTLdata['GPOSinfo'][$i]['XAdvanceR']) && $OTLdata['GPOSinfo'][$i]['XAdvanceR']) {
+ $w += $OTLdata['GPOSinfo'][$i]['XAdvanceR']* 1000/$this->CurrentFont['unitsPerEm'];
+ }
+ }
+ else {
+ if (isset($OTLdata['GPOSinfo'][$i]['XAdvanceL']) && $OTLdata['GPOSinfo'][$i]['XAdvanceL']) {
+ $w += $OTLdata['GPOSinfo'][$i]['XAdvanceL']* 1000/$this->CurrentFont['unitsPerEm'];
+ }
+ }
+ // Kashida from GPOS
+ // Kashida is set as an absolute length value (already set as a proportion based on useKashida %)
+ if ($includeKashida && isset($OTLdata['GPOSinfo'][$i]['kashida_space']) && $OTLdata['GPOSinfo'][$i]['kashida_space']) {
+ $kashida += $OTLdata['GPOSinfo'][$i]['kashida_space'];
+ }
+ }
+ if (($textvar & FC_KERNING) && $lastchar) {
+ if (isset($this->CurrentFont['kerninfo'][$lastchar][$char])) {
+ $kerning += $this->CurrentFont['kerninfo'][$lastchar][$char];
+ }
+ }
+ $lastchar = $char;
+ }
+ }
+ } // *CJK-FONTS*
+
+ }
+ else {
+ if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
+ $s = str_replace(chr(173),'',$s );
+ }
+ $nb_carac = $l = strlen($s);
+ if ($this->minwSpacing || $this->fixedlSpacing) {
+ $nb_spaces = substr_count($s,' ');
+ }
+ for($i=0; $i<$l; $i++) {
+ if (($textvar & FC_SMALLCAPS) && isset($this->upperCase[ord($s[$i])])) { // mPDF 5.7.1
+ $charw = $cw[chr($this->upperCase[ord($s[$i])])];
+ if ($charw!==false) {
+ $charw = $charw*$this->smCapsScale * $this->smCapsStretch/100;
+ $w+=$charw;
+ }
+ }
+ else if (isset($cw[$s[$i]])) {
+ $w += $cw[$s[$i]];
+ }
+ else if (isset($cw[ord($s[$i])])) {
+ $w += $cw[ord($s[$i])];
+ }
+ if (($textvar & FC_KERNING) && $i>0) { // mPDF 5.7.1
+ if (isset($this->CurrentFont['kerninfo'][$s[($i-1)]][$s[$i]])) {
+ $kerning += $this->CurrentFont['kerninfo'][$s[($i-1)]][$s[$i]];
+ }
+ }
+ }
+ }
+ unset($cw);
+ if ($textvar & FC_KERNING) { $w += $kerning; } // mPDF 5.7.1
+ $w *= ($this->FontSize/ 1000);
+ $w += (($nb_carac + $nb_spaces) * $this->fixedlSpacing) + ($nb_spaces * $this->minwSpacing);
+ $w += $kashida / _MPDFK;
+
+ return ($w);
+}
+
+
+function SetLineWidth($width) {
+ //Set line width
+ $this->LineWidth=$width;
+ $lwout = (sprintf('%.3F w',$width*_MPDFK));
+ if($this->page>0 && ((isset($this->pageoutput[$this->page]['LineWidth']) && $this->pageoutput[$this->page]['LineWidth'] != $lwout) || !isset($this->pageoutput[$this->page]['LineWidth']))) {
+ $this->_out($lwout);
+ }
+ $this->pageoutput[$this->page]['LineWidth'] = $lwout;
+}
+
+function Line($x1,$y1,$x2,$y2) {
+ //Draw a line
+ $this->_out(sprintf('%.3F %.3F m %.3F %.3F l S',$x1*_MPDFK,($this->h-$y1)*_MPDFK,$x2*_MPDFK,($this->h-$y2)*_MPDFK));
+}
+
+function Arrow($x1,$y1,$x2,$y2,$headsize=3,$fill='B',$angle=25) {
+ //F == fill //S == stroke //B == stroke and fill
+ // angle = splay of arrowhead - 1 - 89 degrees
+ if($fill=='F') $fill='f';
+ elseif($fill=='FD' or $fill=='DF' or $fill=='B') $fill='B';
+ else $fill='S';
+ $a = atan2(($y2-$y1),($x2-$x1));
+ $b = $a + deg2rad($angle);
+ $c = $a - deg2rad($angle);
+ $x3 = $x2 - ($headsize* cos($b));
+ $y3 = $this->h-($y2 - ($headsize* sin($b)));
+ $x4 = $x2 - ($headsize* cos($c));
+ $y4 = $this->h-($y2 - ($headsize* sin($c)));
+
+ $x5 = $x3-($x3-$x4)/2; // mid point of base of arrowhead - to join arrow line to
+ $y5 = $y3-($y3-$y4)/2;
+
+ $s = '';
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S',$x1*_MPDFK,($this->h-$y1)*_MPDFK,$x5*_MPDFK,$y5*_MPDFK);
+ $this->_out($s);
+
+ $s = '';
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l %.3F %.3F l %.3F %.3F l %.3F %.3F l ',$x5*_MPDFK,$y5*_MPDFK,$x3*_MPDFK,$y3*_MPDFK,$x2*_MPDFK,($this->h-$y2)*_MPDFK,$x4*_MPDFK,$y4*_MPDFK,$x5*_MPDFK,$y5*_MPDFK);
+ $s.=$fill;
+ $this->_out($s);
+}
+
+
+function Rect($x,$y,$w,$h,$style='') {
+ //Draw a rectangle
+ if($style=='F') $op='f';
+ elseif($style=='FD' or $style=='DF') $op='B';
+ else $op='S';
+ $this->_out(sprintf('%.3F %.3F %.3F %.3F re %s',$x*_MPDFK,($this->h-$y)*_MPDFK,$w*_MPDFK,-$h*_MPDFK,$op));
+}
+
+function AddFont($family,$style='') {
+ if(empty($family)) { return; }
+ $family = strtolower($family);
+ $style=strtoupper($style);
+ $style=str_replace('U','',$style);
+ if($style=='IB') $style='BI';
+ $fontkey = $family.$style;
+ // check if the font has been already added
+ if(isset($this->fonts[$fontkey])) {
+ return;
+ }
+
+/*-- CJK-FONTS --*/
+ if (in_array($family,$this->available_CJK_fonts)) {
+ if (empty($this->Big5_widths)) { require(_MPDF_PATH . 'includes/CJKdata.php'); }
+ $this->AddCJKFont($family); // don't need to add style
+ return;
+ }
+/*-- END CJK-FONTS --*/
+
+ if ($this->usingCoreFont) { die("mPDF Error - problem with Font management"); }
+
+ $stylekey = $style;
+ if (!$style) { $stylekey = 'R'; }
+
+ if (!isset($this->fontdata[$family][$stylekey]) || !$this->fontdata[$family][$stylekey]) {
+ die('mPDF Error - Font is not supported - '.$family.' '.$style);
+ }
+
+ $name = '';
+ $originalsize = 0;
+ $sip = false;
+ $smp = false;
+ $useOTL = 0; // mPDF 5.7.1
+ $fontmetrics = ''; // mPDF 6
+ $haskerninfo = false;
+ $haskernGPOS = false;
+ $hassmallcapsGSUB = false;
+ $BMPselected = false;
+ $GSUBScriptLang = array();
+ $GSUBFeatures = array();
+ $GSUBLookups = array();
+ $GPOSScriptLang = array();
+ $GPOSFeatures = array();
+ $GPOSLookups = array();
+ if (file_exists(_MPDF_TTFONTDATAPATH.$fontkey.'.mtx.php')) { include(_MPDF_TTFONTDATAPATH.$fontkey.'.mtx.php'); }
+
+ $ttffile = '';
+ if (defined('_MPDF_SYSTEM_TTFONTS')) {
+ $ttffile = _MPDF_SYSTEM_TTFONTS.$this->fontdata[$family][$stylekey];
+ if (!file_exists($ttffile)) { $ttffile = ''; }
+ }
+ if (!$ttffile) {
+ $ttffile = _MPDF_TTFONTPATH.$this->fontdata[$family][$stylekey];
+ if (!file_exists($ttffile)) { die("mPDF Error - cannot find TTF TrueType font file - ".$ttffile); }
+ }
+ $ttfstat = stat($ttffile);
+
+ if (isset($this->fontdata[$family]['TTCfontID'][$stylekey])) { $TTCfontID = $this->fontdata[$family]['TTCfontID'][$stylekey]; }
+ else { $TTCfontID = 0; }
+
+ $BMPonly = false;
+ if (in_array($family,$this->BMPonly)) { $BMPonly = true; }
+ $regenerate = false;
+ if ($BMPonly && !$BMPselected) { $regenerate = true; }
+ else if (!$BMPonly && $BMPselected) { $regenerate = true; }
+ // mPDF 5.7.1
+ if (isset($this->fontdata[$family]['useOTL']) && $this->fontdata[$family]['useOTL'] && $useOTL!=$this->fontdata[$family]['useOTL']) {
+ $regenerate = true;
+ $useOTL = $this->fontdata[$family]['useOTL'];
+ }
+ else if ((!isset($this->fontdata[$family]['useOTL']) || !$this->fontdata[$family]['useOTL']) && $useOTL) {
+ $regenerate = true;
+ $useOTL = 0;
+ }
+ if (_FONT_DESCRIPTOR != $fontmetrics) { $regenerate = true; } // mPDF 6
+ if (!isset($name) || $originalsize != $ttfstat['size'] || $regenerate) {
+ if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
+ $ttf = new TTFontFile();
+ $ttf->getMetrics($ttffile, $fontkey, $TTCfontID, $this->debugfonts, $BMPonly, $useOTL); // mPDF 5.7.1
+ $cw = $ttf->charWidths;
+ $kerninfo = $ttf->kerninfo;
+ if ($kerninfo) $haskerninfo = true;
+ $haskernGPOS = $ttf->haskernGPOS;
+ $hassmallcapsGSUB = $ttf->hassmallcapsGSUB;
+ $name = preg_replace('/[ ()]/','',$ttf->fullName);
+ $sip = $ttf->sipset;
+ $smp = $ttf->smpset;
+ // mPDF 6
+ $GSUBScriptLang = $ttf->GSUBScriptLang;
+ $GSUBFeatures = $ttf->GSUBFeatures;
+ $GSUBLookups = $ttf->GSUBLookups;
+ $rtlPUAstr = $ttf->rtlPUAstr;
+ $GPOSScriptLang = $ttf->GPOSScriptLang;
+ $GPOSFeatures = $ttf->GPOSFeatures;
+ $GPOSLookups = $ttf->GPOSLookups;
+ $glyphIDtoUni = $ttf->glyphIDtoUni;
+
+
+ $desc= array(
+ 'CapHeight'=>round($ttf->capHeight),
+ 'XHeight'=>round($ttf->xHeight),
+ 'FontBBox'=>'['.round($ttf->bbox[0])." ".round($ttf->bbox[1])." ".round($ttf->bbox[2])." ".round($ttf->bbox[3]).']', /* FontBBox from head table */
+
+/* 'MaxWidth' => round($ttf->advanceWidthMax), // AdvanceWidthMax from hhea table NB ArialUnicode MS = 31990 ! */
+ 'Flags'=>$ttf->flags,
+ 'Ascent'=>round($ttf->ascent),
+ 'Descent'=>round($ttf->descent),
+ 'Leading' => round($ttf->lineGap),
+ 'ItalicAngle'=>$ttf->italicAngle,
+ 'StemV'=>round($ttf->stemV),
+ 'MissingWidth'=>round($ttf->defaultWidth)
+ );
+ $panose = '';
+ if (count($ttf->panose)) {
+ $panoseArray = array_merge(array($ttf->sFamilyClass, $ttf->sFamilySubClass), $ttf->panose);
+ foreach($panoseArray as $value)
+ $panose .= ' '.dechex($value);
+ }
+ $unitsPerEm = round($ttf->unitsPerEm);
+ $up = round($ttf->underlinePosition);
+ $ut = round($ttf->underlineThickness);
+ $strp = round($ttf->strikeoutPosition); // mPDF 6
+ $strs = round($ttf->strikeoutSize); // mPDF 6
+ $originalsize = $ttfstat['size']+0;
+ $type = 'TTF';
+ //Generate metrics .php file
+ $s='typoAscender).', '.round($ttf->typoDescender).', '.round($ttf->typoLineGap)."\n";
+ $s.='// usWinAscent/usWinDescent = '.round($ttf->usWinAscent).', '.round(-$ttf->usWinDescent)."\n";
+ $s.='// hhea Ascent/Descent/LineGap = '.round($ttf->hheaascent).', '.round($ttf->hheadescent).', '.round($ttf->hhealineGap)."\n";
+
+ // mPDF 5.7.1
+ if (isset($this->fontdata[$family]['useOTL'])) {
+ $s.='$useOTL='.$this->fontdata[$family]['useOTL'].';'."\n";
+ }
+ else $s.='$useOTL=0x0000;'."\n";
+ if ($rtlPUAstr) {
+ $s.='$rtlPUAstr=\''.$rtlPUAstr."';\n";
+ }
+ else $s.='$rtlPUAstr=\'\';'."\n";
+ if (count($GSUBScriptLang)) {
+ $s.='$GSUBScriptLang='.var_export($GSUBScriptLang,true).";\n";
+ }
+ if (count($GSUBFeatures)) {
+ $s.='$GSUBFeatures='.var_export($GSUBFeatures,true).";\n";
+ }
+ if (count($GSUBLookups)) {
+ $s.='$GSUBLookups='.var_export($GSUBLookups,true).";\n";
+ }
+ if (count($GPOSScriptLang)) {
+ $s.='$GPOSScriptLang='.var_export($GPOSScriptLang,true).";\n";
+ }
+ if (count($GPOSFeatures)) {
+ $s.='$GPOSFeatures='.var_export($GPOSFeatures,true).";\n";
+ }
+ if (count($GPOSLookups)) {
+ $s.='$GPOSLookups='.var_export($GPOSLookups,true).";\n";
+ }
+ if ($kerninfo) {
+ $s.='$kerninfo='.var_export($kerninfo,true).";\n";
+ }
+ $s.="?>";
+ if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
+ $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.mtx.php',"w");
+ fwrite($fh,$s,strlen($s));
+ fclose($fh);
+ $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.cw.dat',"wb");
+ fwrite($fh,$cw,strlen($cw));
+ fclose($fh);
+ // mPDF 5.7.1
+ $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.gid.dat',"wb");
+ fwrite($fh,$glyphIDtoUni,strlen($glyphIDtoUni));
+ fclose($fh);
+ if (file_exists(_MPDF_TTFONTDATAPATH.$fontkey.'.cgm')) unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.cgm');
+ if (file_exists(_MPDF_TTFONTDATAPATH.$fontkey.'.z')) unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.z');
+ if (file_exists(_MPDF_TTFONTDATAPATH.$fontkey.'.cw127.php')) unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.cw127.php');
+ if (file_exists(_MPDF_TTFONTDATAPATH.$fontkey.'.cw')) unlink(_MPDF_TTFONTDATAPATH.$fontkey.'.cw');
+ }
+ else if ($this->debugfonts) { $this->Error('Cannot write to the font caching directory - '._MPDF_TTFONTDATAPATH); }
+ unset($ttf);
+ }
+ else {
+ $cw = '';
+ $glyphIDtoUni = '';
+ if (file_exists(_MPDF_TTFONTDATAPATH.$fontkey.'.cw.dat')) $cw = file_get_contents(_MPDF_TTFONTDATAPATH.$fontkey.'.cw.dat');
+ if (file_exists(_MPDF_TTFONTDATAPATH.$fontkey.'.gid.dat')) $glyphIDtoUni = file_get_contents(_MPDF_TTFONTDATAPATH.$fontkey.'.gid.dat');
+ }
+
+/*-- OTL --*/
+ // mPDF 5.7.1
+ // Use OTL OpenType Table Layout - GSUB
+ if (isset($this->fontdata[$family]['useOTL']) && ($this->fontdata[$family]['useOTL'])) {
+ if (!class_exists('otl', false)) { include(_MPDF_PATH.'classes/otl.php'); }
+ if (empty($this->otl)) { $this->otl = new otl($this); }
+ }
+/*-- END OTL --*/
+
+ if (isset($this->fontdata[$family]['sip-ext']) && $this->fontdata[$family]['sip-ext']) { $sipext = $this->fontdata[$family]['sip-ext']; }
+ else { $sipext = ''; }
+
+ // Override with values from config_font.php
+ if (isset($this->fontdata[$family]['Ascent']) && $this->fontdata[$family]['Ascent']) {
+ $desc['Ascent'] = $this->fontdata[$family]['Ascent'];
+ }
+ if (isset($this->fontdata[$family]['Descent']) && $this->fontdata[$family]['Descent']) {
+ $desc['Descent'] = $this->fontdata[$family]['Descent'];
+ }
+ if (isset($this->fontdata[$family]['Leading']) && $this->fontdata[$family]['Leading']) {
+ $desc['Leading'] = $this->fontdata[$family]['Leading'];
+ }
+
+
+
+ $i = count($this->fonts)+$this->extraFontSubsets+1;
+ if ($sip || $smp) {
+ $this->fonts[$fontkey] = array('i'=>$i, 'type'=>$type, 'name'=>$name, 'desc'=>$desc, 'panose'=>$panose, 'unitsPerEm'=>$unitsPerEm, 'up'=>$up, 'ut'=>$ut, 'strs'=>$strs, 'strp'=>$strp, 'cw'=>$cw, 'ttffile'=>$ttffile, 'fontkey'=>$fontkey, 'subsets'=>array(0=>range(0,127)), 'subsetfontids'=>array($i), 'used'=>false, 'sip'=>$sip, 'sipext'=>$sipext, 'smp'=>$smp, 'TTCfontID' => $TTCfontID, 'useOTL' => (isset($this->fontdata[$family]['useOTL']) ? $this->fontdata[$family]['useOTL'] : false), 'useKashida' => (isset($this->fontdata[$family]['useKashida']) ? $this->fontdata[$family]['useKashida'] : false), 'GSUBScriptLang'=>$GSUBScriptLang, 'GSUBFeatures'=>$GSUBFeatures, 'GSUBLookups'=>$GSUBLookups, 'GPOSScriptLang'=>$GPOSScriptLang, 'GPOSFeatures'=>$GPOSFeatures, 'GPOSLookups'=>$GPOSLookups, 'rtlPUAstr'=>$rtlPUAstr, 'glyphIDtoUni'=>$glyphIDtoUni, 'haskerninfo'=>$haskerninfo, 'haskernGPOS'=>$haskernGPOS, 'hassmallcapsGSUB'=>$hassmallcapsGSUB); // mPDF 5.7.1 // mPDF 6
+ }
+ else {
+ $ss = array();
+ for ($s=32; $s<128; $s++) { $ss[$s] = $s; }
+ $this->fonts[$fontkey] = array('i'=>$i, 'type'=>$type, 'name'=>$name, 'desc'=>$desc, 'panose'=>$panose, 'unitsPerEm'=>$unitsPerEm, 'up'=>$up, 'ut'=>$ut, 'strs'=>$strs, 'strp'=>$strp, 'cw'=>$cw, 'ttffile'=>$ttffile, 'fontkey'=>$fontkey, 'subset'=>$ss, 'used'=>false, 'sip'=>$sip, 'sipext'=>$sipext, 'smp'=>$smp, 'TTCfontID' => $TTCfontID, 'useOTL' => (isset($this->fontdata[$family]['useOTL']) ? $this->fontdata[$family]['useOTL'] : false), 'useKashida' => (isset($this->fontdata[$family]['useKashida']) ? $this->fontdata[$family]['useKashida'] : false), 'GSUBScriptLang'=>$GSUBScriptLang, 'GSUBFeatures'=>$GSUBFeatures, 'GSUBLookups'=>$GSUBLookups, 'GPOSScriptLang'=>$GPOSScriptLang, 'GPOSFeatures'=>$GPOSFeatures, 'GPOSLookups'=>$GPOSLookups, 'rtlPUAstr'=>$rtlPUAstr, 'glyphIDtoUni'=>$glyphIDtoUni, 'haskerninfo'=>$haskerninfo, 'haskernGPOS'=>$haskernGPOS, 'hassmallcapsGSUB'=>$hassmallcapsGSUB); // mPDF 5.7.1 // mPDF 6
+ }
+ if ($haskerninfo) { $this->fonts[$fontkey]['kerninfo'] = $kerninfo; }
+ $this->FontFiles[$fontkey]=array('length1'=>$originalsize, 'type'=>"TTF", 'ttffile'=>$ttffile, 'sip'=>$sip, 'smp'=>$smp);
+ unset($cw);
+}
+
+
+
+function SetFont($family,$style='',$size=0, $write=true, $forcewrite=false) {
+ $family=strtolower($family);
+ if (!$this->onlyCoreFonts) {
+ if ($family == 'sans' || $family == 'sans-serif') { $family = $this->sans_fonts[0]; }
+ if ($family == 'serif') { $family = $this->serif_fonts[0]; }
+ if ($family == 'mono' || $family == 'monospace') { $family = $this->mono_fonts[0]; }
+ }
+ if (isset($this->fonttrans[$family]) && $this->fonttrans[$family]) { $family = $this->fonttrans[$family]; }
+ if($family=='') {
+ if ($this->FontFamily) { $family=$this->FontFamily; }
+ else if ($this->default_font) { $family=$this->default_font; }
+ else { $this->Error("No font or default font set!"); }
+ }
+ $this->ReqFontStyle = $style; // required or requested style - used later for artificial bold/italic
+
+ if (($family == 'csymbol') || ($family == 'czapfdingbats') || ($family == 'ctimes') || ($family == 'ccourier') || ($family == 'chelvetica')) {
+ if ($this->PDFA || $this->PDFX) {
+ if ($family == 'csymbol' || $family == 'czapfdingbats') {
+ $this->Error("Symbol and Zapfdingbats cannot be embedded in mPDF (required for PDFA1-b or PDFX/1-a).");
+ }
+ if ($family == 'ctimes' || $family == 'ccourier' || $family == 'chelvetica') {
+ if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "Core Adobe font ".ucfirst($family)." cannot be embedded in mPDF, which is required for PDFA1-b or PDFX/1-a. (Embedded font will be substituted.)"; }
+ if ($family == 'chelvetica') { $family = 'sans'; }
+ if ($family == 'ctimes') { $family = 'serif'; }
+ if ($family == 'ccourier') { $family = 'mono'; }
+ }
+ $this->usingCoreFont = false;
+ }
+ else { $this->usingCoreFont = true; }
+ if($family=='csymbol' || $family=='czapfdingbats') { $style=''; }
+ }
+ else { $this->usingCoreFont = false; }
+
+ // mPDF 5.7.1
+ if ($style) {
+ $style=strtoupper($style);
+ if ($style=='IB') $style='BI';
+ }
+ if ($size==0) $size=$this->FontSizePt;
+
+ $fontkey=$family.$style;
+
+ $stylekey = $style;
+ if (!$stylekey) { $stylekey = "R"; }
+
+ if (!$this->onlyCoreFonts && !$this->usingCoreFont) {
+ if(!isset($this->fonts[$fontkey]) || count($this->default_available_fonts) != count($this->available_unifonts) ) { // not already added
+/*-- CJK-FONTS --*/
+ // CJK fonts
+ if (in_array($fontkey,$this->available_CJK_fonts)) {
+ if(!isset($this->fonts[$fontkey])) { // already added
+ if (empty($this->Big5_widths)) { require(_MPDF_PATH . 'includes/CJKdata.php'); }
+ $this->AddCJKFont($family); // don't need to add style
+ }
+ }
+ // Test to see if requested font/style is available - or substitute
+ else
+/*-- END CJK-FONTS --*/
+ if (!in_array($fontkey,$this->available_unifonts)) {
+ // If font[nostyle] exists - set it
+ if (in_array($family,$this->available_unifonts)) {
+ $style = '';
+ }
+
+ // Else if only one font available - set it (assumes if only one font available it will not have a style)
+ else if (count($this->available_unifonts) == 1) {
+ $family = $this->available_unifonts[0];
+ $style = '';
+ }
+
+ else {
+ $found = 0;
+ // else substitute font of similar type
+ if (in_array($family,$this->sans_fonts)) {
+ $i = array_intersect($this->sans_fonts,$this->available_unifonts);
+ if (count($i)) {
+ $i = array_values($i);
+ // with requested style if possible
+ if (!in_array(($i[0].$style),$this->available_unifonts)) {
+ $style = '';
+ }
+ $family = $i[0];
+ $found = 1;
+ }
+ }
+ else if (in_array($family,$this->serif_fonts)) {
+ $i = array_intersect($this->serif_fonts,$this->available_unifonts);
+ if (count($i)) {
+ $i = array_values($i);
+ // with requested style if possible
+ if (!in_array(($i[0].$style),$this->available_unifonts)) {
+ $style = '';
+ }
+ $family = $i[0];
+ $found = 1;
+ }
+ }
+ else if (in_array($family,$this->mono_fonts)) {
+ $i = array_intersect($this->mono_fonts,$this->available_unifonts);
+ if (count($i)) {
+ $i = array_values($i);
+ // with requested style if possible
+ if (!in_array(($i[0].$style),$this->available_unifonts)) {
+ $style = '';
+ }
+ $family = $i[0];
+ $found = 1;
+ }
+ }
+
+ if (!$found) {
+ // set first available font
+ $fs = $this->available_unifonts[0];
+ preg_match('/^([a-z_0-9\-]+)([BI]{0,2})$/',$fs,$fas); // Allow "-"
+ // with requested style if possible
+ $ws = $fas[1].$style;
+ if (in_array($ws,$this->available_unifonts)) {
+ $family = $fas[1]; // leave $style as is
+ }
+ else if (in_array($fas[1],$this->available_unifonts)) {
+ // or without style
+ $family = $fas[1];
+ $style = '';
+ }
+ else {
+ // or with the style specified
+ $family = $fas[1];
+ $style = $fas[2];
+ }
+ }
+ }
+ $fontkey = $family.$style;
+ }
+ }
+ // try to add font (if not already added)
+ $this->AddFont($family, $style);
+
+ //Test if font is already selected
+ if($this->FontFamily == $family && $this->FontFamily == $this->currentfontfamily && $this->FontStyle == $style && $this->FontStyle == $this->currentfontstyle && $this->FontSizePt == $size && $this->FontSizePt == $this->currentfontsize && !$forcewrite) {
+ return $family;
+ }
+
+ $fontkey = $family.$style;
+
+ //Select it
+ $this->FontFamily = $family;
+ $this->FontStyle = $style;
+ $this->FontSizePt = $size;
+ $this->FontSize = $size / _MPDFK;
+ $this->CurrentFont = &$this->fonts[$fontkey];
+ if ($write) {
+ $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
+ if($this->page>0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']))) { $this->_out($fontout); }
+ $this->pageoutput[$this->page]['Font'] = $fontout;
+ }
+
+
+
+ // Added - currentfont (lowercase) used in HTML2PDF
+ $this->currentfontfamily=$family;
+ $this->currentfontsize=$size;
+ $this->currentfontstyle=$style;
+ $this->setMBencoding('UTF-8');
+ }
+
+ else { // if using core fonts
+
+
+ if ($this->PDFA || $this->PDFX) {
+ $this->Error('Core Adobe fonts cannot be embedded in mPDF (required for PDFA1-b or PDFX/1-a) - cannot use option to use core fonts.');
+ }
+ $this->setMBencoding('windows-1252');
+
+ //Test if font is already selected
+ if(($this->FontFamily == $family) AND ($this->FontStyle == $style) AND ($this->FontSizePt == $size) && !$forcewrite) {
+ return $family;
+ }
+
+ if (!isset($this->CoreFonts[$fontkey])) {
+ if (in_array($family,$this->serif_fonts)) { $family = 'ctimes'; }
+ else if (in_array($family,$this->mono_fonts)) { $family = 'ccourier'; }
+ else { $family = 'chelvetica'; }
+ $this->usingCoreFont = true;
+ $fontkey = $family.$style;
+ }
+
+ if(!isset($this->fonts[$fontkey])) {
+ // STANDARD CORE FONTS
+ if (isset($this->CoreFonts[$fontkey])) {
+ //Load metric file
+ $file=$family;
+ if($family=='ctimes' || $family=='chelvetica' || $family=='ccourier') { $file.=strtolower($style); }
+ $file.='.php';
+ include(_MPDF_PATH.'font/'.$file);
+ if(!isset($cw)) { $this->Error('Could not include font metric file'); }
+ $i=count($this->fonts)+$this->extraFontSubsets+1;
+ $this->fonts[$fontkey]=array('i'=>$i,'type'=>'core','name'=>$this->CoreFonts[$fontkey],'desc'=>$desc,'up'=>$up,'ut'=>$ut,'cw'=>$cw);
+ if ($this->useKerning && isset($kerninfo)) { $this->fonts[$fontkey]['kerninfo'] = $kerninfo; }
+ }
+ else {
+ die('mPDF error - Font not defined');
+ }
+ }
+ //Test if font is already selected
+ if(($this->FontFamily == $family) AND ($this->FontStyle == $style) AND ($this->FontSizePt == $size) && !$forcewrite) {
+ return $family;
+ }
+ //Select it
+ $this->FontFamily=$family;
+ $this->FontStyle=$style;
+ $this->FontSizePt=$size;
+ $this->FontSize=$size/_MPDFK;
+ $this->CurrentFont=&$this->fonts[$fontkey];
+ if ($write) {
+ $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
+ if($this->page>0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']))) { $this->_out($fontout); }
+ $this->pageoutput[$this->page]['Font'] = $fontout;
+ }
+ // Added - currentfont (lowercase) used in HTML2PDF
+ $this->currentfontfamily=$family;
+ $this->currentfontsize=$size;
+ $this->currentfontstyle=$style;
+
+ }
+
+ return $family;
+}
+
+function SetFontSize($size,$write=true) {
+ //Set font size in points
+ if($this->FontSizePt==$size) return;
+ $this->FontSizePt=$size;
+ $this->FontSize=$size/_MPDFK;
+ $this->currentfontsize=$size;
+ if ($write) {
+ $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
+ // Edited mPDF 3.0
+ if($this->page>0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']))) { $this->_out($fontout); }
+ $this->pageoutput[$this->page]['Font'] = $fontout;
+ }
+}
+
+function AddLink() {
+ //Create a new internal link
+ $n=count($this->links)+1;
+ $this->links[$n]=array(0,0);
+ return $n;
+}
+
+function SetLink($link,$y=0,$page=-1) {
+ //Set destination of internal link
+ if($y==-1) $y=$this->y;
+ if($page==-1) $page=$this->page;
+ $this->links[$link]=array($page,$y);
+}
+
+function Link($x,$y,$w,$h,$link) {
+ $l = array($x*_MPDFK,$this->hPt-$y*_MPDFK,$w*_MPDFK,$h*_MPDFK,$link);
+ if ($this->keep_block_together) { // don't write yet
+ return;
+ }
+ else if ($this->table_rotate) { // *TABLES*
+ $this->tbrot_Links[$this->page][]= $l; // *TABLES*
+ return; // *TABLES*
+ } // *TABLES*
+ else if ($this->kwt) {
+ $this->kwt_Links[$this->page][]= $l;
+ return;
+ }
+
+ if ($this->writingHTMLheader || $this->writingHTMLfooter) {
+ $this->HTMLheaderPageLinks[]= $l;
+ return;
+ }
+ //Put a link on the page
+ $this->PageLinks[$this->page][]= $l;
+ // Save cross-reference to Column buffer
+ $ref = count($this->PageLinks[$this->page])-1; // *COLUMNS*
+ $this->columnLinks[$this->CurrCol][INTVAL($this->x)][INTVAL($this->y)] = $ref; // *COLUMNS*
+
+}
+
+function Text($x,$y,$txt,$OTLdata=array(), $textvar=0, $aixextra='',$coordsys='',$return=false) {
+ // Output (or return) a string
+ // Called (internally) by Watermark() & _tableWrite() [rotated cells] & TableHeaderFooter() & WriteText()
+ // Called also from classes/svg.php
+ // Expects Font to be set
+ // Expects input to be mb_encoded if necessary and RTL reversed & OTL processed
+
+ // ARTIFICIAL BOLD AND ITALIC
+ $s = 'q ';
+ if ($this->falseBoldWeight && strpos($this->ReqFontStyle,"B") !== false && strpos($this->FontStyle,"B") === false) {
+ $s .= '2 Tr 1 J 1 j ';
+ $s .= sprintf('%.3F w ',($this->FontSize/130)*_MPDFK*$this->falseBoldWeight);
+ $tc = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
+ if($this->FillColor!=$tc) { $s .= $tc.' '; } // stroke (outline) = same colour as text(fill)
+ }
+ if (strpos($this->ReqFontStyle,"I") !== false && strpos($this->FontStyle,"I") === false) {
+ $aix = '1 0 0.261799 1 %.3F %.3F Tm';
+ }
+ else { $aix = '%.3F %.3F Td'; }
+
+ $aix = $aixextra.$aix;
+
+ if($this->ColorFlag) $s.=$this->TextColor.' ';
+
+ $this->CurrentFont['used']= true;
+
+ if ($this->usingCoreFont) {
+ $txt2 = str_replace(chr(160),chr(32),$txt);
+ }
+ else {
+ $txt2 = str_replace(chr(194).chr(160),chr(32),$txt);
+ }
+
+ $px = $x;
+ $py = $y;
+ if ($coordsys != 'SVG') {
+ $px = $x*_MPDFK;
+ $py = ($this->h-$y)*_MPDFK;
+ }
+
+
+ /* *************** SIMILAR TO Cell() ************************ */
+
+ // IF corefonts AND NOT SmCaps AND NOT Kerning
+ // Just output text
+ if ($this->usingCoreFont && !($textvar & FC_SMALLCAPS) && !($textvar & FC_KERNING)) {
+ $txt2=$this->_escape($txt2);
+ $s .=sprintf('BT '.$aix.' (%s) Tj ET',$px,$py,$txt2);
+ }
+
+
+ // IF NOT corefonts [AND NO wordspacing] AND NOT SIP/SMP AND NOT SmCaps AND NOT Kerning AND NOT OTL
+ // Just output text
+ else if (!$this->usingCoreFont && !($textvar & FC_SMALLCAPS) && !($textvar & FC_KERNING) && !(isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF) && !empty($OTLdata['GPOSinfo']))) {
+ // IF SIP/SMP
+ if ($this->CurrentFont['sip'] || $this->CurrentFont['smp']) {
+ $txt2 = $this->UTF8toSubset($txt2);
+ $s .=sprintf('BT '.$aix.' %s Tj ET',$px,$py,$txt2);
+ }
+ // NOT SIP/SMP
+ else {
+ $txt2 = $this->UTF8ToUTF16BE($txt2, false);
+ $txt2=$this->_escape($txt2);
+ $s .=sprintf('BT '.$aix.' (%s) Tj ET',$px,$py,$txt2);
+ }
+ }
+
+ // IF NOT corefonts [AND IS wordspacing] AND NOT SIP AND NOT SmCaps AND NOT Kerning AND NOT OTL
+ // Not required here (cf. Cell() )
+
+ // ELSE (IF SmCaps || Kerning || OTL) [corefonts or not corefonts; SIP or SMP or BMP]
+ else {
+ $s .= $this->applyGPOSpdf($txt2, $aix, $px,$py, $OTLdata, $textvar );
+ }
+ /* *************** END ************************ */
+
+ $s .= ' ';
+
+ if(($textvar & FD_UNDERLINE) && $txt!='') { // mPDF 5.7.1
+ $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
+ if($this->FillColor!=$c) { $s.= ' '.$c.' '; }
+ if (isset($this->CurrentFont['up']) && $this->CurrentFont['up']) { $up=$this->CurrentFont['up']; }
+ else { $up = -100; }
+ $adjusty = (-$up/1000* $this->FontSize);
+ if (isset($this->CurrentFont['ut']) && $this->CurrentFont['ut']) { $ut=$this->CurrentFont['ut']/1000* $this->FontSize; }
+ else { $ut = 60/1000* $this->FontSize; }
+ $olw = $this->LineWidth;
+ $s.=' '.(sprintf(' %.3F w',$ut*_MPDFK));
+ $s.=' '.$this->_dounderline($x,$y + $adjusty,$txt,$OTLdata,$textvar);
+ $s.=' '.(sprintf(' %.3F w',$olw*_MPDFK));
+ if($this->FillColor!=$c) { $s.= ' '.$this->FillColor.' '; }
+ }
+ // STRIKETHROUGH
+ if(($textvar & FD_LINETHROUGH) && $txt!='') { // mPDF 5.7.1
+ $c = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
+ if($this->FillColor!=$c) { $s.= ' '.$c.' '; }
+ //Superscript and Subscript Y coordinate adjustment (now for striked-through texts)
+ if (isset($this->CurrentFont['desc']['CapHeight']) && $this->CurrentFont['desc']['CapHeight']) { $ch=$this->CurrentFont['desc']['CapHeight']; }
+ else { $ch = 700; }
+ $adjusty = (-$ch/1000* $this->FontSize) * 0.35;
+ if (isset($this->CurrentFont['ut']) && $this->CurrentFont['ut']) { $ut=$this->CurrentFont['ut']/1000* $this->FontSize; }
+ else { $ut = 60/1000* $this->FontSize; }
+ $olw = $this->LineWidth;
+ $s.=' '.(sprintf(' %.3F w',$ut*_MPDFK));
+ $s.=' '.$this->_dounderline($x,$y+$adjusty,$txt,$OTLdata,$textvar);
+ $s.=' '.(sprintf(' %.3F w',$olw*_MPDFK));
+ if($this->FillColor!=$c) { $s.= ' '.$this->FillColor.' '; }
+ }
+ $s .= 'Q';
+
+ if ($return) { return $s." \n"; }
+ $this->_out($s);
+}
+
+/*-- DIRECTW --*/
+function WriteText($x,$y,$txt) {
+ // Output a string using Text() but does encoding and text reversing of RTL
+ $txt = $this->purify_utf8_text($txt);
+ if ($this->text_input_as_HTML) {
+ $txt = $this->all_entities_to_utf8($txt);
+ }
+ if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
+
+ // DIRECTIONALITY
+ if (preg_match("/([".$this->pregRTLchars."])/u", $txt)) { $this->biDirectional = true; } // *OTL*
+
+ $textvar = 0;
+ $save_OTLtags = $this->OTLtags;
+ $this->OTLtags = array();
+ if ($this->useKerning) {
+ if ($this->CurrentFont['haskernGPOS']) { $this->OTLtags['Plus'] .= ' kern'; }
+ else { $textvar = ($textvar | FC_KERNING); }
+ }
+
+/*-- OTL --*/
+ // Use OTL OpenType Table Layout - GSUB & GPOS
+ if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
+ $txt = $this->otl->applyOTL($txt, $this->CurrentFont['useOTL']);
+ $OTLdata = $this->otl->OTLdata;
+ }
+/*-- END OTL --*/
+ $this->OTLtags = $save_OTLtags ;
+
+ $this->magic_reverse_dir($txt, $this->directionality, $OTLdata);
+
+ $this->Text($x,$y,$txt,$OTLdata, $textvar);
+}
+
+function WriteCell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='', $currentx=0) {
+ //Output a cell using Cell() but does encoding and text reversing of RTL
+ $txt = $this->purify_utf8_text($txt);
+ if ($this->text_input_as_HTML) {
+ $txt = $this->all_entities_to_utf8($txt);
+ }
+ if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
+ // DIRECTIONALITY
+ if (preg_match("/([".$this->pregRTLchars."])/u", $txt)) { $this->biDirectional = true; } // *OTL*
+
+ $textvar = 0;
+ $save_OTLtags = $this->OTLtags;
+ $this->OTLtags = array();
+ if ($this->useKerning) {
+ if ($this->CurrentFont['haskernGPOS']) { $this->OTLtags['Plus'] .= ' kern'; }
+ else { $textvar = ($textvar | FC_KERNING); }
+ }
+
+/*-- OTL --*/
+ // Use OTL OpenType Table Layout - GSUB & GPOS
+ if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
+ $txt = $this->otl->applyOTL($txt, $this->CurrentFont['useOTL']);
+ $OTLdata = $this->otl->OTLdata;
+ }
+/*-- END OTL --*/
+ $this->OTLtags = $save_OTLtags ;
+
+ $this->magic_reverse_dir($txt, $this->directionality, $OTLdata);
+
+ $this->Cell($w,$h,$txt,$border,$ln,$align,$fill,$link, $currentx,0,0,'M', 0, false, $OTLdata, $textvar );
+}
+/*-- END DIRECTW --*/
+
+
+function ResetSpacing() {
+ if ($this->ws != 0) { $this->_out('BT 0 Tw ET'); }
+ $this->ws=0;
+ if ($this->charspacing != 0) { $this->_out('BT 0 Tc ET'); }
+ $this->charspacing=0;
+}
+
+
+function SetSpacing($cs,$ws) {
+ if (intval($cs*1000)==0) { $cs = 0; }
+ if ($cs) { $this->_out(sprintf('BT %.3F Tc ET',$cs)); }
+ else if ($this->charspacing != 0) { $this->_out('BT 0 Tc ET'); }
+ $this->charspacing=$cs;
+ if (intval($ws*1000)==0) { $ws = 0; }
+ if ($ws) { $this->_out(sprintf('BT %.3F Tw ET',$ws)); }
+ else if ($this->ws != 0) { $this->_out('BT 0 Tw ET'); }
+ $this->ws=$ws;
+}
+
+// WORD SPACING
+function GetJspacing($nc,$ns,$w,$inclCursive,&$cOTLdata) {
+ $kashida_present = false;
+ $kashida_space = 0;
+ if ($w >0 && $inclCursive && isset($this->CurrentFont['useKashida']) && $this->CurrentFont['useKashida'] && !empty($cOTLdata)) {
+ for($c=0;$c 0) {
+ $kashida_present = true;
+ break 2;
+ }
+ }
+ }
+ }
+
+ if ($kashida_present) {
+ $k_ctr = 0; // Number of kashida points
+ $k_total = 0; // Total of kashida values (priority)
+ // Reset word
+ $max_kashida_in_word = 0;
+ $last_kashida_in_word = -1;
+
+ for($c=0;$c0) {
+ if ($max_kashida_in_word) {
+ if ($cOTLdata[$c]['GPOSinfo'][$i]['kashida'] > $max_kashida_in_word) {
+ $max_kashida_in_word = $cOTLdata[$c]['GPOSinfo'][$i]['kashida'];
+ $cOTLdata[$c]['GPOSinfo'][$last_kashida_in_word]['kashida'] = 0;
+ $last_kashida_in_word = $i;
+ }
+ else {
+ $cOTLdata[$c]['GPOSinfo'][$i]['kashida'] = 0;
+ }
+ }
+ else {
+ $max_kashida_in_word = $cOTLdata[$c]['GPOSinfo'][$i]['kashida'];
+ $last_kashida_in_word = $i;
+ }
+ }
+ }
+ }
+ // Save from last word
+ if ($max_kashida_in_word) {
+ $k_ctr++;
+ $k_total = $max_kashida_in_word;
+ }
+
+ // Number of kashida points = $k_ctr
+ // $useKashida is a % value from CurrentFont/config_fonts.php
+ // % ratio divided between word-spacing and kashida-spacing
+ $kashida_space_ratio = intval($this->CurrentFont['useKashida']) / 100;
+
+
+ $kashida_space = $w * $kashida_space_ratio;
+
+ $tatw = $this->_getCharWidth($this->CurrentFont['cw'], 0x0640);
+ // Only use kashida if each allocated kashida width is > 0.01 x width of a tatweel
+ // Otherwise fontstretch is too small and errors
+ // If not just leave to adjust word-spacing
+ if ($tatw && (($kashida_space/$k_ctr) / $tatw) > 0.01) {
+ for($c=0;$c0) {
+ // At this point kashida is a number representing priority (higher number - higher priority)
+ // We are now going to set it as an actual length
+ // This shares it equally amongst words:
+ $cOTLdata[$c]['GPOSinfo'][$i]['kashida_space'] = (1 / $k_ctr) * $kashida_space;
+ }
+ }
+ }
+ $w -= $kashida_space;
+ }
+ }
+
+ $ws = 0;
+ $charspacing = 0;
+ $ww = $this->jSWord;
+ $ncx = $nc-1;
+ if ($nc == 0) { return array(0,0,0); }
+ // Only word spacing allowed / possible
+ else if ($this->fixedlSpacing !== false || $inclCursive) {
+ if ($ns) { $ws = $w / $ns; }
+ }
+ else if ($nc==1) { $charspacing = $w; }
+ else if (!$ns) {
+ $charspacing = $w / ($ncx );
+ if (($this->jSmaxChar > 0) && ($charspacing > $this->jSmaxChar)) {
+ $charspacing = $this->jSmaxChar;
+ }
+ }
+ else if ($ns == ($ncx )) {
+ $charspacing = $w / $ns;
+ }
+ else {
+ if ($this->usingCoreFont) {
+ $cs = ($w * (1 - $this->jSWord)) / ($ncx );
+ if (($this->jSmaxChar > 0) && ($cs > $this->jSmaxChar)) {
+ $cs = $this->jSmaxChar;
+ $ww = 1 - (($cs * ($ncx ))/$w);
+ }
+ $charspacing = $cs;
+ $ws = ($w * ($ww) ) / $ns;
+ }
+ else {
+ $cs = ($w * (1 - $this->jSWord)) / ($ncx -$ns);
+ if (($this->jSmaxChar > 0) && ($cs > $this->jSmaxChar)) {
+ $cs = $this->jSmaxChar;
+ $ww = 1 - (($cs * ($ncx -$ns))/$w);
+ }
+ $charspacing = $cs;
+ $ws = (($w * ($ww) ) / $ns) - $charspacing;
+ }
+ }
+ return array($charspacing,$ws,$kashida_space);
+}
+
+function Cell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='', $currentx=0, $lcpaddingL=0, $lcpaddingR=0, $valign='M', $spanfill=0, $exactWidth=false, $OTLdata=false, $textvar=0, $lineBox=false) { // mPDF 5.7.1
+
+ //Output a cell
+ // Expects input to be mb_encoded if necessary and RTL reversed
+ // NON_BREAKING SPACE
+ if ($this->usingCoreFont) {
+ $txt = str_replace(chr(160),chr(32),$txt);
+ }
+ else {
+ $txt = str_replace(chr(194).chr(160),chr(32),$txt);
+ }
+
+ $oldcolumn = $this->CurrCol;
+ // Automatic page break
+ // Allows PAGE-BREAK-AFTER = avoid to work
+ if (isset($this->blk[$this->blklvl])) { $bottom = $this->blk[$this->blklvl]['padding_bottom']+$this->blk[$this->blklvl]['margin_bottom']; }
+ else { $bottom = 0; }
+ if (!$this->tableLevel && (($this->y+$this->divheight>$this->PageBreakTrigger) || ($this->y+$h>$this->PageBreakTrigger) ||
+ ($this->y+($h*2)+$bottom>$this->PageBreakTrigger && $this->blk[$this->blklvl]['page_break_after_avoid'])) and !$this->InFooter and $this->AcceptPageBreak()) { // mPDF 5.7.2
+ $x=$this->x;//Current X position
+
+
+ // WORD SPACING
+ $ws=$this->ws;//Word Spacing
+ $charspacing=$this->charspacing;//Character Spacing
+ $this->ResetSpacing();
+
+ $this->AddPage($this->CurOrientation);
+ // Added to correct for OddEven Margins
+ $x += $this->MarginCorrection;
+ if ($currentx) {
+ $currentx += $this->MarginCorrection;
+ }
+ $this->x=$x;
+ // WORD SPACING
+ $this->SetSpacing($charspacing,$ws);
+ }
+
+ // Test: to put line through centre of cell: $this->Line($this->x,$this->y+($h/2),$this->x+50,$this->y+($h/2));
+ // Test: to put border around cell as it is specified: $border='LRTB';
+
+
+/*-- COLUMNS --*/
+ // COLS
+ // COLUMN CHANGE
+ if ($this->CurrCol != $oldcolumn) {
+ if ($currentx) {
+ $currentx += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
+ }
+ $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
+ }
+
+ // COLUMNS Update/overwrite the lowest bottom of printing y value for a column
+ if ($this->ColActive) {
+ if ($h) { $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y+$h; }
+ else { $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y+$this->divheight; }
+ }
+/*-- END COLUMNS --*/
+
+
+ if($w==0) $w = $this->w-$this->rMargin-$this->x;
+ $s='';
+ if($fill==1 && $this->FillColor) {
+ if((isset($this->pageoutput[$this->page]['FillColor']) && $this->pageoutput[$this->page]['FillColor'] != $this->FillColor) || !isset($this->pageoutput[$this->page]['FillColor'])) { $s .= $this->FillColor.' '; }
+ $this->pageoutput[$this->page]['FillColor'] = $this->FillColor;
+ }
+
+
+ if ($lineBox && isset($lineBox['boxtop']) && $txt) { // i.e. always from WriteFlowingBlock/finishFlowingBlock (but not objects -
+ // which only have $lineBox['top'] set)
+ $boxtop = $this->y + $lineBox['boxtop'];
+ $boxbottom = $this->y + $lineBox['boxbottom'];
+ $glyphYorigin = $lineBox['glyphYorigin'];
+ $baseline_shift = $lineBox['baseline-shift'];
+ $bord_boxtop = $bg_boxtop = $boxtop = $boxtop - $baseline_shift;
+ $bord_boxbottom = $bg_boxbottom = $boxbottom = $boxbottom - $baseline_shift;
+ $bord_boxheight = $bg_boxheight = $boxheight = $boxbottom - $boxtop;
+
+ // If inline element BACKGROUND has bounding box set by parent element:
+ if (isset($lineBox['background-boxtop'])) {
+ $bg_boxtop = $this->y + $lineBox['background-boxtop'] - $lineBox['background-baseline-shift'];
+ $bg_boxbottom = $this->y + $lineBox['background-boxbottom'] - $lineBox['background-baseline-shift'];
+ $bg_boxheight = $bg_boxbottom - $bg_boxtop;
+ }
+ // If inline element BORDER has bounding box set by parent element:
+ if (isset($lineBox['border-boxtop'])) {
+ $bord_boxtop = $this->y + $lineBox['border-boxtop'] - $lineBox['border-baseline-shift'];
+ $bord_boxbottom = $this->y + $lineBox['border-boxbottom'] - $lineBox['border-baseline-shift'];
+ $bord_boxheight = $bord_boxbottom - $bord_boxtop;
+ }
+
+
+ }
+ else {
+ $boxtop = $this->y;
+ $boxheight = $h;
+ $boxbottom = $this->y+$h;
+ $baseline_shift = 0;
+ if($txt!='') {
+ // FONT SIZE - this determines the baseline caculation
+ $bfs = $this->FontSize;
+ //Calculate baseline Superscript and Subscript Y coordinate adjustment
+ $bfx = $this->baselineC;
+ $baseline = $bfx*$bfs;
+
+ if($textvar & FA_SUPERSCRIPT) { $baseline_shift = $this->textparam['text-baseline']; } // mPDF 5.7.1 // mPDF 6
+ else if($textvar & FA_SUBSCRIPT) { $baseline_shift = $this->textparam['text-baseline']; } // mPDF 5.7.1 // mPDF 6
+ else if($this->bullet) { $baseline += ($bfx-0.7)*$this->FontSize; }
+
+ // Vertical align (for Images)
+ if ($valign == 'T') { $va = (0.5 * $bfs * $this->normalLineheight); }
+ else if ($valign == 'B') { $va = $h-(0.5 * $bfs * $this->normalLineheight); }
+ else { $va = 0.5*$h; } // Middle
+
+ // ONLY SET THESE IF WANT TO CONFINE BORDER +/- FILL TO FIT FONTSIZE - NOT FULL CELL AS IS ORIGINAL FUNCTION
+ // spanfill or spanborder are set in FlowingBlock functions
+ if ($spanfill || !empty($this->spanborddet) || $link!='') {
+ $exth = 0.2; // Add to fontsize to increase height of background / link / border
+ $boxtop = $this->y+$baseline+$va-($this->FontSize*(1+$exth/2)*(0.5+$bfx));
+ $boxheight = $this->FontSize * (1+$exth);
+ $boxbottom = $boxtop + $boxheight;
+ }
+ $glyphYorigin = $baseline + $va;
+ }
+ $boxtop -= $baseline_shift;
+ $boxbottom -= $baseline_shift;
+ $bord_boxtop = $bg_boxtop = $boxtop;
+ $bord_boxbottom = $bg_boxbottom = $boxbottom;
+ $bord_boxheight = $bg_boxheight = $boxheight = $boxbottom - $boxtop;
+ }
+
+
+ $bbw = $tbw = $lbw = $rbw = 0; // Border widths
+ if (!empty($this->spanborddet)) {
+ if (!isset($this->spanborddet['B'])) { $this->spanborddet['B'] = array('s' => 0, 'style' => '', 'w' => 0); }
+ if (!isset($this->spanborddet['T'])) { $this->spanborddet['T'] = array('s' => 0, 'style' => '', 'w' => 0); }
+ if (!isset($this->spanborddet['L'])) { $this->spanborddet['L'] = array('s' => 0, 'style' => '', 'w' => 0); }
+ if (!isset($this->spanborddet['R'])) { $this->spanborddet['R'] = array('s' => 0, 'style' => '', 'w' => 0); }
+ $bbw = $this->spanborddet['B']['w'];
+ $tbw = $this->spanborddet['T']['w'];
+ $lbw = $this->spanborddet['L']['w'];
+ $rbw = $this->spanborddet['R']['w'];
+ }
+ if($fill==1 || $border==1 || !empty($this->spanborddet)) {
+ if (!empty($this->spanborddet)) {
+ if ($fill==1) {
+ $s.=sprintf('%.3F %.3F %.3F %.3F re f ',($this->x-$lbw)*_MPDFK,($this->h-$bg_boxtop+$tbw)*_MPDFK,($w+$lbw+$rbw)*_MPDFK,(-$bg_boxheight-$tbw-$bbw)*_MPDFK);
+ }
+ $s.= ' q ';
+ $dashon = 3;
+ $dashoff = 3.5;
+ $dot = 2.5;
+ if($tbw) {
+ $short = 0;
+ if ($this->spanborddet['T']['style'] == 'dashed') {
+ $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$tbw*$dashon*_MPDFK,$tbw*$dashoff*_MPDFK);
+ }
+ else if ($this->spanborddet['T']['style'] == 'dotted') {
+ $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$tbw*$dot*_MPDFK,-$tbw/2*_MPDFK);
+ $short = $tbw/2;
+ }
+ else {
+ $s.=' 0 j 0 J [] 0 d ';
+ }
+ if ($this->spanborddet['T']['style'] != 'dotted') {
+ $s .= 'q ';
+ $s .= sprintf('%.3F %.3F m ',($this->x-$lbw)*_MPDFK, ($this->h-$bord_boxtop+$tbw)*_MPDFK);
+ $s .= sprintf('%.3F %.3F l ',($this->x+$w+$rbw)*_MPDFK, ($this->h-$bord_boxtop+$tbw)*_MPDFK);
+ $s .= sprintf('%.3F %.3F l ',($this->x+$w)*_MPDFK, ($this->h-$bord_boxtop)*_MPDFK);
+ $s .= sprintf('%.3F %.3F l ',($this->x)*_MPDFK, ($this->h-$bord_boxtop)*_MPDFK);
+ $s .= ' h W n '; // Ends path no-op & Sets the clipping path
+
+ }
+ $c = $this->SetDColor($this->spanborddet['T']['c'],true);
+ if ($this->spanborddet['T']['style'] == 'double') {
+ $s.=sprintf(' %s %.3F w ',$c,$tbw/3*_MPDFK);
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw)*_MPDFK,($this->h-$bord_boxtop+$tbw*5/6)*_MPDFK,($this->x+$w+$rbw)*_MPDFK,($this->h-$bord_boxtop+$tbw*5/6)*_MPDFK);
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw)*_MPDFK,($this->h-$bord_boxtop+$tbw/6)*_MPDFK,($this->x+$w+$rbw)*_MPDFK,($this->h-$bord_boxtop+$tbw/6)*_MPDFK);
+ }
+ else if ($this->spanborddet['T']['style'] == 'dotted') {
+ $s.=sprintf(' %s %.3F w ',$c,$tbw*_MPDFK);
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw)*_MPDFK,($this->h-$bord_boxtop+$tbw/2)*_MPDFK,($this->x+$w+$rbw-$short)*_MPDFK,($this->h-$bord_boxtop+$tbw/2)*_MPDFK);
+ }
+ else {
+ $s.=sprintf(' %s %.3F w ',$c,$tbw*_MPDFK);
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw)*_MPDFK,($this->h-$bord_boxtop+$tbw/2)*_MPDFK,($this->x+$w+$rbw-$short)*_MPDFK,($this->h-$bord_boxtop+$tbw/2)*_MPDFK);
+ }
+ if ($this->spanborddet['T']['style'] != 'dotted') {
+ $s .= ' Q ';
+ }
+ }
+ if($bbw) {
+ $short = 0;
+ if ($this->spanborddet['B']['style'] == 'dashed') {
+ $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$bbw*$dashon*_MPDFK,$bbw*$dashoff*_MPDFK);
+ }
+ else if ($this->spanborddet['B']['style'] == 'dotted') {
+ $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$bbw*$dot*_MPDFK,-$bbw/2*_MPDFK);
+ $short = $bbw/2;
+ }
+ else {
+ $s.=' 0 j 0 J [] 0 d ';
+ }
+ if ($this->spanborddet['B']['style'] != 'dotted') {
+ $s .= 'q ';
+ $s .= sprintf('%.3F %.3F m ',($this->x-$lbw)*_MPDFK, ($this->h-$bord_boxbottom-$bbw)*_MPDFK);
+ $s .= sprintf('%.3F %.3F l ',($this->x+$w+$rbw)*_MPDFK, ($this->h-$bord_boxbottom-$bbw)*_MPDFK);
+ $s .= sprintf('%.3F %.3F l ',($this->x+$w)*_MPDFK, ($this->h-$bord_boxbottom)*_MPDFK);
+ $s .= sprintf('%.3F %.3F l ',($this->x)*_MPDFK, ($this->h-$bord_boxbottom)*_MPDFK);
+ $s .= ' h W n '; // Ends path no-op & Sets the clipping path
+ }
+ $c = $this->SetDColor($this->spanborddet['B']['c'],true);
+ if ($this->spanborddet['B']['style'] == 'double') {
+ $s.=sprintf(' %s %.3F w ',$c,$bbw/3*_MPDFK);
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw)*_MPDFK,($this->h-$bord_boxbottom-$bbw/6)*_MPDFK,($this->x+$w+$rbw-$short)*_MPDFK,($this->h-$bord_boxbottom-$bbw/6)*_MPDFK);
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw)*_MPDFK,($this->h-$bord_boxbottom-$bbw*5/6)*_MPDFK,($this->x+$w+$rbw-$short)*_MPDFK,($this->h-$bord_boxbottom-$bbw*5/6)*_MPDFK);
+ }
+ else if ($this->spanborddet['B']['style'] == 'dotted') {
+ $s.=sprintf(' %s %.3F w ',$c,$bbw*_MPDFK);
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw)*_MPDFK,($this->h-$bord_boxbottom-$bbw/2)*_MPDFK,($this->x+$w+$rbw-$short)*_MPDFK,($this->h-$bord_boxbottom-$bbw/2)*_MPDFK);
+ }
+ else {
+ $s.=sprintf(' %s %.3F w ',$c,$bbw*_MPDFK);
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw)*_MPDFK,($this->h-$bord_boxbottom-$bbw/2)*_MPDFK,($this->x+$w+$rbw-$short)*_MPDFK,($this->h-$bord_boxbottom-$bbw/2)*_MPDFK);
+ }
+ if ($this->spanborddet['B']['style'] != 'dotted') {
+ $s .= ' Q ';
+ }
+ }
+ if($lbw) {
+ $short = 0;
+ if ($this->spanborddet['L']['style'] == 'dashed') {
+ $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$lbw*$dashon*_MPDFK,$lbw*$dashoff*_MPDFK);
+ }
+ else if ($this->spanborddet['L']['style'] == 'dotted') {
+ $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$lbw*$dot*_MPDFK,-$lbw/2*_MPDFK);
+ $short = $lbw/2;
+ }
+ else {
+ $s.=' 0 j 0 J [] 0 d ';
+ }
+ if ($this->spanborddet['L']['style'] != 'dotted') {
+ $s .= 'q ';
+ $s .= sprintf('%.3F %.3F m ',($this->x-$lbw)*_MPDFK, ($this->h-$bord_boxbottom-$bbw)*_MPDFK);
+ $s .= sprintf('%.3F %.3F l ',($this->x)*_MPDFK, ($this->h-$bord_boxbottom)*_MPDFK);
+ $s .= sprintf('%.3F %.3F l ',($this->x)*_MPDFK, ($this->h-$bord_boxtop)*_MPDFK);
+ $s .= sprintf('%.3F %.3F l ',($this->x-$lbw)*_MPDFK, ($this->h-$bord_boxtop+$tbw)*_MPDFK);
+ $s .= ' h W n '; // Ends path no-op & Sets the clipping path
+ }
+ $c = $this->SetDColor($this->spanborddet['L']['c'],true);
+ if ($this->spanborddet['L']['style'] == 'double') {
+ $s.=sprintf(' %s %.3F w ',$c,$lbw/3*_MPDFK);
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw/6)*_MPDFK,($this->h-$bord_boxtop+$tbw)*_MPDFK,($this->x-$lbw/6)*_MPDFK,($this->h-$bord_boxbottom-$bbw+$short)*_MPDFK);
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw*5/6)*_MPDFK,($this->h-$bord_boxtop+$tbw)*_MPDFK,($this->x-$lbw*5/6)*_MPDFK,($this->h-$bord_boxbottom-$bbw+$short)*_MPDFK);
+ }
+ else if ($this->spanborddet['L']['style'] == 'dotted') {
+ $s.=sprintf(' %s %.3F w ',$c,$lbw*_MPDFK);
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw/2)*_MPDFK,($this->h-$bord_boxtop+$tbw)*_MPDFK,($this->x-$lbw/2)*_MPDFK,($this->h-$bord_boxbottom-$bbw+$short)*_MPDFK);
+ }
+ else {
+ $s.=sprintf(' %s %.3F w ',$c,$lbw*_MPDFK);
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x-$lbw/2)*_MPDFK,($this->h-$bord_boxtop+$tbw)*_MPDFK,($this->x-$lbw/2)*_MPDFK,($this->h-$bord_boxbottom-$bbw+$short)*_MPDFK);
+ }
+ if ($this->spanborddet['L']['style'] != 'dotted') {
+ $s .= ' Q ';
+ }
+ }
+ if($rbw) {
+ $short = 0;
+ if ($this->spanborddet['R']['style'] == 'dashed') {
+ $s.=sprintf(' 0 j 0 J [%.3F %.3F] 0 d ',$rbw*$dashon*_MPDFK,$rbw*$dashoff*_MPDFK);
+ }
+ else if ($this->spanborddet['R']['style'] == 'dotted') {
+ $s.=sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ',0.001,$rbw*$dot*_MPDFK,-$rbw/2*_MPDFK);
+ $short = $rbw/2;
+ }
+ else {
+ $s.=' 0 j 0 J [] 0 d ';
+ }
+ if ($this->spanborddet['R']['style'] != 'dotted') {
+ $s .= 'q ';
+ $s .= sprintf('%.3F %.3F m ',($this->x+$w+$rbw)*_MPDFK, ($this->h-$bord_boxbottom-$bbw)*_MPDFK);
+ $s .= sprintf('%.3F %.3F l ',($this->x+$w)*_MPDFK, ($this->h-$bord_boxbottom)*_MPDFK);
+ $s .= sprintf('%.3F %.3F l ',($this->x+$w)*_MPDFK, ($this->h-$bord_boxtop)*_MPDFK);
+ $s .= sprintf('%.3F %.3F l ',($this->x+$w+$rbw)*_MPDFK, ($this->h-$bord_boxtop+$tbw)*_MPDFK);
+ $s .= ' h W n '; // Ends path no-op & Sets the clipping path
+ }
+ $c = $this->SetDColor($this->spanborddet['R']['c'],true);
+ if ($this->spanborddet['R']['style'] == 'double') {
+ $s.=sprintf(' %s %.3F w ',$c,$rbw/3*_MPDFK);
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x+$w+$rbw/6)*_MPDFK,($this->h-$bord_boxtop+$tbw)*_MPDFK,($this->x+$w+$rbw/6)*_MPDFK,($this->h-$bord_boxbottom-$bbw+$short)*_MPDFK);
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x+$w+$rbw*5/6)*_MPDFK,($this->h-$bord_boxtop+$tbw)*_MPDFK,($this->x+$w+$rbw*5/6)*_MPDFK,($this->h-$bord_boxbottom-$bbw+$short)*_MPDFK);
+ }
+ else if ($this->spanborddet['R']['style'] == 'dotted') {
+ $s.=sprintf(' %s %.3F w ',$c,$rbw*_MPDFK);
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x+$w+$rbw/2)*_MPDFK,($this->h-$bord_boxtop+$tbw)*_MPDFK,($this->x+$w+$rbw/2)*_MPDFK,($this->h-$bord_boxbottom-$bbw+$short)*_MPDFK);
+ }
+ else {
+ $s.=sprintf(' %s %.3F w ',$c,$rbw*_MPDFK);
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($this->x+$w+$rbw/2)*_MPDFK,($this->h-$bord_boxtop+$tbw)*_MPDFK,($this->x+$w+$rbw/2)*_MPDFK,($this->h-$bord_boxbottom-$bbw+$short)*_MPDFK);
+ }
+ if ($this->spanborddet['R']['style'] != 'dotted') {
+ $s .= ' Q ';
+ }
+ }
+ $s.= ' Q ';
+ }
+ else { // If "border", does not come from WriteFlowingBlock or FinishFlowingBlock
+ if ($fill==1) $op=($border==1) ? 'B' : 'f';
+ else $op='S';
+ $s.=sprintf('%.3F %.3F %.3F %.3F re %s ',$this->x*_MPDFK,($this->h-$bg_boxtop)*_MPDFK,$w*_MPDFK,-$bg_boxheight*_MPDFK,$op);
+ }
+ }
+
+ if(is_string($border)) { // If "border", does not come from WriteFlowingBlock or FinishFlowingBlock
+ $x=$this->x;
+ $y=$this->y;
+ if(is_int(strpos($border,'L')))
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',$x*_MPDFK,($this->h-$bord_boxtop)*_MPDFK,$x*_MPDFK,($this->h-($bord_boxbottom))*_MPDFK);
+ if(is_int(strpos($border,'T')))
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',$x*_MPDFK,($this->h-$bord_boxtop)*_MPDFK,($x+$w)*_MPDFK,($this->h-$bord_boxtop)*_MPDFK);
+ if(is_int(strpos($border,'R')))
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',($x+$w)*_MPDFK,($this->h-$bord_boxtop)*_MPDFK,($x+$w)*_MPDFK,($this->h-($bord_boxbottom))*_MPDFK);
+ if(is_int(strpos($border,'B')))
+ $s.=sprintf('%.3F %.3F m %.3F %.3F l S ',$x*_MPDFK,($this->h-($bord_boxbottom))*_MPDFK,($x+$w)*_MPDFK,($this->h-($bord_boxbottom))*_MPDFK);
+ }
+
+ if($txt!='') {
+
+
+ if ($exactWidth)
+ $stringWidth = $w;
+ else
+ $stringWidth = $this->GetStringWidth($txt, true, $OTLdata, $textvar) + ( $this->charspacing * mb_strlen( $txt, $this->mb_enc )/_MPDFK )
+ + ( $this->ws * mb_substr_count( $txt, ' ', $this->mb_enc ) / _MPDFK );
+
+ // Set x OFFSET FOR PRINTING
+ if($align=='R') {
+ $dx=$w-$this->cMarginR - $stringWidth - $lcpaddingR;
+ }
+ elseif($align=='C') {
+ $dx=(($w - $stringWidth )/2);
+ }
+ elseif($align=='L' or $align=='J') $dx=$this->cMarginL + $lcpaddingL;
+ else $dx = 0;
+
+ if($this->ColorFlag) $s .='q '.$this->TextColor.' ';
+
+ // OUTLINE
+ if(isset($this->textparam['outline-s'] ) && $this->textparam['outline-s'] && !($textvar & FC_SMALLCAPS)) { // mPDF 5.7.1
+ $s .=' '.sprintf('%.3F w',$this->LineWidth*_MPDFK).' ';
+ $s .=" $this->DrawColor ";
+ $s .=" 2 Tr ";
+ }
+ else if ($this->falseBoldWeight && strpos($this->ReqFontStyle,"B") !== false && strpos($this->FontStyle,"B") === false && !($textvar & FC_SMALLCAPS)) { // can't use together with OUTLINE or Small Caps // mPDF 5.7.1 ??? why not with SmallCaps ???
+ $s .= ' 2 Tr 1 J 1 j ';
+ $s .= ' '.sprintf('%.3F w',($this->FontSize/130)*_MPDFK*$this->falseBoldWeight).' ';
+ $tc = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
+ if($this->FillColor!=$tc) { $s .= ' '.$tc.' '; } // stroke (outline) = same colour as text(fill)
+ }
+ else { $s .=" 0 Tr "; }
+
+ if (strpos($this->ReqFontStyle,"I") !== false && strpos($this->FontStyle,"I") === false) { // Artificial italic
+ $aix = '1 0 0.261799 1 %.3F %.3F Tm ';
+ }
+ else { $aix = '%.3F %.3F Td '; }
+
+ $px = ($this->x+$dx)*_MPDFK;
+ $py = ($this->h-($this->y+$glyphYorigin-$baseline_shift))*_MPDFK;
+
+ // THE TEXT
+ $txt2= $txt;
+ $sub = '';
+ $this->CurrentFont['used']= true;
+
+ /* *************** SIMILAR TO Text() ************************ */
+
+ // IF corefonts AND NOT SmCaps AND NOT Kerning
+ // Just output text; charspacing and wordspacing already set by charspacing (Tc) and ws (Tw)
+ if ($this->usingCoreFont && !($textvar & FC_SMALLCAPS) && !($textvar & FC_KERNING)) {
+ $txt2=$this->_escape($txt2);
+ $sub .=sprintf('BT '.$aix.' (%s) Tj ET',$px,$py,$txt2);
+ }
+
+
+ // IF NOT corefonts AND NO wordspacing AND NOT SIP/SMP AND NOT SmCaps AND NOT Kerning AND NOT OTL
+ // Just output text
+ else if (!$this->usingCoreFont && !$this->ws && !($textvar & FC_SMALLCAPS) && !($textvar & FC_KERNING) && !(isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF) && !empty($OTLdata['GPOSinfo']))) {
+ // IF SIP/SMP
+ if ((isset($this->CurrentFont['sip']) && $this->CurrentFont['sip']) || (isset($this->CurrentFont['smp']) && $this->CurrentFont['smp'])) {
+ $txt2 = $this->UTF8toSubset($txt2);
+ $sub .=sprintf('BT '.$aix.' %s Tj ET',$px,$py,$txt2);
+ }
+ // NOT SIP/SMP
+ else {
+ $txt2 = $this->UTF8ToUTF16BE($txt2, false);
+ $txt2=$this->_escape($txt2);
+ $sub .=sprintf('BT '.$aix.' (%s) Tj ET',$px,$py,$txt2);
+ }
+ }
+
+
+ // IF NOT corefonts AND IS wordspacing AND NOT SIP AND NOT SmCaps AND NOT Kerning AND NOT OTL
+ // Output text word by word with an adjustment to the intercharacter spacing for SPACEs to form word spacing
+ // IF multibyte - Tw has no effect - need to do word spacing using an adjustment before each space
+ else if (!$this->usingCoreFont && $this->ws && !((isset($this->CurrentFont['sip']) && $this->CurrentFont['sip']) || (isset($this->CurrentFont['smp']) && $this->CurrentFont['smp'])) && !($textvar & FC_SMALLCAPS) && !($textvar & FC_KERNING) && !(isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF) && (!empty($OTLdata['GPOSinfo']) || (strpos($OTLdata['group'],'M')!==false && $this->charspacing)) )) {
+ $space = " ";
+ $space= $this->UTF8ToUTF16BE($space, false);
+ $space=$this->_escape($space);
+ $sub .=sprintf('BT '.$aix.' %.3F Tc [',$px,$py, $this->charspacing);
+ $t = explode(' ',$txt2);
+ $numt = count($t);
+ for($i=0;$i<$numt;$i++) {
+ $tx = $t[$i];
+ $tx = $this->UTF8ToUTF16BE($tx , false);
+ $tx = $this->_escape($tx);
+ $sub .=sprintf('(%s) ',$tx);
+ if (($i+1)<$numt) {
+ $adj = -($this->ws)*1000/$this->FontSizePt;
+ $sub .=sprintf('%d(%s) ',$adj,$space);
+ }
+ }
+ $sub .='] TJ ';
+ $sub .=' ET';
+ }
+
+
+ // ELSE (IF SmCaps || Kerning || OTL) [corefonts or not corefonts; SIP or SMP or BMP]
+ else {
+ $sub = $this->applyGPOSpdf($txt, $aix, $px,$py, $OTLdata, $textvar );
+ }
+
+ /* *************** END SIMILAR TO Text() ************************ */
+
+ if ($this->shrin_k > 1) { $shrin_k = $this->shrin_k; }
+ else { $shrin_k = 1; }
+ // UNDERLINE
+ if($textvar & FD_UNDERLINE) { // mPDF 5.7.1 // mPDF 6
+ // mPDF 5.7.3 inline text-decoration parameters
+ $c = $this->textparam['u-decoration']['color'];
+ if($this->FillColor!=$c) { $sub .= ' '.$c.' '; }
+ // mPDF 5.7.3 inline text-decoration parameters
+ $decorationfontkey = $this->textparam['u-decoration']['fontkey'];
+ $decorationfontsize = $this->textparam['u-decoration']['fontsize'] / $shrin_k;
+ if (isset($this->fonts[$decorationfontkey]['ut']) && $this->fonts[$decorationfontkey]['ut']) { $ut=$this->fonts[$decorationfontkey]['ut']/1000* $decorationfontsize; }
+ else { $ut = 60/1000* $decorationfontsize; }
+ if (isset($this->fonts[$decorationfontkey]['up']) && $this->fonts[$decorationfontkey]['up']) { $up=$this->fonts[$decorationfontkey]['up']; }
+ else { $up = -100; }
+ $adjusty = (-$up/1000* $decorationfontsize) + $ut/2;
+ $ubaseline = $glyphYorigin - $this->textparam['u-decoration']['baseline'] / $shrin_k;
+ $olw = $this->LineWidth;
+ $sub .=' '.(sprintf(' %.3F w 0 j 0 J ',$ut*_MPDFK));
+ $sub .=' '.$this->_dounderline($this->x+$dx,$this->y+$ubaseline+$adjusty,$txt,$OTLdata,$textvar);
+ $sub .=' '.(sprintf(' %.3F w 2 j 2 J ',$olw*_MPDFK));
+ if($this->FillColor!=$c) { $sub .= ' '.$this->FillColor.' '; }
+ }
+
+ // STRIKETHROUGH
+ if($textvar & FD_LINETHROUGH) { // mPDF 5.7.1 // mPDF 6
+ // mPDF 5.7.3 inline text-decoration parameters
+ $c = $this->textparam['s-decoration']['color'];
+ if($this->FillColor!=$c) { $sub .= ' '.$c.' '; }
+ // mPDF 5.7.3 inline text-decoration parameters
+ $decorationfontkey = $this->textparam['s-decoration']['fontkey'];
+ $decorationfontsize = $this->textparam['s-decoration']['fontsize'] / $shrin_k;
+ // Use yStrikeoutSize from OS/2 if available
+ if (isset($this->fonts[$decorationfontkey]['strs']) && $this->fonts[$decorationfontkey]['strs']) { $ut=$this->fonts[$decorationfontkey]['strs']/1000* $decorationfontsize; }
+ // else use underlineThickness from post if available
+ else if (isset($this->fonts[$decorationfontkey]['ut']) && $this->fonts[$decorationfontkey]['ut']) { $ut=$this->fonts[$decorationfontkey]['ut']/1000* $decorationfontsize; }
+ else { $ut = 50/1000* $decorationfontsize; }
+ // Use yStrikeoutPosition from OS/2 if available
+ if (isset($this->fonts[$decorationfontkey]['strp']) && $this->fonts[$decorationfontkey]['strp']) {
+ $up=$this->fonts[$decorationfontkey]['strp'];
+ $adjusty = (-$up/1000* $decorationfontsize);
+ }
+ // else use a fraction ($this->baselineS) of CapHeight
+ else {
+ if (isset($this->fonts[$decorationfontkey]['desc']['CapHeight']) && $this->fonts[$decorationfontkey]['desc']['CapHeight']) { $ch=$this->fonts[$decorationfontkey]['desc']['CapHeight']; }
+ else { $ch = 700; }
+ $adjusty = (-$ch/1000* $decorationfontsize) * $this->baselineS;
+ }
+
+ $sbaseline = $glyphYorigin - $this->textparam['s-decoration']['baseline'] / $shrin_k;
+ $olw = $this->LineWidth;
+ $sub .=' '.(sprintf(' %.3F w 0 j 0 J ',$ut*_MPDFK));
+ $sub .=' '.$this->_dounderline($this->x+$dx,$this->y+$sbaseline+$adjusty,$txt,$OTLdata,$textvar);
+ $sub .=' '.(sprintf(' %.3F w 2 j 2 J ',$olw*_MPDFK));
+ if($this->FillColor!=$c) { $sub .= ' '.$this->FillColor.' '; }
+ }
+
+ // mPDF 5.7.3 inline text-decoration parameters
+ // OVERLINE
+ if($textvar & FD_OVERLINE) { // mPDF 5.7.1 // mPDF 6
+ // mPDF 5.7.3 inline text-decoration parameters
+ $c = $this->textparam['o-decoration']['color'];
+ if($this->FillColor!=$c) { $sub .= ' '.$c.' '; }
+ // mPDF 5.7.3 inline text-decoration parameters
+ $decorationfontkey = $this->textparam['o-decoration']['fontkey'] / $shrin_k;
+ $decorationfontsize = $this->textparam['o-decoration']['fontsize'];
+ if (isset($this->fonts[$decorationfontkey]['ut']) && $this->fonts[$decorationfontkey]['ut']) { $ut=$this->fonts[$decorationfontkey]['ut']/1000* $decorationfontsize; }
+ else { $ut = 60/1000* $decorationfontsize; }
+ if (isset($this->fonts[$decorationfontkey]['desc']['CapHeight']) && $this->fonts[$decorationfontkey]['desc']['CapHeight']) { $ch=$this->fonts[$decorationfontkey]['desc']['CapHeight']; }
+ else { $ch = 700; }
+ $adjusty = (-$ch/1000* $decorationfontsize) * $this->baselineO;
+ $obaseline = $glyphYorigin - $this->textparam['o-decoration']['baseline'] / $shrin_k;
+ $olw = $this->LineWidth;
+ $sub .=' '.(sprintf(' %.3F w 0 j 0 J ',$ut*_MPDFK));
+ $sub .=' '.$this->_dounderline($this->x+$dx,$this->y+$obaseline+$adjusty,$txt,$OTLdata,$textvar);
+ $sub .=' '.(sprintf(' %.3F w 2 j 2 J ',$olw*_MPDFK));
+ if($this->FillColor!=$c) { $sub .= ' '.$this->FillColor.' '; }
+ }
+
+ // TEXT SHADOW
+ if ($this->textshadow) { // First to process is last in CSS comma separated shadows
+ foreach($this->textshadow AS $ts) {
+ $s .= ' q ';
+ $s .= $this->SetTColor($ts['col'], true)."\n";
+ if ($ts['col']{0}==5 && ord($ts['col']{4})<100) { // RGBa
+ $s .= $this->SetAlpha(ord($ts['col']{4})/100, 'Normal', true, 'F')."\n";
+ }
+ else if ($ts['col']{0}==6 && ord($ts['col']{5})<100) { // CMYKa
+ $s .= $this->SetAlpha(ord($ts['col']{5})/100, 'Normal', true, 'F')."\n";
+ }
+ else if ($ts['col']{0}==1 && $ts['col']{2}==1 && ord($ts['col']{3})<100) { // Gray
+ $s .= $this->SetAlpha(ord($ts['col']{3})/100, 'Normal', true, 'F')."\n";
+ }
+ $s .= sprintf(' 1 0 0 1 %.4F %.4F cm', $ts['x']*_MPDFK, -$ts['y']*_MPDFK)."\n";
+ $s .= $sub;
+ $s .= ' Q ';
+ }
+ }
+
+ $s .= $sub;
+
+ // COLOR
+ if($this->ColorFlag) $s .=' Q';
+
+ // LINK
+ if($link!='') {
+ $this->Link($this->x,$boxtop,$w,$boxheight,$link);
+ }
+ }
+ if($s) $this->_out($s);
+
+ // WORD SPACING
+ if ($this->ws && !$this->usingCoreFont) {
+ $this->_out(sprintf('BT %.3F Tc ET',$this->charspacing));
+ }
+ $this->lasth=$h;
+ if( strpos($txt,"\n") !== false) $ln=1; // cell recognizes \n from tag
+ if($ln>0)
+ {
+ //Go to next line
+ $this->y += $h;
+ if($ln==1) {
+ //Move to next line
+ if ($currentx != 0) { $this->x=$currentx; }
+ else { $this->x=$this->lMargin; }
+ }
+ }
+ else $this->x+=$w;
+
+
+}
+
+
+function applyGPOSpdf($txt, $aix, $x, $y, $OTLdata, $textvar=0 ) {
+ // Generate PDF string
+ //==============================
+ if ((isset($this->CurrentFont['sip']) && $this->CurrentFont['sip']) || (isset($this->CurrentFont['smp']) && $this->CurrentFont['smp'])) { $sipset = true; }
+ else { $sipset = false; }
+
+ if ($textvar & FC_SMALLCAPS) { $smcaps = true; } // IF SmallCaps using transformation, NOT OTL
+ else { $smcaps = false; }
+
+ if ($sipset) {
+ $fontid = $last_fontid = $original_fontid = $this->CurrentFont['subsetfontids'][0];
+ }
+ else {
+ $fontid = $last_fontid = $original_fontid = $this->CurrentFont['i'];
+ }
+ $SmallCapsON = false; // state: uppercase/not
+ $lastSmallCapsON = false; // state: uppercase/not
+ $last_fontsize = $fontsize = $this->FontSizePt;
+ $last_fontstretch = $fontstretch = 100;
+ $groupBreak = false;
+
+ $unicode = $this->UTF8StringToArray($txt);
+
+ $GPOSinfo = (isset($OTLdata['GPOSinfo']) ? $OTLdata['GPOSinfo'] : array());
+ $charspacing = ($this->charspacing * 1000 / $this->FontSizePt);
+ $wordspacing = ($this->ws * 1000 / $this->FontSizePt);
+
+ $XshiftBefore = 0;
+ $XshiftAfter = 0;
+ $lastYPlacement = 0;
+
+ if ($sipset) {
+ // mPDF 6 DELETED ********
+// $txt= preg_replace('/'.preg_quote($this->aliasNbPg,'/').'/', chr(7), $txt); // ? Need to adjust OTL info
+// $txt= preg_replace('/'.preg_quote($this->aliasNbPgGp,'/').'/', chr(8), $txt); // ? Need to adjust OTL info
+ $tj = '<';
+ }
+ else {
+ $tj = '(';
+ }
+
+ for($i=0;$iFontSizePt / $this->CurrentFont['unitsPerEm'];
+ $groupBreak = true;
+
+ }
+ // XPlacement from GPOS
+ if (isset($GPOSinfo[$i]['XPlacement']) && $GPOSinfo[$i]['XPlacement']) {
+
+ if (!isset($GPOSinfo[$i]['wDir']) || $GPOSinfo[$i]['wDir'] != 'RTL') {
+ if (isset($GPOSinfo[$i]['BaseWidth'])) {
+ $GPOSinfo[$i]['XPlacement'] -= $GPOSinfo[$i]['BaseWidth'];
+ }
+ }
+
+ // Convert to PDF Text space (thousandths of a unit );
+ $XshiftBefore += $GPOSinfo[$i]['XPlacement'] * 1000 / $this->CurrentFont['unitsPerEm'];
+ $XshiftAfter += -$GPOSinfo[$i]['XPlacement'] * 1000 / $this->CurrentFont['unitsPerEm'];
+ }
+
+ // Kashida from GPOS
+ // Kashida is set as an absolute length value, but to adjust text needs to be converted to
+ // font-related size
+ if (isset($GPOSinfo[$i]['kashida_space']) && $GPOSinfo[$i]['kashida_space']) {
+ $kashida = $GPOSinfo[$i]['kashida_space'];
+ }
+
+ if ($c==32) { // word spacing
+ $XshiftAfter += $wordspacing;
+ }
+
+ if (substr($OTLdata['group'],($i+1),1)!='M') { // Don't add inter-character spacing before Marks
+ $XshiftAfter += $charspacing;
+ }
+
+ // ...applyGPOSpdf...
+ // XAdvance from GPOS - Convert to PDF Text space (thousandths of a unit );
+ if (((isset($GPOSinfo[$i]['wDir']) && $GPOSinfo[$i]['wDir'] != 'RTL') || !isset($GPOSinfo[$i]['wDir'])) && isset($GPOSinfo[$i]['XAdvanceL']) && $GPOSinfo[$i]['XAdvanceL']) {
+ $XshiftAfter += $GPOSinfo[$i]['XAdvanceL'] * 1000 / $this->CurrentFont['unitsPerEm'];
+ }
+ else if (isset($GPOSinfo[$i]['wDir']) && $GPOSinfo[$i]['wDir'] == 'RTL' && isset($GPOSinfo[$i]['XAdvanceR']) && $GPOSinfo[$i]['XAdvanceR']) {
+ $XshiftAfter += $GPOSinfo[$i]['XAdvanceR'] * 1000 / $this->CurrentFont['unitsPerEm'];
+ }
+ }
+ // Character & Word spacing - if NOT OTL
+ else {
+ $XshiftAfter += $charspacing;
+ if ($c==32) { $XshiftAfter += $wordspacing; }
+ }
+
+ // IF Kerning done using pairs rather than OTL
+ if ($textvar & FC_KERNING) {
+ if ($i > 0 && isset($this->CurrentFont['kerninfo'][$unicode[($i-1)]][$unicode[$i]])) {
+ $XshiftBefore += $this->CurrentFont['kerninfo'][$unicode[($i-1)]][$unicode[$i]];
+ }
+ }
+
+ if ($YPlacement != $lastYPlacement) { $groupBreak = true; }
+
+ if ($XshiftBefore) { // +ve value in PDF moves to the left
+ // If Fontstretch is ongoing, need to adjust X adjustments because these will be stretched out.
+ $XshiftBefore *= 100/$last_fontstretch;
+ if ($sipset) { $tj .= sprintf('>%d<',(-$XshiftBefore) ); }
+ else { $tj .= sprintf(')%d(',(-$XshiftBefore) ); }
+ }
+
+ // Small-Caps
+ if ($smcaps) {
+ if (isset($this->upperCase[$c])) {
+ $c = $this->upperCase[$c];
+ //$this->CurrentFont['subset'][$this->upperCase[$c]] = $this->upperCase[$c]; // add the CAP to subset
+ $SmallCapsON = true;
+ // For $sipset
+ if (!$lastSmallCapsON) { // Turn ON SmallCaps
+ $groupBreak = true;
+ $fontstretch = $this->smCapsStretch;
+ $fontsize=$this->FontSizePt*$this->smCapsScale;
+ }
+ }
+ else {
+ $SmallCapsON = false;
+ if ($lastSmallCapsON) { // Turn OFF SmallCaps
+ $groupBreak = true;
+ $fontstretch = 100;
+ $fontsize=$this->FontSizePt;
+ }
+ }
+ }
+
+ // Prepare Text and Select Font ID
+ if ($sipset) {
+ // mPDF 6 DELETED ********
+ //if ($c == 7 || $c == 8) {
+ // if ($original_fontid != $last_fontid) {
+ // $groupBreak = true;
+ // $fontid = $original_fontid;
+ // }
+ // if ($c == 7) { $tj .= $this->aliasNbPgHex; }
+ // else { $tj .= $this->aliasNbPgGpHex; }
+ // continue;
+ //}
+ for ($j=0; $j<99; $j++) {
+ $init = array_search($c, $this->CurrentFont['subsets'][$j]);
+ if ($init!==false) {
+ if ($this->CurrentFont['subsetfontids'][$j] != $last_fontid) {
+ $groupBreak = true;
+ $fontid = $this->CurrentFont['subsetfontids'][$j];
+ }
+ $tx = sprintf("%02s", strtoupper(dechex($init)));
+ break;
+ }
+ else if (count($this->CurrentFont['subsets'][$j]) < 255) {
+ $n = count($this->CurrentFont['subsets'][$j]);
+ $this->CurrentFont['subsets'][$j][$n] = $c;
+ if ($this->CurrentFont['subsetfontids'][$j] != $last_fontid) {
+ $groupBreak = true;
+ $fontid = $this->CurrentFont['subsetfontids'][$j];
+ }
+ $tx = sprintf("%02s", strtoupper(dechex($n)));
+ break;
+ }
+ else if (!isset($this->CurrentFont['subsets'][($j+1)])) {
+ $this->CurrentFont['subsets'][($j+1)] = array(0=>0);
+ $this->CurrentFont['subsetfontids'][($j+1)] = count($this->fonts)+$this->extraFontSubsets+1;
+ $this->extraFontSubsets++;
+ }
+ }
+ }
+ else {
+ $tx = code2utf($c);
+ if ($this->usingCoreFont) {
+ $tx = utf8_decode($tx);
+ }
+ else {
+ $tx = $this->UTF8ToUTF16BE($tx, false);
+ }
+ $tx = $this->_escape($tx);
+ }
+
+ // If any settings require a new Text Group
+ if ($groupBreak || $fontstretch != $last_fontstretch) {
+ if ($sipset) { $tj .= '>] TJ '; }
+ else { $tj .= ')] TJ '; }
+ if ($fontid != $last_fontid || $fontsize != $last_fontsize) { $tj .= sprintf(' /F%d %.3F Tf ', $fontid , $fontsize); }
+ if ($fontstretch != $last_fontstretch) { $tj .= sprintf('%d Tz ', $fontstretch); }
+ if ($YPlacement != $lastYPlacement) { $tj .= sprintf('%.3F Ts ', $YPlacement); }
+ if ($sipset) { $tj .= '[<'; }
+ else { $tj .= '[('; }
+ }
+
+ // Output the code for the txt character
+ $tj .= $tx;
+ $lastSmallCapsON = $SmallCapsON;
+ $last_fontid = $fontid;
+ $last_fontsize = $fontsize;
+ $last_fontstretch = $fontstretch ;
+
+ // Kashida
+ if ($kashida) {
+ $c = 0x0640; // add the Tatweel U+0640
+ if (isset($this->CurrentFont['subset'])) {
+ $this->CurrentFont['subset'][$c] = $c;
+ }
+ $kashida *= 1000 / $this->FontSizePt;
+ $tatw = $this->_getCharWidth($this->CurrentFont['cw'], 0x0640);
+
+ // Get YPlacement from next Base character
+ $nextbase = $i+1;
+ while($OTLdata['group']{$nextbase}!='C') { $nextbase++; }
+ if (isset($GPOSinfo[$nextbase]) && isset($GPOSinfo[$nextbase]['YPlacement']) && $GPOSinfo[$nextbase]['YPlacement']) {
+ $YPlacement = $GPOSinfo[$nextbase]['YPlacement'] * $this->FontSizePt / $this->CurrentFont['unitsPerEm'];
+ }
+
+ // Prepare Text and Select Font ID
+ if ($sipset) {
+ for ($j=0; $j<99; $j++) {
+ $init = array_search($c, $this->CurrentFont['subsets'][$j]);
+ if ($init!==false) {
+ if ($this->CurrentFont['subsetfontids'][$j] != $last_fontid) {
+ $fontid = $this->CurrentFont['subsetfontids'][$j];
+ }
+ $tx = sprintf("%02s", strtoupper(dechex($init)));
+ break;
+ }
+ else if (count($this->CurrentFont['subsets'][$j]) < 255) {
+ $n = count($this->CurrentFont['subsets'][$j]);
+ $this->CurrentFont['subsets'][$j][$n] = $c;
+ if ($this->CurrentFont['subsetfontids'][$j] != $last_fontid) {
+ $fontid = $this->CurrentFont['subsetfontids'][$j];
+ }
+ $tx = sprintf("%02s", strtoupper(dechex($n)));
+ break;
+ }
+ else if (!isset($this->CurrentFont['subsets'][($j+1)])) {
+ $this->CurrentFont['subsets'][($j+1)] = array(0=>0);
+ $this->CurrentFont['subsetfontids'][($j+1)] = count($this->fonts)+$this->extraFontSubsets+1;
+ $this->extraFontSubsets++;
+ }
+ }
+ }
+ else {
+ $tx = code2utf($c);
+ $tx = $this->UTF8ToUTF16BE($tx, false);
+ $tx = $this->_escape($tx);
+ }
+
+ if ($kashida > $tatw) {
+ // Insert multiple tatweel characters, repositioning the last one to give correct total length
+ $fontstretch = 100;
+ $nt = intval($kashida / $tatw);
+ $nudgeback = (($nt+1)*$tatw) - $kashida;
+ $optx = str_repeat($tx, $nt);
+ if ($sipset) { $optx .= sprintf('>%d<',($nudgeback) ); }
+ else { $optx .= sprintf(')%d(',($nudgeback) ); }
+ $optx .= $tx; // #last
+ }
+ else {
+ // Insert single tatweel character and use fontstretch to get correct length
+ $fontstretch = ($kashida / $tatw) * 100;
+ $optx = $tx;
+ }
+
+ if ($sipset) { $tj .= '>] TJ '; }
+ else { $tj .= ')] TJ '; }
+ if ($fontid != $last_fontid || $fontsize != $last_fontsize) { $tj .= sprintf(' /F%d %.3F Tf ', $fontid , $fontsize); }
+ if ($fontstretch != $last_fontstretch) { $tj .= sprintf('%d Tz ', $fontstretch); }
+ $tj .= sprintf('%.3F Ts ', $YPlacement);
+ if ($sipset) { $tj .= '[<'; }
+ else { $tj .= '[('; }
+
+ // Output the code for the txt character(s)
+ $tj .= $optx;
+ $last_fontid = $fontid;
+ $last_fontstretch = $fontstretch ;
+ $fontstretch = 100;
+ }
+
+ $lastYPlacement = $YPlacement;
+
+ }
+
+
+ // Finish up
+ if ($sipset) {
+ $tj .= '>';
+ if ($XshiftAfter) { $tj .= sprintf('%d',(-$XshiftAfter) ); }
+ if ($last_fontid != $original_fontid) {
+ $tj .= '] TJ ';
+ $tj .= sprintf(' /F%d %.3F Tf ', $original_fontid, $fontsize);
+ $tj .= '[';
+ }
+ $tj = preg_replace('/([^\\\])<>/', '\\1 ', $tj);
+ }
+ else {
+ $tj .= ')';
+ if ($XshiftAfter) { $tj .= sprintf('%d',(-$XshiftAfter) ); }
+ if ($last_fontid != $original_fontid) {
+ $tj .= '] TJ ';
+ $tj .= sprintf(' /F%d %.3F Tf ', $original_fontid, $fontsize);
+ $tj .= '[';
+ }
+ $tj = preg_replace('/([^\\\])\(\)/', '\\1 ', $tj);
+ }
+
+
+ $s = sprintf(' BT '.$aix.' 0 Tc 0 Tw [%s] TJ ET ', $x, $y, $tj);
+
+//echo $s."\n\n"; // exit;
+
+ return $s;
+}
+
+function _kern($txt, $mode, $aix, $x, $y) {
+ if ($mode == 'MBTw') { // Multibyte requiring word spacing
+ $space = ' ';
+ //Convert string to UTF-16BE without BOM
+ $space= $this->UTF8ToUTF16BE($space , false);
+ $space=$this->_escape($space );
+ $s = sprintf(' BT '.$aix,$x*_MPDFK,($this->h-$y)*_MPDFK);
+ $t = explode(' ',$txt);
+ for($i=0;$iUTF8StringToArray($tx);
+ for($ti=0;$ti 0 && isset($this->CurrentFont['kerninfo'][$unicode[($ti-1)]][$unicode[$ti]])) {
+ $kern = -$this->CurrentFont['kerninfo'][$unicode[($ti-1)]][$unicode[$ti]];
+ $tj .= sprintf(')%d(',$kern);
+ }
+ $tc = code2utf($unicode[$ti]);
+ $tc = $this->UTF8ToUTF16BE($tc, false);
+ $tj .= $this->_escape($tc);
+ }
+ $tj .= ')';
+ $s.=sprintf(' %.3F Tc [%s] TJ',$this->charspacing,$tj);
+
+
+ if (($i+1)ws+$this->charspacing,$space);
+ }
+ }
+ $s.=' ET ';
+ }
+ else if (!$this->usingCoreFont) {
+ $s = '';
+ $tj = '(';
+ $unicode = $this->UTF8StringToArray($txt);
+ for($i=0;$i 0 && isset($this->CurrentFont['kerninfo'][$unicode[($i-1)]][$unicode[$i]])) {
+ $kern = -$this->CurrentFont['kerninfo'][$unicode[($i-1)]][$unicode[$i]];
+ $tj .= sprintf(')%d(',$kern);
+ }
+ $tx = code2utf($unicode[$i]);
+ $tx = $this->UTF8ToUTF16BE($tx, false);
+ $tj .= $this->_escape($tx);
+ }
+ $tj .= ')';
+ $s.=sprintf(' BT '.$aix.' [%s] TJ ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$tj);
+ }
+ else { // CORE Font
+ $s = '';
+ $tj = '(';
+ $l = strlen($txt);
+ for($i=0;$i<$l;$i++) {
+ if ($i > 0 && isset($this->CurrentFont['kerninfo'][$txt[($i-1)]][$txt[$i]])) {
+ $kern = -$this->CurrentFont['kerninfo'][$txt[($i-1)]][$txt[$i]];
+ $tj .= sprintf(')%d(',$kern);
+ }
+ $tj .= $this->_escape($txt[$i]);
+ }
+ $tj .= ')';
+ $s.=sprintf(' BT '.$aix.' [%s] TJ ET ',$x*_MPDFK,($this->h-$y)*_MPDFK,$tj);
+ }
+
+ return $s;
+}
+
+
+
+
+function MultiCell($w,$h,$txt,$border=0,$align='',$fill=0,$link='',$directionality='ltr',$encoded=false, $OTLdata=false, $maxrows=false)
+{
+ // maxrows is called from mpdfform->TEXTAREA
+ // Parameter (pre-)encoded - When called internally from form::textarea - mb_encoding already done and OTL - but not reverse RTL
+ if (!$encoded) {
+ $txt = $this->purify_utf8_text($txt);
+ if ($this->text_input_as_HTML) {
+ $txt = $this->all_entities_to_utf8($txt);
+ }
+ if ($this->usingCoreFont) { $txt = mb_convert_encoding($txt,$this->mb_enc,'UTF-8'); }
+ if (preg_match("/([".$this->pregRTLchars."])/u", $txt)) { $this->biDirectional = true; } // *OTL*
+/*-- OTL --*/
+ $OTLdata = array();
+ // Use OTL OpenType Table Layout - GSUB & GPOS
+ if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
+ $txt = $this->otl->applyOTL($txt, $this->CurrentFont['useOTL']);
+ $OTLdata = $this->otl->OTLdata;
+ }
+ if ($directionality == 'rtl' || $this->biDirectional) {
+ if (!isset($OTLdata)) {
+ $unicode = $this->UTF8StringToArray($txt, false);
+ $is_strong = false;
+ $this->getBasicOTLdata($OTLdata, $unicode, $is_strong);
+ }
+ }
+/*-- END OTL --*/
+ }
+ if (!$align) { $align = $this->defaultAlign; }
+
+ //Output text with automatic or explicit line breaks
+ $cw=&$this->CurrentFont['cw'];
+ if($w==0) $w=$this->w-$this->rMargin-$this->x;
+
+ $wmax = ($w - ($this->cMarginL+$this->cMarginR));
+ if ($this->usingCoreFont) {
+ $s=str_replace("\r",'',$txt);
+ $nb=strlen($s);
+ while($nb>0 and $s[$nb-1]=="\n") $nb--;
+ }
+ else {
+ $s=str_replace("\r",'',$txt);
+ $nb=mb_strlen($s, $this->mb_enc );
+ while($nb>0 and mb_substr($s,$nb-1,1,$this->mb_enc )=="\n") $nb--;
+ }
+ $b=0;
+ if($border) {
+ if($border==1) {
+ $border='LTRB';
+ $b='LRT';
+ $b2='LR';
+ }
+ else {
+ $b2='';
+ if(is_int(strpos($border,'L'))) $b2.='L';
+ if(is_int(strpos($border,'R'))) $b2.='R';
+ $b=is_int(strpos($border,'T')) ? $b2.'T' : $b2;
+ }
+ }
+ $sep=-1;
+ $i=0;
+ $j=0;
+ $l=0;
+ $ns=0;
+ $nl=1;
+
+ $rows = 0;
+ $start_y = $this->y;
+
+ if (!$this->usingCoreFont) {
+ $inclCursive=false;
+ if (preg_match("/([".$this->pregCURSchars."])/u", $s)) { $inclCursive = true; }
+ while($i<$nb) {
+ //Get next character
+ $c = mb_substr($s,$i,1,$this->mb_enc );
+ if($c == "\n") {
+ //Explicit line break
+ // WORD SPACING
+ $this->ResetSpacing();
+ $tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc));
+ $tmpOTLdata = false;
+/*-- OTL --*/
+ if (isset($OTLdata)) {
+ $tmpOTLdata = $this->otl->sliceOTLdata($OTLdata, $j, $i-$j);
+ $this->otl->trimOTLdata($tmpOTLdata, false, true);
+ $this->magic_reverse_dir($tmp, $directionality, $tmpOTLdata);
+ }
+/*-- END OTL --*/
+ $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link,0,0,0,'M', 0, false, $tmpOTLdata);
+ if ($maxrows!=false && isset($this->mpdfform) && ($this->y - $start_y) / $h > $maxrows) { return false; }
+ $i++;
+ $sep=-1;
+ $j=$i;
+ $l=0;
+ $ns=0;
+ $nl++;
+ if($border and $nl==2) $b=$b2;
+ continue;
+ }
+ if($c == " ") {
+ $sep=$i;
+ $ls=$l;
+ $ns++;
+ }
+
+ $l += $this->GetCharWidthNonCore($c);
+
+ if($l>$wmax) {
+ //Automatic line break
+ if($sep==-1) { // Only one word
+ if($i==$j) $i++;
+ // WORD SPACING
+ $this->ResetSpacing();
+ $tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc));
+ $tmpOTLdata = false;
+/*-- OTL --*/
+ if (isset($OTLdata)) {
+ $tmpOTLdata = $this->otl->sliceOTLdata($OTLdata, $j, $i-$j);
+ $this->otl->trimOTLdata($tmpOTLdata, false, true);
+ $this->magic_reverse_dir($tmp, $directionality, $tmpOTLdata);
+ }
+/*-- END OTL --*/
+ $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link,0,0,0,'M', 0, false, $tmpOTLdata);
+ }
+ else {
+ $tmp = rtrim(mb_substr($s,$j,$sep-$j,$this->mb_enc));
+ $tmpOTLdata = false;
+/*-- OTL --*/
+ if (isset($OTLdata)) {
+ $tmpOTLdata = $this->otl->sliceOTLdata($OTLdata, $j, $sep-$j);
+ $this->otl->trimOTLdata($tmpOTLdata, false, true);
+ }
+/*-- END OTL --*/
+ if($align=='J') {
+ //////////////////////////////////////////
+ // JUSTIFY J using Unicode fonts (Word spacing doesn't work)
+ // WORD SPACING UNICODE
+ // Change NON_BREAKING SPACE to spaces so they are 'spaced' properly
+ $tmp = str_replace(chr(194).chr(160),chr(32),$tmp );
+ $len_ligne = $this->GetStringWidth($tmp, false, $tmpOTLdata);
+ $nb_carac = mb_strlen( $tmp , $this->mb_enc ) ;
+ $nb_spaces = mb_substr_count( $tmp ,' ', $this->mb_enc ) ;
+ // Take off number of Marks
+ // Use GPOS OTL
+ if (isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'])) {
+ if (isset($tmpOTLdata['group']) && $tmpOTLdata['group']) {
+ $nb_carac -= substr_count($tmpOTLdata['group'], 'M');
+ }
+ }
+
+ list($charspacing,$ws,$kashida) = $this->GetJspacing($nb_carac,$nb_spaces,((($wmax) - $len_ligne) * _MPDFK),$inclCursive, $tmpOTLdata);
+ $this->SetSpacing($charspacing,$ws);
+ //////////////////////////////////////////
+ }
+ if (isset($OTLdata)) {
+ $this->magic_reverse_dir($tmp, $directionality, $tmpOTLdata);
+ }
+ $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link,0,0,0,'M', 0, false, $tmpOTLdata);
+ $i=$sep+1;
+ }
+ if ($maxrows!=false && isset($this->mpdfform) && ($this->y - $start_y) / $h > $maxrows) { return false; }
+ $sep=-1;
+ $j=$i;
+ $l=0;
+ $ns=0;
+ $nl++;
+ if($border and $nl==2) $b=$b2;
+ }
+ else $i++;
+ }
+ //Last chunk
+ // WORD SPACING
+
+ $this->ResetSpacing();
+
+ }
+
+
+ else {
+
+ while($i<$nb) {
+ //Get next character
+ $c=$s[$i];
+ if($c == "\n") {
+ //Explicit line break
+ // WORD SPACING
+ $this->ResetSpacing();
+ $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link);
+ if ($maxrows!=false && isset($this->mpdfform) && ($this->y - $start_y) / $h > $maxrows) { return false; }
+ $i++;
+ $sep=-1;
+ $j=$i;
+ $l=0;
+ $ns=0;
+ $nl++;
+ if($border and $nl==2) $b=$b2;
+ continue;
+ }
+ if($c == " ") {
+ $sep=$i;
+ $ls=$l;
+ $ns++;
+ }
+
+ $l += $this->GetCharWidthCore($c);
+ if($l>$wmax) {
+ //Automatic line break
+ if($sep==-1) {
+ if($i==$j) $i++;
+ // WORD SPACING
+ $this->ResetSpacing();
+ $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link);
+ }
+ else {
+ if($align=='J') {
+ $tmp = rtrim(substr($s,$j,$sep-$j));
+ //////////////////////////////////////////
+ // JUSTIFY J using Unicode fonts (Word spacing doesn't work)
+ // WORD SPACING NON_UNICODE/CJK
+ // Change NON_BREAKING SPACE to spaces so they are 'spaced' properly
+ $tmp = str_replace(chr(160),chr(32),$tmp);
+ $len_ligne = $this->GetStringWidth($tmp );
+ $nb_carac = strlen( $tmp ) ;
+ $nb_spaces = substr_count( $tmp ,' ' ) ;
+ $tmpOTLdata = array();
+ list($charspacing,$ws,$kashida) = $this->GetJspacing($nb_carac,$nb_spaces,((($wmax) - $len_ligne) * _MPDFK),false, $tmpOTLdata);
+ $this->SetSpacing($charspacing,$ws);
+ //////////////////////////////////////////
+ }
+ $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill,$link);
+ $i=$sep+1;
+ }
+ if ($maxrows!=false && isset($this->mpdfform) && ($this->y - $start_y) / $h > $maxrows) { return false; }
+ $sep=-1;
+ $j=$i;
+ $l=0;
+ $ns=0;
+ $nl++;
+ if($border and $nl==2) $b=$b2;
+ }
+ else $i++;
+ }
+ //Last chunk
+ // WORD SPACING
+
+ $this->ResetSpacing();
+
+ }
+ //Last chunk
+ if($border and is_int(strpos($border,'B'))) $b.='B';
+ if (!$this->usingCoreFont) {
+ $tmp = rtrim(mb_substr($s,$j,$i-$j,$this->mb_enc));
+ $tmpOTLdata = false;
+/*-- OTL --*/
+ if (isset($OTLdata)) {
+ $tmpOTLdata = $this->otl->sliceOTLdata($OTLdata, $j, $i-$j);
+ $this->otl->trimOTLdata($tmpOTLdata, false, true);
+ $this->magic_reverse_dir($tmp, $directionality, $tmpOTLdata);
+ }
+/*-- END OTL --*/
+ $this->Cell($w,$h,$tmp,$b,2,$align,$fill,$link,0,0,0,'M', 0, false, $tmpOTLdata);
+ }
+ else { $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link); }
+ $this->x=$this->lMargin;
+}
+
+
+/*-- DIRECTW --*/
+function Write($h,$txt,$currentx=0,$link='',$directionality='ltr',$align='') {
+ if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
+ if (empty($this->directw)) { $this->directw = new directw($this); }
+ $this->directw->Write($h,$txt,$currentx,$link,$directionality,$align);
+}
+/*-- END DIRECTW --*/
+
+
+/*-- HTML-CSS --*/
+function saveInlineProperties() {
+ $saved = array();
+ $saved[ 'family' ] = $this->FontFamily;
+ $saved[ 'style' ] = $this->FontStyle;
+ $saved[ 'sizePt' ] = $this->FontSizePt;
+ $saved[ 'size' ] = $this->FontSize;
+ $saved[ 'HREF' ] = $this->HREF;
+ $saved[ 'textvar' ] = $this->textvar; // mPDF 5.7.1
+ $saved[ 'OTLtags' ] = $this->OTLtags; // mPDF 5.7.1
+ $saved[ 'textshadow' ] = $this->textshadow;
+ $saved[ 'linewidth' ] = $this->LineWidth;
+ $saved[ 'drawcolor' ] = $this->DrawColor;
+ $saved[ 'textparam' ] = $this->textparam;
+ $saved[ 'lSpacingCSS' ] = $this->lSpacingCSS;
+ $saved[ 'wSpacingCSS' ] = $this->wSpacingCSS;
+ $saved[ 'I' ] = $this->I;
+ $saved[ 'B' ] = $this->B;
+ $saved[ 'colorarray' ] = $this->colorarray;
+ $saved[ 'bgcolorarray' ] = $this->spanbgcolorarray;
+ $saved[ 'border' ] = $this->spanborddet;
+ $saved[ 'color' ] = $this->TextColor;
+ $saved[ 'bgcolor' ] = $this->FillColor;
+ $saved[ 'lang' ] = $this->currentLang;
+ $saved[ 'fontLanguageOverride' ] = $this->fontLanguageOverride; // mPDF 5.7.1
+ $saved[ 'display_off' ] = $this->inlineDisplayOff;
+
+ return $saved;
+}
+
+function restoreInlineProperties( &$saved) {
+ $FontFamily = $saved[ 'family' ];
+ $this->FontStyle = $saved[ 'style' ];
+ $this->FontSizePt = $saved[ 'sizePt' ];
+ $this->FontSize = $saved[ 'size' ];
+
+ $this->currentLang = $saved['lang'];
+ $this->fontLanguageOverride = $saved[ 'fontLanguageOverride' ]; // mPDF 5.7.1
+
+ $this->ColorFlag = ($this->FillColor != $this->TextColor); //Restore ColorFlag as well
+
+ $this->HREF = $saved[ 'HREF' ];
+ $this->textvar = $saved[ 'textvar' ]; // mPDF 5.7.1
+ $this->OTLtags = $saved[ 'OTLtags' ]; // mPDF 5.7.1
+ $this->textshadow = $saved[ 'textshadow' ];
+ $this->LineWidth = $saved[ 'linewidth' ];
+ $this->DrawColor = $saved[ 'drawcolor' ];
+ $this->textparam = $saved[ 'textparam' ];
+ $this->inlineDisplayOff = $saved['display_off'];
+
+ $this->lSpacingCSS = $saved[ 'lSpacingCSS' ];
+ if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
+ $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
+ }
+ else { $this->fixedlSpacing = false; }
+ $this->wSpacingCSS = $saved[ 'wSpacingCSS' ];
+ if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
+ $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
+ }
+ else { $this->minwSpacing = 0; }
+
+ $this->SetFont($FontFamily, $saved[ 'style' ],$saved[ 'sizePt' ],false);
+
+ $this->currentfontstyle = $saved[ 'style' ];
+ $this->currentfontsize = $saved[ 'sizePt' ];
+ $this->SetStylesArray(array('B'=>$saved[ 'B' ], 'I'=>$saved[ 'I' ])); // mPDF 5.7.1
+
+ $this->TextColor = $saved[ 'color' ];
+ $this->FillColor = $saved[ 'bgcolor' ];
+ $this->colorarray = $saved[ 'colorarray' ];
+ $cor = $saved[ 'colorarray' ];
+ if ($cor) $this->SetTColor($cor);
+ $this->spanbgcolorarray = $saved[ 'bgcolorarray' ];
+ $cor = $saved[ 'bgcolorarray' ];
+ if ($cor) $this->SetFColor($cor);
+ $this->spanborddet = $saved[ 'border' ];
+}
+
+
+
+// Used when ColActive for tables - updated to return first block with background fill OR borders
+function GetFirstBlockFill() {
+ // Returns the first blocklevel that uses a bgcolor fill
+ $startfill = 0;
+ for ($i=1;$i<=$this->blklvl;$i++) {
+ if ($this->blk[$i]['bgcolor'] || $this->blk[$i]['border_left']['w'] || $this->blk[$i]['border_right']['w'] || $this->blk[$i]['border_top']['w'] || $this->blk[$i]['border_bottom']['w'] ) {
+ $startfill = $i;
+ break;
+ }
+ }
+ return $startfill;
+}
+
+
+//-------------------------FLOWING BLOCK------------------------------------//
+//The following functions were originally written by Damon Kohler //
+//--------------------------------------------------------------------------//
+
+function saveFont() {
+ $saved = array();
+ $saved[ 'family' ] = $this->FontFamily;
+ $saved[ 'style' ] = $this->FontStyle;
+ $saved[ 'sizePt' ] = $this->FontSizePt;
+ $saved[ 'size' ] = $this->FontSize;
+ $saved[ 'curr' ] = &$this->CurrentFont;
+ $saved[ 'lang' ] = $this->currentLang; // mPDF 6
+ $saved[ 'color' ] = $this->TextColor;
+ $saved[ 'spanbgcolor' ] = $this->spanbgcolor;
+ $saved[ 'spanbgcolorarray' ] = $this->spanbgcolorarray;
+ $saved[ 'bord' ] = $this->spanborder;
+ $saved[ 'border' ] = $this->spanborddet;
+ $saved[ 'HREF' ] = $this->HREF;
+ $saved[ 'textvar' ] = $this->textvar; // mPDF 5.7.1
+ $saved[ 'textshadow' ] = $this->textshadow;
+ $saved[ 'linewidth' ] = $this->LineWidth;
+ $saved[ 'drawcolor' ] = $this->DrawColor;
+ $saved[ 'textparam' ] = $this->textparam;
+ $saved[ 'ReqFontStyle' ] = $this->ReqFontStyle;
+ $saved[ 'fixedlSpacing' ] = $this->fixedlSpacing;
+ $saved[ 'minwSpacing' ] = $this->minwSpacing;
+ return $saved;
+}
+
+function restoreFont( &$saved, $write=true) {
+ if (!isset($saved) || empty($saved)) return;
+
+ $this->FontFamily = $saved[ 'family' ];
+ $this->FontStyle = $saved[ 'style' ];
+ $this->FontSizePt = $saved[ 'sizePt' ];
+ $this->FontSize = $saved[ 'size' ];
+ $this->CurrentFont = &$saved[ 'curr' ];
+ $this->currentLang = $saved[ 'lang' ]; // mPDF 6
+ $this->TextColor = $saved[ 'color' ];
+ $this->spanbgcolor = $saved[ 'spanbgcolor' ];
+ $this->spanbgcolorarray = $saved[ 'spanbgcolorarray' ];
+ $this->spanborder = $saved[ 'bord' ];
+ $this->spanborddet = $saved[ 'border' ];
+ $this->ColorFlag = ($this->FillColor != $this->TextColor); //Restore ColorFlag as well
+ $this->HREF = $saved[ 'HREF' ];
+ $this->fixedlSpacing = $saved[ 'fixedlSpacing' ];
+ $this->minwSpacing = $saved[ 'minwSpacing' ];
+ $this->textvar = $saved[ 'textvar' ]; // mPDF 5.7.1
+ $this->textshadow = $saved[ 'textshadow' ];
+ $this->LineWidth = $saved[ 'linewidth' ];
+ $this->DrawColor = $saved[ 'drawcolor' ];
+ $this->textparam = $saved[ 'textparam' ];
+ if ($write) {
+ $this->SetFont($saved[ 'family' ],$saved[ 'style' ],$saved[ 'sizePt' ],true,true); // force output
+ $fontout = (sprintf('BT /F%d %.3F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
+ if($this->page>0 && ((isset($this->pageoutput[$this->page]['Font']) && $this->pageoutput[$this->page]['Font'] != $fontout) || !isset($this->pageoutput[$this->page]['Font']))) { $this->_out($fontout); }
+ $this->pageoutput[$this->page]['Font'] = $fontout;
+ }
+ else
+ $this->SetFont($saved[ 'family' ],$saved[ 'style' ],$saved[ 'sizePt' ],false);
+ $this->ReqFontStyle = $saved[ 'ReqFontStyle' ];
+}
+
+function newFlowingBlock( $w, $h, $a = '', $is_table = false, $blockstate = 0, $newblock=true, $blockdir='ltr', $table_draft=false)
+{
+ if (!$a) {
+ if ($blockdir=='rtl') { $a = 'R'; }
+ else { $a = 'L'; }
+ }
+ $this->flowingBlockAttr[ 'width' ] = ($w * _MPDFK);
+ // line height in user units
+ $this->flowingBlockAttr[ 'is_table' ] = $is_table;
+ $this->flowingBlockAttr[ 'table_draft' ] = $table_draft;
+ $this->flowingBlockAttr[ 'height' ] = $h;
+ $this->flowingBlockAttr[ 'lineCount' ] = 0;
+ $this->flowingBlockAttr[ 'align' ] = $a;
+ $this->flowingBlockAttr[ 'font' ] = array();
+ $this->flowingBlockAttr[ 'content' ] = array();
+ $this->flowingBlockAttr[ 'contentB' ] = array();
+ $this->flowingBlockAttr[ 'contentWidth' ] = 0;
+ $this->flowingBlockAttr[ 'blockstate' ] = $blockstate;
+
+ $this->flowingBlockAttr[ 'newblock' ] = $newblock;
+ $this->flowingBlockAttr[ 'valign' ] = 'M';
+ $this->flowingBlockAttr[ 'blockdir' ] = $blockdir;
+ $this->flowingBlockAttr[ 'cOTLdata' ] = array(); // mPDF 5.7.1
+ $this->flowingBlockAttr[ 'lastBidiText' ] = ''; // mPDF 5.7.1
+ if (!empty($this->otl)) { $this->otl->lastBidiStrongType=''; } // *OTL*
+
+}
+
+function finishFlowingBlock($endofblock=false, $next='') {
+ $currentx = $this->x;
+ //prints out the last chunk
+ $is_table = $this->flowingBlockAttr[ 'is_table' ];
+ $table_draft = $this->flowingBlockAttr[ 'table_draft' ];
+ $maxWidth =& $this->flowingBlockAttr[ 'width' ];
+ $stackHeight =& $this->flowingBlockAttr[ 'height' ];
+ $align =& $this->flowingBlockAttr[ 'align' ];
+ $content =& $this->flowingBlockAttr[ 'content' ];
+ $contentB =& $this->flowingBlockAttr[ 'contentB' ];
+ $font =& $this->flowingBlockAttr[ 'font' ];
+ $contentWidth =& $this->flowingBlockAttr[ 'contentWidth' ];
+ $lineCount =& $this->flowingBlockAttr[ 'lineCount' ];
+ $valign =& $this->flowingBlockAttr[ 'valign' ];
+ $blockstate = $this->flowingBlockAttr[ 'blockstate' ];
+
+ $cOTLdata =& $this->flowingBlockAttr[ 'cOTLdata' ]; // mPDF 5.7.1
+ $newblock = $this->flowingBlockAttr[ 'newblock' ];
+ $blockdir = $this->flowingBlockAttr['blockdir'];
+
+ // *********** BLOCK BACKGROUND COLOR *****************//
+ if ($this->blk[$this->blklvl]['bgcolor'] && !$is_table) {
+ $fill = 0;
+ }
+ else {
+ $this->SetFColor($this->ConvertColor(255));
+ $fill = 0;
+ }
+
+ $hanger = '';
+ // Always right trim!
+ // Right trim last content and adjust width if needed to justify (later)
+ if (isset($content[count($content)-1]) && preg_match('/[ ]+$/',$content[count($content)-1], $m)) {
+ $strip = strlen($m[0]);
+ $content[count($content)-1] = substr($content[count($content)-1],0,(strlen($content[count($content)-1])-$strip));
+/*-- OTL --*/
+ if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
+ $this->otl->trimOTLdata($cOTLdata[count($cOTLdata)-1], false, true);
+ }
+/*-- END OTL --*/
+ }
+
+ // the amount of space taken up so far in user units
+ $usedWidth = 0;
+
+ // COLS
+ $oldcolumn = $this->CurrCol;
+
+ if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
+
+ // Print out each chunk
+
+/*-- TABLES --*/
+ if ($is_table) {
+ $ipaddingL = 0;
+ $ipaddingR = 0;
+ $paddingL = 0;
+ $paddingR = 0;
+ }
+ else {
+/*-- END TABLES --*/
+ $ipaddingL = $this->blk[$this->blklvl]['padding_left'];
+ $ipaddingR = $this->blk[$this->blklvl]['padding_right'];
+ $paddingL = ($ipaddingL * _MPDFK);
+ $paddingR = ($ipaddingR * _MPDFK);
+ $this->cMarginL = $this->blk[$this->blklvl]['border_left']['w'];
+ $this->cMarginR = $this->blk[$this->blklvl]['border_right']['w'];
+
+ // Added mPDF 3.0 Float DIV
+ $fpaddingR = 0;
+ $fpaddingL = 0;
+/*-- CSS-FLOAT --*/
+ if (count($this->floatDivs)) {
+ list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
+ if ($r_exists) { $fpaddingR = $r_width; }
+ if ($l_exists) { $fpaddingL = $l_width; }
+ }
+/*-- END CSS-FLOAT --*/
+
+ $usey = $this->y + 0.002;
+ if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
+ $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
+ }
+/*-- CSS-IMAGE-FLOAT --*/
+ // If float exists at this level
+ if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
+ if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
+/*-- END CSS-IMAGE-FLOAT --*/
+ } // *TABLES*
+
+
+ $lineBox = array();
+
+ $this->_setInlineBlockHeights($lineBox, $stackHeight, $content, $font, $is_table);
+
+ if ($is_table && count($content)==0) { $stackHeight = 0; }
+
+ if ($table_draft) {
+ $this->y += $stackHeight;
+ $this->objectbuffer = array();
+ return 0;
+ }
+
+ // While we're at it, check if contains cursive text
+ // Change NBSP to SPACE.
+
+ // Re-calculate contentWidth
+ $contentWidth = 0;
+
+ foreach ( $content as $k => $chunk )
+ {
+ $this->restoreFont( $font[ $k ],false );
+ if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
+ // Soft Hyphens chr(173)
+ if (!$this->usingCoreFont) {
+/*-- OTL --*/
+ // mPDF 5.7.1
+ if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
+ $this->otl->removeChar($chunk, $cOTLdata[$k], "\xc2\xad");
+ $this->otl->replaceSpace($chunk, $cOTLdata[$k]);
+ $content[$k] = $chunk;
+ }
+/*-- END OTL --*/
+ else { // *OTL*
+ $content[$k] = $chunk = str_replace("\xc2\xad",'',$chunk );
+ $content[$k] = $chunk = str_replace(chr(194).chr(160),chr(32),$chunk );
+ } // *OTL*
+ }
+ else if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
+ $content[$k] = $chunk = str_replace(chr(173),'',$chunk );
+ $content[$k] = $chunk = str_replace(chr(160),chr(32),$chunk );
+ }
+ $contentWidth += $this->GetStringWidth( $chunk, true, (isset($cOTLdata[$k]) ? $cOTLdata[$k] : false), $this->textvar ) * _MPDFK;
+
+ }
+ else if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]) {
+ // LIST MARKERS // mPDF 6 Lists
+ if ($this->objectbuffer[$k]['type'] == 'image' && isset($this->objectbuffer[$k]['listmarker']) && $this->objectbuffer[$k]['listmarker'] && $this->objectbuffer[$k]['listmarkerposition'] == 'outside') {
+ // do nothing
+ }
+ else {
+ $contentWidth += $this->objectbuffer[$k]['OUTER-WIDTH'] * _MPDFK;
+ }
+ }
+ }
+
+ if(isset($font[count($font)-1])) {
+ $lastfontreqstyle = (isset($font[count($font)-1]['ReqFontStyle']) ? $font[count($font)-1]['ReqFontStyle'] : '');
+ $lastfontstyle = (isset($font[count($font)-1]['style']) ? $font[count($font)-1]['style'] : '');
+ }
+ else {
+ $lastfontreqstyle=null;
+ $lastfontstyle=null;
+ }
+ if ($blockdir == 'ltr' && strpos($lastfontreqstyle,"I") !== false && strpos($lastfontstyle,"I") === false) { // Artificial italic
+ $lastitalic = $this->FontSize*0.15*_MPDFK;
+ }
+ else { $lastitalic = 0; }
+
+ // Get PAGEBREAK TO TEST for height including the bottom border/padding
+ $check_h = max($this->divheight,$stackHeight);
+
+ // This fixes a proven bug...
+ if ($endofblock && $newblock && $blockstate==0 && !$content) { $check_h = 0; }
+ // but ? needs to fix potentially more widespread...
+ // if (!$content) { $check_h = 0; }
+
+ if ($this->blklvl > 0 && !$is_table) {
+ if ($endofblock && $blockstate > 1) {
+ if ($this->blk[$this->blklvl]['page_break_after_avoid']) { $check_h += $stackHeight; }
+ $check_h += ($this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']);
+ }
+ if (($newblock && ($blockstate==1 || $blockstate==3) && $lineCount == 0) || ($endofblock && $blockstate ==3 && $lineCount == 0)) {
+ $check_h += ($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['border_top']['w']);
+ }
+ }
+
+ // Force PAGE break if column height cannot take check-height
+ if ($this->ColActive && $check_h > ($this->PageBreakTrigger - $this->y0)) {
+ $this->SetCol($this->NbCol-1);
+ }
+
+ // Avoid just border/background-color moved on to next page
+ if ($endofblock && $blockstate > 1 && !$content) { $buff = $this->margBuffer; }
+ else { $buff = 0; }
+
+
+ // PAGEBREAK
+ if(!$is_table && ($this->y+$check_h) > ($this->PageBreakTrigger + $buff) and !$this->InFooter and $this->AcceptPageBreak()) {
+ $bak_x=$this->x;//Current X position
+ // WORD SPACING
+ $ws=$this->ws;//Word Spacing
+ $charspacing=$this->charspacing;//Character Spacing
+ $this->ResetSpacing();
+
+ $this->AddPage($this->CurOrientation);
+
+ $this->x=$bak_x;
+ // Added to correct for OddEven Margins
+ $currentx += $this->MarginCorrection;
+ $this->x += $this->MarginCorrection;
+
+ // WORD SPACING
+ $this->SetSpacing($charspacing,$ws);
+ }
+
+
+/*-- COLUMNS --*/
+ // COLS
+ // COLUMN CHANGE
+ if ($this->CurrCol != $oldcolumn) {
+ $currentx += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
+ $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
+ $oldcolumn = $this->CurrCol;
+ }
+
+
+ if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; }
+/*-- END COLUMNS --*/
+
+ // TOP MARGIN
+ if ($newblock && ($blockstate==1 || $blockstate==3) && ($this->blk[$this->blklvl]['margin_top']) && $lineCount == 0 && !$is_table) {
+ $this->DivLn($this->blk[$this->blklvl]['margin_top'],$this->blklvl-1,true,$this->blk[$this->blklvl]['margin_collapse']);
+ if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
+ }
+
+ if ($newblock && ($blockstate==1 || $blockstate==3) && $lineCount == 0 && !$is_table) {
+ $this->blk[$this->blklvl]['y0'] = $this->y;
+ $this->blk[$this->blklvl]['startpage'] = $this->page;
+ if ($this->blk[$this->blklvl]['float']) { $this->blk[$this->blklvl]['float_start_y'] = $this->y; }
+ if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
+ }
+
+ // Paragraph INDENT
+ $WidthCorrection = 0;
+ if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && ($align != 'C')) {
+ $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->blk[$this->blklvl]['InlineProperties']['size'],false); // mPDF 5.7.4
+ $WidthCorrection = ($ti*_MPDFK);
+ }
+
+
+ // PADDING and BORDER spacing/fill
+ if (($newblock) && ($blockstate==1 || $blockstate==3) && (($this->blk[$this->blklvl]['padding_top']) || ($this->blk[$this->blklvl]['border_top'])) && ($lineCount == 0) && (!$is_table)) {
+ // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
+ $this->DivLn($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'],-3,true,false,1);
+ if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
+ $this->x = $currentx;
+ }
+
+
+ // Added mPDF 3.0 Float DIV
+ $fpaddingR = 0;
+ $fpaddingL = 0;
+/*-- CSS-FLOAT --*/
+ if (count($this->floatDivs)) {
+ list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
+ if ($r_exists) { $fpaddingR = $r_width; }
+ if ($l_exists) { $fpaddingL = $l_width; }
+ }
+/*-- END CSS-FLOAT --*/
+
+ $usey = $this->y + 0.002;
+ if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
+ $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
+ }
+/*-- CSS-IMAGE-FLOAT --*/
+ // If float exists at this level
+ if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
+ if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
+/*-- END CSS-IMAGE-FLOAT --*/
+
+
+ if ($content) {
+
+ // In FinishFlowing Block no lines are justified as it is always last line
+ // but if CJKorphan has allowed content width to go over max width, use J charspacing to compress line
+ // JUSTIFICATION J - NOT!
+ $nb_carac = 0;
+ $nb_spaces = 0;
+ $jcharspacing = 0;
+ $jkashida = 0;
+ $jws = 0;
+ $inclCursive=false;
+ $dottab = false;
+ foreach ( $content as $k => $chunk ) {
+ if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
+ $nb_carac += mb_strlen( $chunk, $this->mb_enc );
+ $nb_spaces += mb_substr_count( $chunk,' ', $this->mb_enc );
+ // mPDF 6
+ // Use GPOS OTL
+ $this->restoreFont( $font[ $k ], false);
+ if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
+ if (isset($cOTLdata[$k]['group']) && $cOTLdata[$k]['group']) {
+ $nb_marks = substr_count($cOTLdata[$k]['group'], 'M');
+ $nb_carac -= $nb_marks ;
+ }
+ if (preg_match("/([".$this->pregCURSchars."])/u", $chunk)) { $inclCursive = true; }
+ }
+ }
+ else {
+ $nb_carac ++ ; // mPDF 6 allow spacing for inline object
+ if ($this->objectbuffer[$k]['type']=='dottab') { $dottab = $this->objectbuffer[$k]['outdent']; }
+ }
+ }
+
+ // DIRECTIONALITY RTL
+ $chunkorder = range(0, count($content)-1); // mPDF 6
+/*-- OTL --*/
+ // mPDF 6
+ if ($blockdir == 'rtl' || $this->biDirectional) {
+ $this->otl->_bidiReorder($chunkorder, $content, $cOTLdata, $blockdir);
+ // From this point on, $content and $cOTLdata may contain more elements (and re-ordered) compared to
+ // $this->objectbuffer and $font ($chunkorder contains the mapping)
+ }
+/*-- END OTL --*/
+
+ // Remove any XAdvance from OTL data at end of line
+ // And correct for XPlacement on last character
+ // BIDI is applied
+ foreach($chunkorder AS $aord=>$k) {
+ if (count($cOTLdata)) {
+ $this->restoreFont( $font[ $k ], false);
+ // ...FinishFlowingBlock...
+ if ($aord == count($chunkorder)-1 && isset($cOTLdata[$aord]['group'])) { // Last chunk on line
+ $nGPOS = strlen($cOTLdata[$aord]['group'])-1; // Last character
+ if (isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL']) || isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'])) {
+ if (isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'])) {
+ $w = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'] * 1000/$this->CurrentFont['unitsPerEm'];
+ }
+ else {
+ $w = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'] * 1000/$this->CurrentFont['unitsPerEm'];
+ }
+ $w *= ($this->FontSize/ 1000);
+ $contentWidth -= $w * _MPDFK;
+ $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'] = 0;
+ $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'] = 0;
+ }
+
+ // If last character has an XPlacement set, adjust width calculation, and add to XAdvance to account for it
+ if (isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'])) {
+ $w = -$cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'] * 1000/$this->CurrentFont['unitsPerEm'];
+ $w *= ($this->FontSize/ 1000);
+ $contentWidth -= $w * _MPDFK;
+ $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'] = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'];
+ $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'] = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'];
+ }
+
+ }
+ }
+ }
+
+ // if it's justified, we need to find the char/word spacing (or if orphans have allowed length of line to go over the maxwidth)
+ // If "orphans" in fact is just a final space - ignore this
+ $lastchar = mb_substr($content[(count($chunkorder)-1)],mb_strlen($content[(count($chunkorder)-1)], $this->mb_enc)-1, 1, $this->mb_enc);
+ if (preg_match("/[".$this->CJKoverflow."]/u", $lastchar)) { $CJKoverflow = true; }
+ else {$CJKoverflow = false; }
+ if ((((($contentWidth + $lastitalic) > $maxWidth) && ($content[(count($chunkorder)-1)] != ' ') ) ||
+ (!$endofblock && $align=='J' && ($next=='image' || $next=='select' || $next=='input' || $next=='textarea' || ($next=='br' && $this->justifyB4br)))) && !($CJKoverflow && $this->allowCJKoverflow) ) {
+ // WORD SPACING
+ list($jcharspacing,$jws,$jkashida) = $this->GetJspacing($nb_carac,$nb_spaces,($maxWidth-$lastitalic-$contentWidth-$WidthCorrection-(($this->cMarginL+$this->cMarginR)*_MPDFK)-($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) )),$inclCursive, $cOTLdata);
+ }
+/*-- CJK-FONTS --*/
+ else if ($this->checkCJK && $align=='J' && $CJKoverflow && $this->allowCJKoverflow && $this->CJKforceend) {
+ // force-end overhang
+ $hanger = mb_substr($content[(count($chunkorder)-1)],mb_strlen($content[(count($chunkorder)-1)],$this->mb_enc)-1,1,$this->mb_enc );
+ if (preg_match("/[".$this->CJKoverflow."]/u", $hanger)) {
+ $content[(count($chunkorder)-1)] = mb_substr($content[(count($chunkorder)-1)],0,mb_strlen($content[(count($chunkorder)-1)],$this->mb_enc)-1,$this->mb_enc );
+ $this->restoreFont( $font[ $chunkorder[count($chunkorder)-1] ],false );
+ $contentWidth -= $this->GetStringWidth($hanger) * _MPDFK;
+ $nb_carac -= 1;
+ list($jcharspacing,$jws,$jkashida) = $this->GetJspacing($nb_carac,$nb_spaces,($maxWidth-$lastitalic-$contentWidth-$WidthCorrection-(($this->cMarginL+$this->cMarginR)*_MPDFK)-($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) )),$inclCursive, $cOTLdata);
+ }
+ }
+/*-- END CJK-FONTS --*/
+
+ // Check if will fit at word/char spacing of previous line - if so continue it
+ // but only allow a maximum of $this->jSmaxWordLast and $this->jSmaxCharLast
+ else if ($contentWidth < ($maxWidth - $lastitalic-$WidthCorrection - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK))) && !$this->fixedlSpacing) {
+ if ($this->ws > $this->jSmaxWordLast) {
+ $jws = $this->jSmaxWordLast;
+ }
+ if ($this->charspacing > $this->jSmaxCharLast) {
+ $jcharspacing = $this->jSmaxCharLast;
+ }
+ $check = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) ) - ( $jcharspacing * $nb_carac) - ( $jws * $nb_spaces);
+ if ($check <= 0) {
+ $jcharspacing = 0;
+ $jws = 0;
+ }
+ }
+
+ $empty = $maxWidth - $lastitalic-$WidthCorrection - $contentWidth - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
+
+
+ $empty -= ($jcharspacing * ($nb_carac-1)); // mPDF 6 nb_carac MINUS 1
+ $empty -= ($jws * $nb_spaces);
+ $empty -= ($jkashida);
+
+ $empty /= _MPDFK;
+
+ if (!$is_table) {
+ $this->maxPosR = max($this->maxPosR , ($this->w - $this->rMargin - $this->blk[$this->blklvl]['outer_right_margin'] - $empty));
+ $this->maxPosL = min($this->maxPosL , ($this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $empty));
+ }
+
+ $arraysize = count($chunkorder);
+
+ $margins = ($this->cMarginL+$this->cMarginR) + ($ipaddingL+$ipaddingR + $fpaddingR + $fpaddingR );
+
+ if (!$is_table) { $this->DivLn($stackHeight,$this->blklvl,false); } // false -> don't advance y
+
+ $this->x = $currentx + $this->cMarginL + $ipaddingL + $fpaddingL;
+ if ($dottab !== false && $blockdir=='rtl') { $this->x -= $dottab; }
+ else if ($align == 'R') { $this->x += $empty; }
+ else if ($align == 'J' && $blockdir == 'rtl') { $this->x += $empty; }
+ else if ($align == 'C') { $this->x += ($empty / 2); }
+
+ // Paragraph INDENT
+ $WidthCorrection = 0;
+ if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && ($align !='C')) {
+ $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->blk[$this->blklvl]['InlineProperties']['size'],false); // mPDF 5.7.4
+ if ($blockdir!='rtl') { $this->x += $ti; } // mPDF 6
+ }
+
+ foreach($chunkorder AS $aord=>$k) { // mPDF 5.7
+ $chunk = $content[$aord];
+ if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]) {
+
+ $xadj = $this->x - $this->objectbuffer[$k]['OUTER-X'];
+ $this->objectbuffer[$k]['OUTER-X'] += $xadj;
+ $this->objectbuffer[$k]['BORDER-X'] += $xadj;
+ $this->objectbuffer[$k]['INNER-X'] += $xadj;
+
+ if ($this->objectbuffer[$k]['type'] == 'listmarker') {
+ $this->objectbuffer[$k]['lineBox'] = $lineBox[-1]; // Block element details for glyph-origin
+ }
+ $yadj = $this->y - $this->objectbuffer[$k]['OUTER-Y'];
+ if ($this->objectbuffer[$k]['type'] == 'dottab') { // mPDF 6 DOTTAB
+ $this->objectbuffer[$k]['lineBox'] = $lineBox[$k]; // element details for glyph-origin
+ }
+ if ($this->objectbuffer[$k]['type'] != 'dottab') { // mPDF 6 DOTTAB
+ $yadj += $lineBox[$k]['top'];
+ }
+ $this->objectbuffer[$k]['OUTER-Y'] += $yadj;
+ $this->objectbuffer[$k]['BORDER-Y'] += $yadj;
+ $this->objectbuffer[$k]['INNER-Y'] += $yadj;
+
+ }
+
+ $this->restoreFont( $font[ $k ] ); // mPDF 5.7
+
+ if ($is_table && substr($align,0,1)=='D' && $aord==0 ) {
+ $dp = $this->decimal_align[substr($align,0,2)];
+ $s = preg_split('/'.preg_quote($dp,'/').'/', $content[0], 2); // ? needs to be /u if not core
+ $s0 = $this->GetStringWidth($s[0], false);
+ $this->x += ($this->decimal_offset - $s0);
+ }
+
+ $this->SetSpacing(($this->fixedlSpacing*_MPDFK)+$jcharspacing,($this->fixedlSpacing+$this->minwSpacing)*_MPDFK+$jws);
+ $this->fixedlSpacing = false;
+ $this->minwSpacing = 0;
+
+ $save_vis = $this->visibility;
+ if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->textparam['visibility'] != $this->visibility) {
+ $this->SetVisibility($this->textparam['visibility']);
+ }
+
+ // *********** SPAN BACKGROUND COLOR ***************** //
+ if (isset($this->spanbgcolor) && $this->spanbgcolor) {
+ $cor = $this->spanbgcolorarray;
+ $this->SetFColor($cor);
+ $save_fill = $fill; $spanfill = 1; $fill = 1;
+ }
+ if (!empty($this->spanborddet)) {
+ if (strpos($contentB[$k],'L')!==false && isset($this->spanborddet['L'])) $this->x += $this->spanborddet['L']['w'];
+ if (strpos($contentB[$k],'L')===false) $this->spanborddet['L']['s'] = $this->spanborddet['L']['w'] = 0;
+ if (strpos($contentB[$k],'R')===false) $this->spanborddet['R']['s'] = $this->spanborddet['R']['w'] = 0;
+ }
+ // WORD SPACING
+ // mPDF 5.7.1
+ $stringWidth = $this->GetStringWidth($chunk, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar );
+ $nch = mb_strlen($chunk,$this->mb_enc );
+ // Use GPOS OTL
+ if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
+ if (isset($cOTLdata[$aord]['group']) && $cOTLdata[$aord]['group']) {
+ $nch -= substr_count($cOTLdata[$aord]['group'], 'M');
+ }
+ }
+ $stringWidth += ( $this->charspacing * $nch / _MPDFK );
+
+ $stringWidth += ( $this->ws * mb_substr_count($chunk,' ',$this->mb_enc ) / _MPDFK );
+
+ if (isset($this->objectbuffer[$k])) {
+ if ($this->objectbuffer[$k]['type']=='dottab') {
+ $this->objectbuffer[$k]['OUTER-WIDTH'] +=$empty;
+ $this->objectbuffer[$k]['OUTER-WIDTH'] +=$this->objectbuffer[$k]['outdent'];
+ }
+ // LIST MARKERS // mPDF 6 Lists
+ if ($this->objectbuffer[$k]['type'] == 'image' && isset($this->objectbuffer[$k]['listmarker']) && $this->objectbuffer[$k]['listmarker'] && $this->objectbuffer[$k]['listmarkerposition'] == 'outside') {
+ // do nothing
+ }
+ else {
+ $stringWidth = $this->objectbuffer[$k]['OUTER-WIDTH'];
+ }
+ }
+
+ if ($stringWidth==0) { $stringWidth = 0.000001; }
+ if ($aord == $arraysize-1) { // mPDF 5.7
+ // mPDF 5.7.1
+ if ($this->checkCJK && $CJKoverflow && $align=='J' && $this->allowCJKoverflow && $hanger && $this->CJKforceend) {
+ // force-end overhang
+ $this->Cell( $stringWidth, $stackHeight, $chunk, '', 0, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false)); // mPDF 5.7.1
+ $this->Cell( $this->GetStringWidth($hanger), $stackHeight, $hanger, '', 1, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false)); // mPDF 5.7.1
+ }
+ else {
+ $this->Cell( $stringWidth, $stackHeight, $chunk, '', 1, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false)); // mPDF 5.7.1
+ }
+ }
+ else $this->Cell( $stringWidth, $stackHeight, $chunk, '', 0, '', $fill, $this->HREF, 0, 0,0,'M', $fill, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false));//first or middle part // mPDF 5.7.1
+
+
+ if (!empty($this->spanborddet)) {
+ if (strpos($contentB[$k],'R')!==false && $aord != $arraysize-1) $this->x += $this->spanborddet['R']['w'];
+ }
+ // *********** SPAN BACKGROUND COLOR OFF - RESET BLOCK BGCOLOR ***************** //
+ if (isset($spanfill) && $spanfill) {
+ $fill = $save_fill; $spanfill = 0;
+ if ($fill) { $this->SetFColor($bcor); }
+ }
+ if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->visibility != $save_vis) {
+ $this->SetVisibility($save_vis);
+ }
+
+ }
+
+ $this->printobjectbuffer($is_table, $blockdir);
+ $this->objectbuffer = array();
+ $this->ResetSpacing();
+
+ } // END IF CONTENT
+
+/*-- CSS-IMAGE-FLOAT --*/
+ // Update values if set to skipline
+ if ($this->floatmargins) { $this->_advanceFloatMargins(); }
+
+
+ if ($endofblock && $blockstate>1) {
+ // If float exists at this level
+ if (isset($this->floatmargins['R']['y1'])) { $fry1 = $this->floatmargins['R']['y1']; }
+ else { $fry1 = 0; }
+ if (isset($this->floatmargins['L']['y1'])) { $fly1 = $this->floatmargins['L']['y1']; }
+ else { $fly1 = 0; }
+ if ($this->y < $fry1 || $this->y < $fly1) {
+ $drop = max($fry1,$fly1) - $this->y;
+ $this->DivLn($drop);
+ $this->x = $currentx;
+ }
+ }
+/*-- END CSS-IMAGE-FLOAT --*/
+
+
+ // PADDING and BORDER spacing/fill
+ if ($endofblock && ($blockstate > 1) && ($this->blk[$this->blklvl]['padding_bottom'] || $this->blk[$this->blklvl]['border_bottom'] || $this->blk[$this->blklvl]['css_set_height']) && (!$is_table)) {
+ // If CSS height set, extend bottom - if on same page as block started, and CSS HEIGHT > actual height,
+ // and does not force pagebreak
+ $extra = 0;
+ if (isset($this->blk[$this->blklvl]['css_set_height']) && $this->blk[$this->blklvl]['css_set_height'] && $this->blk[$this->blklvl]['startpage']==$this->page) {
+ // predicted height
+ $h1 = ($this->y-$this->blk[$this->blklvl]['y0']) + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'];
+ if ($h1 < ($this->blk[$this->blklvl]['css_set_height']+$this->blk[$this->blklvl]['padding_bottom']+$this->blk[$this->blklvl]['padding_top'])) { $extra = ($this->blk[$this->blklvl]['css_set_height']+$this->blk[$this->blklvl]['padding_bottom']+$this->blk[$this->blklvl]['padding_top']) - $h1; }
+ if($this->y + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $extra > $this->PageBreakTrigger) {
+ $extra = $this->PageBreakTrigger - ($this->y + $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']);
+ }
+ }
+
+ // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
+ $this->DivLn($this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $extra,-3,true,false,2);
+ $this->x = $currentx;
+
+ if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
+
+ }
+
+ // SET Bottom y1 of block (used for painting borders)
+ if (($endofblock) && ($blockstate > 1) && (!$is_table)) {
+ $this->blk[$this->blklvl]['y1'] = $this->y;
+ }
+
+ // BOTTOM MARGIN
+ if (($endofblock) && ($blockstate > 1) && ($this->blk[$this->blklvl]['margin_bottom']) && (!$is_table)) {
+ if($this->y+$this->blk[$this->blklvl]['margin_bottom'] < $this->PageBreakTrigger and !$this->InFooter) {
+ $this->DivLn($this->blk[$this->blklvl]['margin_bottom'],$this->blklvl-1,true,$this->blk[$this->blklvl]['margin_collapse']);
+ if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
+ }
+ }
+
+ // Reset lineheight
+ $stackHeight = $this->divheight;
+}
+
+
+
+
+
+function printobjectbuffer($is_table=false, $blockdir=false) {
+ if (!$blockdir) { $blockdir = $this->directionality; }
+ if ($is_table && $this->shrin_k > 1) { $k = $this->shrin_k; }
+ else { $k = 1; }
+ $save_y = $this->y;
+ $save_x = $this->x;
+ $save_currentfontfamily = $this->FontFamily;
+ $save_currentfontsize = $this->FontSizePt;
+ $save_currentfontstyle = $this->FontStyle;
+ if ($blockdir == 'rtl') { $rtlalign = 'R'; } else { $rtlalign = 'L'; }
+ foreach ($this->objectbuffer AS $ib => $objattr) {
+ if ($objattr['type'] == 'bookmark' || $objattr['type'] == 'indexentry' || $objattr['type'] == 'toc') {
+ $x = $objattr['OUTER-X'];
+ $y = $objattr['OUTER-Y'];
+ $this->y = $y - $this->FontSize/2;
+ $this->x = $x;
+ if ($objattr['type'] == 'bookmark' ) { $this->Bookmark($objattr['CONTENT'],$objattr['bklevel'] ,$y - $this->FontSize); } // *BOOKMARKS*
+ if ($objattr['type'] == 'indexentry') { $this->IndexEntry($objattr['CONTENT']); } // *INDEX*
+ if ($objattr['type'] == 'toc') { $this->TOC_Entry($objattr['CONTENT'], $objattr['toclevel'], (isset($objattr['toc_id']) ? $objattr['toc_id'] : '')); } // *TOC*
+ }
+/*-- ANNOTATIONS --*/
+ else if ($objattr['type'] == 'annot') {
+ if ($objattr['POS-X']) { $x = $objattr['POS-X']; }
+ else if ($this->annotMargin<>0) { $x = -$objattr['OUTER-X']; }
+ else { $x = $objattr['OUTER-X']; }
+ if ($objattr['POS-Y']) { $y = $objattr['POS-Y']; }
+ else { $y = $objattr['OUTER-Y'] - $this->FontSize/2; }
+ // Create a dummy entry in the _out/columnBuffer with position sensitive data,
+ // linking $y-1 in the Columnbuffer with entry in $this->columnAnnots
+ // and when columns are split in length will not break annotation from current line
+ $this->y = $y-1;
+ $this->x = $x-1;
+ $this->Line($x-1,$y-1,$x-1,$y-1);
+ $this->Annotation($objattr['CONTENT'], $x , $y , $objattr['ICON'], $objattr['AUTHOR'], $objattr['SUBJECT'], $objattr['OPACITY'], $objattr['COLOR'], (isset($objattr['POPUP']) ? $objattr['POPUP'] : '') , (isset($objattr['FILE']) ? $objattr['FILE'] : '') );
+ }
+/*-- END ANNOTATIONS --*/
+ else {
+ $y = $objattr['OUTER-Y'];
+ $x = $objattr['OUTER-X'];
+ $w = $objattr['OUTER-WIDTH'];
+ $h = $objattr['OUTER-HEIGHT'];
+ if (isset($objattr['text'])) { $texto = $objattr['text']; }
+ $this->y = $y;
+ $this->x = $x;
+ if (isset($objattr['fontfamily'])) { $this->SetFont($objattr['fontfamily'],'',$objattr['fontsize'] ); }
+ }
+
+ // HR
+ if ($objattr['type'] == 'hr') {
+ $this->SetDColor($objattr['color']);
+ switch($objattr['align']) {
+ case 'C':
+ $empty = $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH'];
+ $empty /= 2;
+ $x += $empty;
+ break;
+ case 'R':
+ $empty = $objattr['OUTER-WIDTH'] - $objattr['INNER-WIDTH'];
+ $x += $empty;
+ break;
+ }
+ $oldlinewidth = $this->LineWidth;
+ $this->SetLineWidth($objattr['linewidth']/$k );
+ $this->y += ($objattr['linewidth']/2) + $objattr['margin_top']/$k;
+ $this->Line($x,$this->y,$x+$objattr['INNER-WIDTH'],$this->y);
+ $this->SetLineWidth($oldlinewidth);
+ $this->SetDColor($this->ConvertColor(0));
+ }
+ // IMAGE
+ if ($objattr['type'] == 'image') {
+ // mPDF 5.7.3 TRANSFORMS
+ if (isset($objattr['transform'])) {
+ $this->_out("\n".'% BTR'); // Begin Transform
+ }
+ if (isset($objattr['z-index']) && $objattr['z-index'] > 0 && $this->current_layer==0) {
+ $this->BeginLayer($objattr['z-index']);
+ }
+ if(isset($objattr['visibility']) && $objattr['visibility']!='visible' && $objattr['visibility']) {
+ $this->SetVisibility($objattr['visibility']);
+ }
+ if (isset($objattr['opacity'])) { $this->SetAlpha($objattr['opacity']); }
+
+ $obiw = $objattr['INNER-WIDTH'];
+ $obih = $objattr['INNER-HEIGHT'];
+ $sx = $objattr['INNER-WIDTH']*_MPDFK / $objattr['orig_w'];
+ $sy = abs($objattr['INNER-HEIGHT'])*_MPDFK / abs($objattr['orig_h']);
+ $sx = ($objattr['INNER-WIDTH']*_MPDFK / $objattr['orig_w']);
+ $sy = ($objattr['INNER-HEIGHT']*_MPDFK / $objattr['orig_h']);
+
+ $rotate = 0;
+ if (isset($objattr['ROTATE'])) { $rotate = $objattr['ROTATE']; }
+ if ($rotate==90) {
+ // Clockwise
+ $obiw = $objattr['INNER-HEIGHT'];
+ $obih = $objattr['INNER-WIDTH'];
+ $tr = $this->transformTranslate(0, -$objattr['INNER-WIDTH'], true) ;
+ $tr .= ' '. $this->transformRotate(90, $objattr['INNER-X'],($objattr['INNER-Y'] +$objattr['INNER-WIDTH'] ),true) ;
+ $sx = $obiw*_MPDFK / $objattr['orig_h'];
+ $sy = $obih*_MPDFK / $objattr['orig_w'];
+ }
+ else if ($rotate==-90 || $rotate==270) {
+ // AntiClockwise
+ $obiw = $objattr['INNER-HEIGHT'];
+ $obih = $objattr['INNER-WIDTH'];
+ $tr = $this->transformTranslate($objattr['INNER-WIDTH'], ($objattr['INNER-HEIGHT']-$objattr['INNER-WIDTH']), true) ;
+ $tr .= ' '. $this->transformRotate(-90, $objattr['INNER-X'],($objattr['INNER-Y'] +$objattr['INNER-WIDTH'] ),true) ;
+ $sx = $obiw*_MPDFK / $objattr['orig_h'];
+ $sy = $obih*_MPDFK / $objattr['orig_w'];
+ }
+ else if ($rotate==180) {
+ // Mirror
+ $tr = $this->transformTranslate($objattr['INNER-WIDTH'], -$objattr['INNER-HEIGHT'], true) ;
+ $tr .= ' '. $this->transformRotate(180, $objattr['INNER-X'],($objattr['INNER-Y'] +$objattr['INNER-HEIGHT'] ),true) ;
+ }
+ else { $tr = ''; }
+ $tr = trim($tr);
+ if ($tr) { $tr .= ' '; }
+ $gradmask = '';
+
+ // mPDF 5.7.3 TRANSFORMS
+ $tr2 = '';
+ if (isset($objattr['transform'])) {
+ $maxsize_x = $w;
+ $maxsize_y = $h;
+ $cx = $x + $w/2;
+ $cy = $y + $h/2;
+ preg_match_all('/(translatex|translatey|translate|scalex|scaley|scale|rotate|skewX|skewY|skew)\((.*?)\)/is',$objattr['transform'],$m);
+ if (count($m[0])) {
+ for($i=0; $iConvertSize($vv[0],$maxsize_x,false,false);
+ if (count($vv)==2) { $translate_y = $this->ConvertSize($vv[1],$maxsize_y,false,false); }
+ else { $translate_y = 0; }
+ $tr2 .= $this->transformTranslate($translate_x, $translate_y, true).' ';
+ }
+ else if ($c=='translatex' && count($vv)) {
+ $translate_x = $this->ConvertSize($vv[0],$maxsize_x,false,false);
+ $tr2 .= $this->transformTranslate($translate_x, 0, true).' ';
+ }
+ else if ($c=='translatey' && count($vv)) {
+ $translate_y = $this->ConvertSize($vv[1],$maxsize_y,false,false);
+ $tr2 .= $this->transformTranslate(0, $translate_y, true).' ';
+ }
+ else if ($c=='scale' && count($vv)) {
+ $scale_x = $vv[0] * 100;
+ if (count($vv)==2) { $scale_y = $vv[1] * 100; }
+ else { $scale_y = $scale_x; }
+ $tr2 .= $this->transformScale($scale_x, $scale_y, $cx, $cy, true).' ';
+ }
+ else if ($c=='scalex' && count($vv)) {
+ $scale_x = $vv[0] * 100;
+ $tr2 .= $this->transformScale($scale_x, 0, $cx, $cy, true).' ';
+ }
+ else if ($c=='scaley' && count($vv)) {
+ $scale_y = $vv[1] * 100;
+ $tr2 .= $this->transformScale(0, $scale_y, $cx, $cy, true).' ';
+ }
+ else if ($c=='skew' && count($vv)) {
+ $angle_x = $this->ConvertAngle($vv[0], false);
+ if (count($vv)==2) { $angle_y = $this->ConvertAngle($vv[1], false); }
+ else { $angle_y = 0; }
+ $tr2 .= $this->transformSkew($angle_x, $angle_y, $cx, $cy, true).' ';
+ }
+ else if ($c=='skewx' && count($vv)) {
+ $angle = $this->ConvertAngle($vv[0], false);
+ $tr2 .= $this->transformSkew($angle, 0, $cx, $cy, true).' ';
+ }
+ else if ($c=='skewy' && count($vv)) {
+ $angle = $this->ConvertAngle($vv[0], false);
+ $tr2 .= $this->transformSkew(0, $angle, $cx, $cy, true).' ';
+ }
+ else if ($c=='rotate' && count($vv)) {
+ $angle = $this->ConvertAngle($vv[0]);
+ $tr2 .= $this->transformRotate($angle, $cx, $cy, true).' ';
+ }
+ }
+ }
+ }
+
+ // LIST MARKERS (Images) // mPDF 6 Lists
+ if (isset($objattr['listmarker']) && $objattr['listmarker'] && $objattr['listmarkerposition']=='outside') {
+ $mw = $objattr['OUTER-WIDTH'];
+ // NB If change marker-offset, also need to alter in function _getListMarkerWidth
+ $adjx = $this->ConvertSize($this->list_marker_offset,$this->FontSize);
+ if ($objattr['dir'] == 'rtl') {
+ $objattr['INNER-X'] += $adjx ;
+ }
+ else {
+ $objattr['INNER-X'] -= $adjx ;
+ $objattr['INNER-X'] -= $mw;
+ }
+ }
+ // mPDF 5.7.3 TRANSFORMS / BACKGROUND COLOR
+ // Transform also affects image background
+ if ($tr2) { $this->_out('q '.$tr2.' '); }
+ if (isset($objattr['bgcolor']) && $objattr['bgcolor']) {
+ $bgcol = $objattr['bgcolor'];
+ $this->SetFColor($bgcol);
+ $this->Rect($x,$y,$w,$h, 'F');
+ $this->SetFColor($this->ConvertColor(255));
+ }
+ if ($tr2) { $this->_out('Q'); }
+
+/*-- BACKGROUNDS --*/
+ if (isset($objattr['GRADIENT-MASK'])) {
+ $g = $this->grad->parseMozGradient( $objattr['GRADIENT-MASK'] );
+ if ($g) {
+ $dummy = $this->grad->Gradient($objattr['INNER-X'], $objattr['INNER-Y'], $obiw, $obih, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend'], true, true);
+ $gradmask = '/TGS'.count($this->gradients).' gs ';
+ }
+ }
+/*-- END BACKGROUNDS --*/
+/*-- IMAGES-WMF --*/
+ if (isset($objattr['itype']) && $objattr['itype']=='wmf') {
+ $outstring = sprintf('q '.$tr.$tr2.'%.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, -$sy, $objattr['INNER-X']*_MPDFK-$sx*$objattr['wmf_x'], (($this->h-$objattr['INNER-Y'])*_MPDFK)+$sy*$objattr['wmf_y'], $objattr['ID']); // mPDF 5.7.3 TRANSFORMS
+ }
+ else
+/*-- END IMAGES-WMF --*/
+ if (isset($objattr['itype']) && $objattr['itype']=='svg') {
+ $outstring = sprintf('q '.$tr.$tr2.'%.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, -$sy, $objattr['INNER-X']*_MPDFK-$sx*$objattr['wmf_x'], (($this->h-$objattr['INNER-Y'])*_MPDFK)+$sy*$objattr['wmf_y'], $objattr['ID']); // mPDF 5.7.3 TRANSFORMS
+ }
+ else {
+ $outstring = sprintf("q ".$tr.$tr2."%.3F 0 0 %.3F %.3F %.3F cm ".$gradmask."/I%d Do Q",$obiw*_MPDFK, $obih*_MPDFK, $objattr['INNER-X'] *_MPDFK, ($this->h-($objattr['INNER-Y'] +$obih ))*_MPDFK,$objattr['ID'] ); // mPDF 5.7.3 TRANSFORMS
+ }
+ $this->_out($outstring);
+ // LINK
+ if (isset($objattr['link'])) $this->Link($objattr['INNER-X'],$objattr['INNER-Y'],$objattr['INNER-WIDTH'],$objattr['INNER-HEIGHT'],$objattr['link']);
+ if (isset($objattr['opacity'])) { $this->SetAlpha(1); }
+
+ // mPDF 5.7.3 TRANSFORMS
+ // Transform also affects image borders
+ if ($tr2) { $this->_out('q '.$tr2.' '); }
+ if ((isset($objattr['border_top']) && $objattr['border_top']>0) || (isset($objattr['border_left']) && $objattr['border_left']>0) || (isset($objattr['border_right']) && $objattr['border_right']>0) || (isset($objattr['border_bottom']) && $objattr['border_bottom']>0)) { $this->PaintImgBorder($objattr,$is_table); }
+ if ($tr2) { $this->_out('Q'); }
+
+ if(isset($objattr['visibility']) && $objattr['visibility']!='visible' && $objattr['visibility']) {
+ $this->SetVisibility('visible');
+ }
+ if (isset($objattr['z-index']) && $objattr['z-index'] > 0 && $this->current_layer==0) {
+ $this->EndLayer();
+ }
+ // mPDF 5.7.3 TRANSFORMS
+ if (isset($objattr['transform'])) {
+ $this->_out("\n".'% ETR'); // End Transform
+ }
+ }
+
+/*-- BARCODES --*/
+ // BARCODE
+ if ($objattr['type'] == 'barcode') {
+ $bgcol = $this->ConvertColor(255);
+ if (isset($objattr['bgcolor']) && $objattr['bgcolor']) {
+ $bgcol = $objattr['bgcolor'];
+ }
+ $col = $this->ConvertColor(0);
+ if (isset($objattr['color']) && $objattr['color']) {
+ $col = $objattr['color'];
+ }
+ $this->SetFColor($bgcol);
+ $this->Rect($objattr['BORDER-X'], $objattr['BORDER-Y'], $objattr['BORDER-WIDTH'], $objattr['BORDER-HEIGHT'], 'F');
+ $this->SetFColor($this->ConvertColor(255));
+ if (isset($objattr['BORDER-WIDTH'])) { $this->PaintImgBorder($objattr,$is_table); }
+ if ($objattr['btype'] == 'EAN13' || $objattr['btype'] == 'ISBN' || $objattr['btype'] == 'ISSN' || $objattr['btype'] == 'UPCA' || $objattr['btype'] == 'UPCE' || $objattr['btype'] == 'EAN8') {
+ $this->WriteBarcode($objattr['code'], $objattr['showtext'], $objattr['INNER-X'], $objattr['INNER-Y'], $objattr['bsize'], 0, 0, 0, 0, 0, $objattr['bheight'], $bgcol, $col, $objattr['btype'], $objattr['bsupp'], (isset($objattr['bsupp_code']) ? $objattr['bsupp_code'] : ''), $k);
+ }
+ // QR-code
+ else if ($objattr['btype']=='QR') {
+ if (!class_exists('QRcode', false)) {
+ include(_MPDF_PATH.'qrcode/qrcode.class.php');
+ }
+ $this->qrcode = new QRcode($objattr['code'], $objattr['errorlevel']);
+ $this->qrcode->displayFPDF($this, $objattr['INNER-X'], $objattr['INNER-Y'], $objattr['bsize']*25, array(255,255,255), array(0,0,0));
+ }
+ else {
+ $this->WriteBarcode2($objattr['code'], $objattr['INNER-X'], $objattr['INNER-Y'], $objattr['bsize'], $objattr['bheight'], $bgcol, $col, $objattr['btype'], $objattr['pr_ratio'], $k);
+ }
+ }
+/*-- END BARCODES --*/
+
+ // TEXT CIRCLE
+ if ($objattr['type'] == 'textcircle') {
+ $bgcol = '';
+ if (isset($objattr['bgcolor']) && $objattr['bgcolor']) {
+ $bgcol = $objattr['bgcolor'];
+ }
+ $col = $this->ConvertColor(0);
+ if (isset($objattr['color']) && $objattr['color']) {
+ $col = $objattr['color'];
+ }
+ $this->SetTColor($col);
+ $this->SetFColor($bgcol);
+ if ($bgcol) $this->Rect($objattr['BORDER-X'], $objattr['BORDER-Y'], $objattr['BORDER-WIDTH'], $objattr['BORDER-HEIGHT'], 'F');
+ $this->SetFColor($this->ConvertColor(255));
+ if (isset($objattr['BORDER-WIDTH'])) { $this->PaintImgBorder($objattr,$is_table); }
+ if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
+ if (empty($this->directw)) { $this->directw = new directw($this); }
+ if (isset($objattr['top-text'])) {
+ $this->directw->CircularText($objattr['INNER-X']+$objattr['INNER-WIDTH']/2, $objattr['INNER-Y']+$objattr['INNER-HEIGHT']/2, $objattr['r']/$k, $objattr['top-text'], 'top', $objattr['fontfamily'], $objattr['fontsize']/$k, $objattr['fontstyle'], $objattr['space-width'], $objattr['char-width'], (isset($objattr['divider']) ? $objattr['divider'] : ''));
+ }
+ if (isset($objattr['bottom-text'])) {
+ $this->directw->CircularText($objattr['INNER-X']+$objattr['INNER-WIDTH']/2, $objattr['INNER-Y']+$objattr['INNER-HEIGHT']/2, $objattr['r']/$k, $objattr['bottom-text'], 'bottom', $objattr['fontfamily'], $objattr['fontsize']/$k, $objattr['fontstyle'], $objattr['space-width'], $objattr['char-width'], (isset($objattr['divider']) ? $objattr['divider'] : ''));
+ }
+ }
+
+ $this->ResetSpacing();
+
+ // LIST MARKERS (Text or bullets) // mPDF 6 Lists
+ if ($objattr['type'] == 'listmarker') {
+ if (isset($objattr['fontfamily'])) { $this->SetFont($objattr['fontfamily'],$objattr['fontstyle'],$objattr['fontsizept'] ); }
+ $col = $this->ConvertColor(0);
+ if (isset($objattr['colorarray']) && ($objattr['colorarray'])) {
+ $col = $objattr['colorarray'];
+ }
+
+ if (isset($objattr['bullet']) && $objattr['bullet']) { // Used for position "outside" only
+ $type = $objattr['bullet'];
+ $size = $objattr['size'];
+
+ if ($objattr['listmarkerposition'] == 'inside') {
+ $adjx = $size/2;
+ if ($objattr['dir'] == 'rtl') {
+ $adjx += $objattr['offset'];
+ }
+ $this->x += $adjx;
+ }
+ else {
+ $adjx = $objattr['offset'];
+ $adjx += $size/2;
+ if ($objattr['dir'] == 'rtl') {
+ $this->x += $adjx;
+ }
+ else {
+ $this->x -= $adjx;
+ }
+ }
+
+ $yadj = $objattr['lineBox']['glyphYorigin'];
+ if (isset($this->CurrentFont['desc']['XHeight']) && $this->CurrentFont['desc']['XHeight']) { $xh=$this->CurrentFont['desc']['XHeight']; }
+ else { $xh = 500; }
+ $yadj -= ($this->FontSize * $xh/1000) * 0.625; // Vertical height of bullet (centre) from baseline= XHeight * 0.625
+ $this->y += $yadj;
+
+ $this->_printListBullet($this->x, $this->y, $size, $type, $col);
+ }
+ else {
+ $this->SetTColor($col);
+ $w = $this->GetStringWidth($texto);
+ // NB If change marker-offset, also need to alter in function _getListMarkerWidth
+ $adjx = $this->ConvertSize($this->list_marker_offset,$this->FontSize);
+ if ($objattr['dir'] == 'rtl') {
+ $align = 'L';
+ $this->x += $adjx;
+ }
+ else {
+ // Use these lines to set as marker-offset, right-aligned - default
+ $align = 'R';
+ $this->x -= $adjx;
+ $this->x -= $w;
+ }
+ $this->Cell($w,$this->FontSize,$texto,0,0,$align,0,'',0,0,0, 'T', 0, false, false, 0 ,$objattr['lineBox']);
+ $this->SetTColor($this->ConvertColor(0));
+ }
+ }
+
+ // DOT-TAB
+ if ($objattr['type'] == 'dottab') {
+ if (isset($objattr['fontfamily'])) { $this->SetFont($objattr['fontfamily'],'',$objattr['fontsize'] ); }
+ $sp = $this->GetStringWidth(' ');
+ $nb=floor(($w-2*$sp)/$this->GetStringWidth('.'));
+ if ($nb>0) { $dots=' '.str_repeat('.',$nb).' '; }
+ else { $dots=' '; }
+ $col = $this->ConvertColor(0);
+ if (isset($objattr['colorarray']) && ($objattr['colorarray'])) {
+ $col = $objattr['colorarray'];
+ }
+ $this->SetTColor($col);
+ $save_dh = $this->divheight;
+ $save_sbd = $this->spanborddet;
+ $save_textvar = $this->textvar; // mPDF 5.7.1
+ $this->spanborddet = '';
+ $this->divheight = 0;
+ $this->textvar = 0x00; // mPDF 5.7.1
+
+ $this->Cell($w,$h,$dots,0,0,'C',0,'',0,0,0, 'T', 0, false, false, 0 ,$objattr['lineBox']); // mPDF 6 DOTTAB
+ $this->spanborddet = $save_sbd;
+ $this->textvar = $save_textvar; // mPDF 5.7.1
+ $this->divheight = $save_dh;
+ $this->SetTColor($this->ConvertColor(0));
+ }
+
+/*-- FORMS --*/
+ // TEXT/PASSWORD INPUT
+ if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'TEXT' || $objattr['subtype'] == 'PASSWORD')) {
+ $this->mpdfform->print_ob_text($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
+ }
+
+ // TEXTAREA
+ if ($objattr['type'] == 'textarea') {
+ $this->mpdfform->print_ob_textarea($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
+ }
+
+ // SELECT
+ if ($objattr['type'] == 'select') {
+ $this->mpdfform->print_ob_select($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
+ }
+
+
+ // INPUT/BUTTON as IMAGE
+ if ($objattr['type'] == 'input' && $objattr['subtype'] == 'IMAGE') {
+ $this->mpdfform->print_ob_imageinput($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
+ }
+
+ // BUTTON
+ if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'SUBMIT' || $objattr['subtype'] == 'RESET' || $objattr['subtype'] == 'BUTTON')) {
+ $this->mpdfform->print_ob_button($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir);
+ }
+
+ // CHECKBOX
+ if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'CHECKBOX')) {
+ $this->mpdfform->print_ob_checkbox($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir,$x,$y);
+ }
+ // RADIO
+ if ($objattr['type'] == 'input' && ($objattr['subtype'] == 'RADIO')) {
+ $this->mpdfform->print_ob_radio($objattr,$w,$h,$texto,$rtlalign,$k,$blockdir,$x,$y);
+ }
+/*-- END FORMS --*/
+ }
+ $this->SetFont($save_currentfontfamily,$save_currentfontstyle,$save_currentfontsize);
+ $this->y = $save_y;
+ $this->x = $save_x;
+ unset($content);
+}
+
+function _printListBullet($x, $y, $size, $type, $color) {
+ // x and y are the centre of the bullet; size is the width and/or height in mm
+ $fcol = $this->SetTColor($color,true);
+ $lcol = strtoupper($fcol); // change 0 0 0 rg to 0 0 0 RG
+ $this->_out( sprintf('q %s %s',$lcol, $fcol) );
+ $this->_out( '0 j 0 J [] 0 d' );
+ if ($type=='square') {
+ $size *= 0.85; // Smaller to appear the same size as circle/disc
+ $this->_out( sprintf('%.3F %.3F %.3F %.3F re f',($x-$size/2)*_MPDFK,($this->h-$y+$size/2)*_MPDFK,($size)*_MPDFK,(-$size)*_MPDFK) );
+ }
+ else if ($type=='disc') {
+ $this->Circle($x, $y, $size/2, 'F'); // Fill
+ }
+ else if ($type=='circle') {
+ $lw = $size/12; // Line width
+ $this->_out( sprintf('%.3F w ',$lw*_MPDFK) );
+ $this->Circle($x, $y, $size/2 - $lw/2, 'S'); // Stroke
+ }
+ $this->_out( 'Q' );
+}
+
+// mPDF 6
+// Get previous character and move pointers
+function _moveToPrevChar(&$contentctr, &$charctr, $content) {
+ $lastchar = false;
+ $charctr--;
+ while ($charctr<0) { // go back to previous $content[]
+ $contentctr--;
+ if ($contentctr<0) { return false; }
+ if ($this->usingCoreFont) { $charctr = strlen( $content[$contentctr] )-1; }
+ else { $charctr = mb_strlen( $content[$contentctr], $this->mb_enc )-1; }
+ }
+ if ($this->usingCoreFont) { $lastchar = $content[$contentctr][$charctr]; }
+ else { $lastchar = mb_substr($content[$contentctr],$charctr,1,$this->mb_enc ); }
+ return $lastchar;
+}
+// Get previous character
+function _getPrevChar($contentctr, $charctr, $content) {
+ $lastchar = false;
+ $charctr--;
+ while ($charctr<0) { // go back to previous $content[]
+ $contentctr--;
+ if ($contentctr<0) { return false; }
+ if ($this->usingCoreFont) { $charctr = strlen( $content[$contentctr] )-1; }
+ else { $charctr = mb_strlen( $content[$contentctr], $this->mb_enc )-1; }
+ }
+ if ($this->usingCoreFont) {$lastchar = $content[$contentctr][$charctr]; }
+ else { $lastchar = mb_substr($content[$contentctr],$charctr,1,$this->mb_enc ); }
+ return $lastchar;
+}
+
+
+
+function WriteFlowingBlock( $s, $sOTLdata) { // mPDF 5.7.1
+ $currentx = $this->x;
+ $is_table = $this->flowingBlockAttr[ 'is_table' ];
+ $table_draft = $this->flowingBlockAttr[ 'table_draft' ];
+ // width of all the content so far in points
+ $contentWidth =& $this->flowingBlockAttr[ 'contentWidth' ];
+ // cell width in points
+ $maxWidth =& $this->flowingBlockAttr[ 'width' ];
+ $lineCount =& $this->flowingBlockAttr[ 'lineCount' ];
+ // line height in user units
+ $stackHeight =& $this->flowingBlockAttr[ 'height' ];
+ $align =& $this->flowingBlockAttr[ 'align' ];
+ $content =& $this->flowingBlockAttr[ 'content' ];
+ $contentB =& $this->flowingBlockAttr[ 'contentB' ];
+ $font =& $this->flowingBlockAttr[ 'font' ];
+ $valign =& $this->flowingBlockAttr[ 'valign' ];
+ $blockstate = $this->flowingBlockAttr[ 'blockstate' ];
+ $cOTLdata =& $this->flowingBlockAttr[ 'cOTLdata' ]; // mPDF 5.7.1
+
+ $newblock = $this->flowingBlockAttr[ 'newblock' ];
+ $blockdir = $this->flowingBlockAttr['blockdir'];
+
+ // *********** BLOCK BACKGROUND COLOR ***************** //
+ if ($this->blk[$this->blklvl]['bgcolor'] && !$is_table) {
+ $fill = 0;
+ }
+ else {
+ $this->SetFColor($this->ConvertColor(255));
+ $fill = 0;
+ }
+ $font[] = $this->saveFont();
+ $content[] = '';
+ $contentB[] = '';
+ $cOTLdata[] = $sOTLdata; // mPDF 5.7.1
+ $currContent =& $content[ count( $content ) - 1 ];
+
+ $CJKoverflow = false;
+ $Oikomi = false; // mPDF 6
+ $hanger = '';
+
+ // COLS
+ $oldcolumn = $this->CurrCol;
+ if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
+
+/*-- TABLES --*/
+ if ($is_table) {
+ $ipaddingL = 0;
+ $ipaddingR = 0;
+ $paddingL = 0;
+ $paddingR = 0;
+ $cpaddingadjustL = 0;
+ $cpaddingadjustR = 0;
+ // Added mPDF 3.0
+ $fpaddingR = 0;
+ $fpaddingL = 0;
+ }
+ else {
+/*-- END TABLES --*/
+ $ipaddingL = $this->blk[$this->blklvl]['padding_left'];
+ $ipaddingR = $this->blk[$this->blklvl]['padding_right'];
+ $paddingL = ($ipaddingL * _MPDFK);
+ $paddingR = ($ipaddingR * _MPDFK);
+ $this->cMarginL = $this->blk[$this->blklvl]['border_left']['w'];
+ $cpaddingadjustL = -$this->cMarginL;
+ $this->cMarginR = $this->blk[$this->blklvl]['border_right']['w'];
+ $cpaddingadjustR = -$this->cMarginR;
+ // Added mPDF 3.0 Float DIV
+ $fpaddingR = 0;
+ $fpaddingL = 0;
+/*-- CSS-FLOAT --*/
+ if (count($this->floatDivs)) {
+ list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
+ if ($r_exists) { $fpaddingR = $r_width; }
+ if ($l_exists) { $fpaddingL = $l_width; }
+ }
+/*-- END CSS-FLOAT --*/
+
+ $usey = $this->y + 0.002;
+ if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
+ $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
+ }
+/*-- CSS-IMAGE-FLOAT --*/
+ // If float exists at this level
+ if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
+ if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
+/*-- END CSS-IMAGE-FLOAT --*/
+ } // *TABLES*
+
+ //OBJECTS - IMAGES & FORM Elements (NB has already skipped line/page if required - in printbuffer)
+ if (substr($s,0,3) == "\xbb\xa4\xac") { //identifier has been identified!
+ $objattr = $this->_getObjAttr($s);
+ $h_corr = 0;
+ if ($is_table) { // *TABLES*
+ $maximumW = ($maxWidth/_MPDFK) - ($this->cellPaddingL + $this->cMarginL + $this->cellPaddingR + $this->cMarginR); // *TABLES*
+ } // *TABLES*
+ else { // *TABLES*
+ if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) && (!$is_table)) { $h_corr = $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w']; }
+ $maximumW = ($maxWidth/_MPDFK) - ($this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_right'] + $this->blk[$this->blklvl]['border_right']['w'] + $fpaddingL + $fpaddingR );
+ } // *TABLES*
+ $objattr = $this->inlineObject($objattr['type'],$this->lMargin + $fpaddingL + ($contentWidth/_MPDFK),($this->y + $h_corr), $objattr, $this->lMargin,($contentWidth/_MPDFK),$maximumW,$stackHeight,true,$is_table);
+
+ // SET LINEHEIGHT for this line ================ RESET AT END
+ $stackHeight = MAX($stackHeight,$objattr['OUTER-HEIGHT']);
+ $this->objectbuffer[count($content)-1] = $objattr;
+ // if (isset($objattr['vertical-align'])) { $valign = $objattr['vertical-align']; }
+ // else { $valign = ''; }
+ // LIST MARKERS // mPDF 6 Lists
+ if ($objattr['type'] == 'image' && isset($objattr['listmarker']) && $objattr['listmarker'] && $objattr['listmarkerposition'] == 'outside') {
+ // do nothing
+ }
+ else {
+ $contentWidth += ($objattr['OUTER-WIDTH'] * _MPDFK);
+ }
+ return;
+ }
+
+ $lbw = $rbw = 0; // Border widths
+ if (!empty($this->spanborddet)) {
+ if (isset($this->spanborddet['L'])) $lbw = $this->spanborddet['L']['w'];
+ if (isset($this->spanborddet['R'])) $rbw = $this->spanborddet['R']['w'];
+ }
+
+ if ($this->usingCoreFont) {
+ $clen = strlen( $s );
+ }
+ else {
+ $clen = mb_strlen( $s, $this->mb_enc );
+ }
+
+ // for every character in the string
+ for ( $i = 0; $i < $clen; $i++ ) {
+
+ // extract the current character
+ // get the width of the character in points
+ if ($this->usingCoreFont) {
+ $c = $s[$i];
+ // Soft Hyphens chr(173)
+ $cw = ($this->GetCharWidthCore($c) * _MPDFK);
+ if (($this->textvar & FC_KERNING) && $i > 0) { // mPDF 5.7.1
+ if (isset($this->CurrentFont['kerninfo'][$s[($i-1)]][$c])) {
+ $cw += ($this->CurrentFont['kerninfo'][$s[($i-1)]][$c] * $this->FontSizePt / 1000 );
+ }
+ }
+ }
+ else {
+ $c = mb_substr($s,$i,1,$this->mb_enc );
+ $cw = ($this->GetCharWidthNonCore($c, false) * _MPDFK);
+ // mPDF 5.7.1
+ // Use OTL GPOS
+ if (isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF)) {
+ // ...WriteFlowingBlock...
+ // Only add XAdvanceL (not sure at present whether RTL or LTR writing direction)
+ // At this point, XAdvanceL and XAdvanceR will balance
+ if (isset($sOTLdata['GPOSinfo'][$i]['XAdvanceL'])) {
+ $cw += $sOTLdata['GPOSinfo'][$i]['XAdvanceL']* (1000/$this->CurrentFont['unitsPerEm']) * ($this->FontSize/ 1000) * _MPDFK;
+ }
+ }
+ if (($this->textvar & FC_KERNING) && $i > 0) { // mPDF 5.7.1
+ $lastc = mb_substr($s,($i-1),1,$this->mb_enc );
+ $ulastc = $this->UTF8StringToArray($lastc, false);
+ $uc = $this->UTF8StringToArray($c, false);
+ if (isset($this->CurrentFont['kerninfo'][$ulastc[0]][$uc[0]])) {
+ $cw += ($this->CurrentFont['kerninfo'][$ulastc[0]][$uc[0]] * $this->FontSizePt / 1000 );
+ }
+ }
+ }
+
+ if ($i==0) {
+ $cw += $lbw*_MPDFK;
+ $contentB[(count($contentB)-1)] .= 'L';
+ }
+ if ($i==($clen-1)) {
+ $cw += $rbw*_MPDFK;
+ $contentB[(count($contentB)-1)] .= 'R';
+ }
+ if ($c==' ') {
+ $currContent .= $c;
+ $contentWidth += $cw;
+ continue;
+ }
+
+ // Paragraph INDENT
+ $WidthCorrection = 0;
+ if (($newblock) && ($blockstate==1 || $blockstate==3) && isset($this->blk[$this->blklvl]['text_indent']) && ($lineCount == 0) && (!$is_table) && ($align != 'C')) {
+ $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->blk[$this->blklvl]['InlineProperties']['size'],false); // mPDF 5.7.4
+ $WidthCorrection = ($ti*_MPDFK);
+ }
+ // OUTDENT
+ foreach ($this->objectbuffer AS $k => $objattr) { // mPDF 6 DOTTAB
+ if ($objattr['type'] == 'dottab') {
+ $WidthCorrection -= ($objattr['outdent'] * _MPDFK);
+ break;
+ }
+ }
+
+
+ // Added mPDF 3.0 Float DIV
+ $fpaddingR = 0;
+ $fpaddingL = 0;
+/*-- CSS-FLOAT --*/
+ if (count($this->floatDivs)) {
+ list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
+ if ($r_exists) { $fpaddingR = $r_width; }
+ if ($l_exists) { $fpaddingL = $l_width; }
+ }
+/*-- END CSS-FLOAT --*/
+
+ $usey = $this->y + 0.002;
+ if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 0) ) {
+ $usey += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
+ }
+
+/*-- CSS-IMAGE-FLOAT --*/
+ // If float exists at this level
+ if (isset($this->floatmargins['R']) && $usey <= $this->floatmargins['R']['y1'] && $usey >= $this->floatmargins['R']['y0'] && !$this->floatmargins['R']['skipline']) { $fpaddingR += $this->floatmargins['R']['w']; }
+ if (isset($this->floatmargins['L']) && $usey <= $this->floatmargins['L']['y1'] && $usey >= $this->floatmargins['L']['y0'] && !$this->floatmargins['L']['skipline']) { $fpaddingL += $this->floatmargins['L']['w']; }
+/*-- END CSS-IMAGE-FLOAT --*/
+
+
+ // try adding another char
+ if (( $contentWidth + $cw > $maxWidth - $WidthCorrection - (($this->cMarginL+$this->cMarginR)*_MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) ) + 0.001)) {// 0.001 is to correct for deviations converting mm=>pts
+ // it won't fit, output what we already have
+ $lineCount++;
+
+ // contains any content that didn't make it into this print
+ $savedContent = '';
+ $savedContentB = '';
+ $savedOTLdata = array(); // mPDF 5.7.1
+ $savedFont = array();
+ $savedObj = array();
+ $savedPreOTLdata = array(); // mPDF 5.7.1
+ $savedPreContent = array();
+ $savedPreContentB = array();
+ $savedPreFont = array();
+
+ // mPDF 6
+ // New line-breaking algorithm
+ /////////////////////
+ // LINE BREAKING
+ /////////////////////
+ $breakfound = false;
+ $contentctr = count($content)-1;
+ if ($this->usingCoreFont) { $charctr = strlen($currContent); }
+ else { $charctr = mb_strlen($currContent,$this->mb_enc ); }
+ $checkchar = $c;
+ $prevchar = $this->_getPrevChar($contentctr, $charctr, $content);
+
+/*-- CJK-FONTS --*/
+ /////////////////////
+ // 1) CJK Overflowing a) punctuation or b) Oikomi
+ /////////////////////
+ // Next character ($c) is suitable to add as overhanging or squeezed punctuation, or Oikomi
+ if ($CJKoverflow || $Oikomi) { // If flag already set
+ $CJKoverflow = false;
+ $Oikomi = false;
+ $breakfound = true;
+ }
+ if (!$this->usingCoreFont && !$breakfound && $this->checkCJK) {
+ // Get next/following character (in this chunk)
+ $followingchar = '';
+ if ($i<($clen-1)) {
+ if ($this->usingCoreFont) { $followingchar = $s[$i+1]; }
+ else { $followingchar = mb_substr($s,$i+1,1,$this->mb_enc ); }
+ }
+ /////////////////////
+ // 1a) Overflow punctuation
+ /////////////////////
+ if (preg_match("/[".$this->pregCJKchars."]/u",$prevchar) && preg_match("/[".$this->CJKoverflow."]/u", $checkchar) && $this->allowCJKorphans) {
+ // add character onto this line
+ $currContent .= $c;
+ $contentWidth += $cw;
+ $CJKoverflow = true; // Set flag
+ continue;
+ }
+ /////////////////////
+ // 1b) Try squeezing another character(s) onto this line = Oikomi, if character cannot end line
+ // or next character cannot start line (and not splitting CJK numerals)
+ /////////////////////
+ // NB otherwise it move lastchar(s) to next line to keep $c company = Oidashi, which is done below in standard way
+ else if (preg_match("/[".$this->pregCJKchars."]/u",$checkchar) && $this->allowCJKorphans &&
+ (preg_match("/[".$this->CJKleading."]/u", $followingchar) || preg_match("/[".$this->CJKfollowing."]/u", $checkchar)) &&
+ !preg_match("/[".$this->CJKleading."]/u", $checkchar) && !preg_match("/[".$this->CJKfollowing."]/u", $followingchar) &&
+ !(preg_match("/[0-9\x{ff10}-\x{ff19}]/u", $followingchar) && preg_match("/[0-9\x{ff10}-\x{ff19}]/u", $checkchar))) {
+ // add character onto this line
+ $currContent .= $c;
+ $contentWidth += $cw;
+ $Oikomi = true; // Set flag
+ continue;
+ }
+ }
+/*-- END CJK-FONTS --*/
+/*-- HYPHENATION --*/
+ /////////////////////
+ // AUTOMATIC HYPHENATION
+ // 2) Automatic hyphen in current word (does not cross tags)
+ /////////////////////
+ if (isset($this->textparam['hyphens']) && $this->textparam['hyphens'] == 1 ) {
+ $currWord = '';
+ // Look back and ahead to get current word
+ for($ac = $charctr-1; $ac>=0; $ac--) {
+ if ($this->usingCoreFont) { $addc = substr($currContent,$ac,1); }
+ else { $addc = mb_substr($currContent,$ac,1,$this->mb_enc ); }
+ if ($addc == ' ') { break; }
+ $currWord = $addc.$currWord;
+ }
+ $start = $ac+1;
+ for($ac = $i; $ac<($clen-1); $ac++) {
+ if ($this->usingCoreFont) { $addc = substr($s,$ac,1); }
+ else { $addc = mb_substr($s,$ac,1,$this->mb_enc ); }
+ if ($addc == ' ') { break; }
+ $currWord .= $addc;
+ }
+ $ptr = $this->hyphenateWord($currWord, $charctr-$start);
+ if ($ptr>-1) {
+ $breakfound = array($contentctr, $start+$ptr, $contentctr, $start+$ptr, 'hyphen');
+ }
+ }
+/*-- END HYPHENATION --*/
+
+ // Search backwards to find first line-break opportunity
+ while ($breakfound==false && $prevchar !== false) {
+ $cutcontentctr = $contentctr;
+ $cutcharctr = $charctr;
+ $prevchar = $this->_moveToPrevChar($contentctr, $charctr, $content);
+ /////////////////////
+ // 3) Break at SPACE
+ /////////////////////
+ if ($prevchar == ' ') {
+ $breakfound = array($contentctr, $charctr, $cutcontentctr, $cutcharctr, 'discard');
+ }
+ /////////////////////
+ // 4) Break at U+200B in current word (Khmer, Lao & Thai Invisible word boundary, and Tibetan)
+ /////////////////////
+ else if ($prevchar == "\xe2\x80\x8b") { // U+200B Zero-width Word Break
+ $breakfound = array($contentctr, $charctr, $cutcontentctr, $cutcharctr, 'discard');
+ }
+ /////////////////////
+ // 5) Break at Hard HYPHEN '-' or U+2010
+ /////////////////////
+ else if (isset($this->textparam['hyphens']) && $this->textparam['hyphens'] != 2 && ($prevchar == '-' || $prevchar == "\xe2\x80\x90")) {
+ // Don't break a URL
+ // Look back to get first part of current word
+ $checkw = '';
+ for($ac = $charctr-1; $ac>=0; $ac--) {
+ if ($this->usingCoreFont) { $addc = substr($currContent,$ac,1); }
+ else { $addc = mb_substr($currContent,$ac,1,$this->mb_enc ); }
+ if ($addc == ' ') { break; }
+ $checkw = $addc.$checkw;
+ }
+ // Don't break if HyphenMinus AND (a URL or before a numeral or before a >)
+ if ((!preg_match('/(http:|ftp:|https:|www\.)/',$checkw) && $checkchar!='>' && !preg_match('/[0-9]/',$checkchar)) || $prevchar == "\xe2\x80\x90") {
+ $breakfound = array($cutcontentctr, $cutcharctr, $cutcontentctr, $cutcharctr, 'cut');
+ }
+ }
+ /////////////////////
+ // 6) Break at Soft HYPHEN (replace with hard hyphen)
+ /////////////////////
+ else if (isset($this->textparam['hyphens']) && $this->textparam['hyphens'] != 2 && !$this->usingCoreFont && $prevchar == "\xc2\xad") {
+ $breakfound = array($cutcontentctr, $cutcharctr, $cutcontentctr, $cutcharctr, 'cut');
+ $content[$contentctr] = mb_substr($content[$contentctr],0,$charctr,$this->mb_enc) . '-' . mb_substr($content[$contentctr],$charctr+1,mb_strlen($content[$contentctr]),$this->mb_enc);
+ if (!empty($cOTLdata[$contentctr])) {
+ $cOTLdata[$contentctr]['char_data'][$charctr] = array('bidi_class'=>9, 'uni'=>45);
+ $cOTLdata[$contentctr]['group'][$charctr] = 'C';
+ }
+ }
+ else if (isset($this->textparam['hyphens']) && $this->textparam['hyphens'] != 2 && $this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats' && $prevchar == chr(173)) {
+ $breakfound = array($cutcontentctr, $cutcharctr, $cutcontentctr, $cutcharctr, 'cut');
+ $content[$contentctr] = substr($content[$contentctr],0,$charctr) . '-' . substr($content[$contentctr],$charctr+1);
+ }
+/*-- CJK-FONTS --*/
+ /////////////////////
+ // 7) Break at CJK characters (unless forbidden characters to end or start line)
+ // CJK Avoiding line break in the middle of numerals
+ /////////////////////
+ else if (!$this->usingCoreFont && $this->checkCJK && preg_match("/[".$this->pregCJKchars."]/u",$checkchar) &&
+ !preg_match("/[".$this->CJKfollowing."]/u", $checkchar) && !preg_match("/[".$this->CJKleading."]/u", $prevchar) &&
+ !(preg_match("/[0-9\x{ff10}-\x{ff19}]/u", $prevchar) && preg_match("/[0-9\x{ff10}-\x{ff19}]/u", $checkchar))) {
+ $breakfound = array($cutcontentctr, $cutcharctr, $cutcontentctr, $cutcharctr, 'cut');
+ }
+/*-- END CJK-FONTS --*/
+ /////////////////////
+ // 8) Break at OBJECT (Break before all objects here - selected objects are moved forward to next line below e.g. dottab)
+ /////////////////////
+ if (isset($this->objectbuffer[$contentctr])) {
+ $breakfound = array($cutcontentctr, $cutcharctr, $cutcontentctr, $cutcharctr, 'cut');
+ }
+
+
+ $checkchar = $prevchar;
+ }
+
+ // If a line-break opportunity found:
+ if (is_array($breakfound)) {
+ $contentctr = $breakfound[0];
+ $charctr = $breakfound[1];
+ $cutcontentctr = $breakfound[2];
+ $cutcharctr = $breakfound[3];
+ $type = $breakfound[4];
+ // Cache chunks which are already processed, but now need to be passed on to the new line
+ for ($ix=count($content)-1;$ix>$cutcontentctr;$ix--) {
+ // save and crop off any subsequent chunks
+/*-- OTL --*/
+ if (!empty($sOTLdata)) {
+ $tmpOTL = array_pop($cOTLdata);
+ $savedPreOTLdata[] = $tmpOTL;
+ }
+/*-- END OTL --*/
+ $savedPreContent[] = array_pop($content);
+ $savedPreContentB[] = array_pop($contentB);
+ $savedPreFont[] = array_pop($font);
+ }
+
+ // Next cache the part which will start the next line
+ if ($this->usingCoreFont) {
+ $savedPreContent[] = substr($content[$cutcontentctr],$cutcharctr);
+ }
+ else {
+ $savedPreContent[] = mb_substr($content[$cutcontentctr],$cutcharctr,mb_strlen($content[$cutcontentctr]),$this->mb_enc);
+ }
+ $savedPreContentB[] = preg_replace('/L/','',$contentB[$cutcontentctr]);
+ $savedPreFont[] = $font[$cutcontentctr];
+/*-- OTL --*/
+ if (!empty($sOTLdata)) {
+ $savedPreOTLdata[] = $this->otl->splitOTLdata($cOTLdata[$cutcontentctr], $cutcharctr, $cutcharctr);
+ }
+/*-- END OTL --*/
+
+
+ // Finally adjust the Current content which ends this line
+ if ($cutcharctr == 0 && $type=='discard') {
+ array_pop($content);
+ array_pop($contentB);
+ array_pop($font);
+ array_pop($cOTLdata);
+ }
+
+ $currContent =& $content[ count( $content ) - 1 ];
+ if ($this->usingCoreFont) {
+ $currContent = substr($currContent,0,$charctr);
+ }
+ else {
+ $currContent = mb_substr($currContent,0,$charctr,$this->mb_enc);
+ }
+
+ if (!empty($sOTLdata)) {
+ $savedPreOTLdata[] = $this->otl->splitOTLdata($cOTLdata[(count($cOTLdata)-1)], mb_strlen($currContent,$this->mb_enc));
+ }
+
+ if (strpos($contentB[(count($contentB)-1)],'R')!==false) { // ???
+ $contentB[count($content)-1] = preg_replace('/R/','',$contentB[count($content)-1]); // ???
+ }
+
+ if ($type=='hyphen') {
+ $currContent .= '-';
+ if (!empty($cOTLdata[(count($cOTLdata)-1)])) {
+ $cOTLdata[(count($cOTLdata)-1)]['char_data'][] = array('bidi_class'=>9, 'uni'=>45);
+ $cOTLdata[(count($cOTLdata)-1)]['group'] .= 'C';
+ }
+ }
+
+ $savedContent = '';
+ $savedContentB = '';
+ $savedFont = array();
+ $savedOTLdata = array();
+
+
+ }
+ // If no line-break opportunity found - split at current position
+ // or - Next character ($c) is suitable to add as overhanging or squeezed punctuation, or Oikomi, as set above by:
+ // 1) CJK Overflowing a) punctuation or b) Oikomi
+ // in which case $breakfound==1 and NOT array
+
+ if (!is_array($breakfound)) {
+ $savedFont = $this->saveFont();
+ if (!empty($sOTLdata)) {
+ $savedOTLdata = $this->otl->splitOTLdata($cOTLdata[(count($cOTLdata)-1)], mb_strlen($currContent,$this->mb_enc));
+ }
+ }
+
+ if ($content[ count($content)-1 ] == '' && !isset($this->objectbuffer[ count($content)-1 ])) {
+ array_pop($content);
+ array_pop($contentB);
+ array_pop($font);
+ array_pop($cOTLdata);
+ $currContent =& $content[ count($content)-1 ];
+ }
+
+ // Right Trim current content - including CJK space, and for OTLdata
+ // incl. CJK - strip CJK space at end of line = \xe3\x80\x80 = CJK space
+ $currContent = rtrim( $currContent );
+ if ($this->checkCJK) { $currContent = preg_replace("/\xe3\x80\x80$/",'',$currContent) ; } // *CJK-FONTS*
+/*-- OTL --*/
+ if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
+ $this->otl->trimOTLdata($cOTLdata[count($cOTLdata)-1], false, true); // NB also does U+3000
+ }
+/*-- END OTL --*/
+
+
+ // Selected OBJECTS are moved forward to next line, unless they come before a space or U+200B (type='discard')
+ if (isset($this->objectbuffer[(count($content)-1)]) && (!isset($type) || $type != 'discard')) {
+ $objtype = $this->objectbuffer[(count($content)-1)]['type'];
+ if ($objtype=='dottab' || $objtype=='bookmark' || $objtype=='indexentry' || $objtype=='toc' || $objtype=='annot') {
+ $savedObj = array_pop( $this->objectbuffer );
+ }
+ }
+
+
+ // Decimal alignment (cancel if wraps to > 1 line)
+ if ($is_table && substr($align,0,1)=='D' ) { $align=substr($align,2,1); }
+
+ $lineBox = array();
+
+ $this->_setInlineBlockHeights($lineBox, $stackHeight, $content, $font, $is_table);
+
+ // update $contentWidth since it has changed with cropping
+ $contentWidth = 0;
+
+ $inclCursive=false;
+ foreach ( $content as $k => $chunk ) {
+ if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]) {
+ // LIST MARKERS
+ if ($this->objectbuffer[$k]['type'] == 'image' && isset($this->objectbuffer[$k]['listmarker']) && $this->objectbuffer[$k]['listmarker']) {
+ if ($this->objectbuffer[$k]['listmarkerposition'] != 'outside') {
+ $contentWidth += $this->objectbuffer[$k]['OUTER-WIDTH'] * _MPDFK;
+ }
+ }
+ else {
+ $contentWidth += $this->objectbuffer[$k]['OUTER-WIDTH'] * _MPDFK;
+ }
+ }
+ else if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
+ $this->restoreFont( $font[ $k ], false);
+ if ($this->checkCJK && $k == count($content)-1 && $CJKoverflow && $align=='J' && $this->allowCJKoverflow && $this->CJKforceend) {
+ // force-end overhang
+ $hanger = mb_substr($chunk,mb_strlen($chunk,$this->mb_enc)-1,1,$this->mb_enc );
+ // Probably ought to do something with char_data and GPOS in cOTLdata...
+ $content[$k] = $chunk = mb_substr($chunk,0,mb_strlen($chunk,$this->mb_enc)-1,$this->mb_enc );
+ }
+
+ // Soft Hyphens chr(173) + Replace NBSP with SPACE + Set inclcursive if includes CURSIVE TEXT
+ if (!$this->usingCoreFont) {
+/*-- OTL --*/
+ if ((isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) || !empty($sOTLdata)) {
+ $this->otl->removeChar($chunk, $cOTLdata[$k], "\xc2\xad");
+ $this->otl->replaceSpace($chunk, $cOTLdata[$k]); // NBSP -> space
+ if (preg_match("/([".$this->pregCURSchars."])/u", $chunk)) { $inclCursive = true; }
+ $content[$k] = $chunk;
+ }
+/*-- END OTL --*/
+ else { // *OTL*
+ $content[$k] = $chunk = str_replace("\xc2\xad",'',$chunk );
+ $content[$k] = $chunk = str_replace(chr(194).chr(160),chr(32),$chunk );
+ } // *OTL*
+ }
+ else if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
+ $content[$k] = $chunk = str_replace(chr(173),'',$chunk );
+ $content[$k] = $chunk = str_replace(chr(160),chr(32),$chunk );
+ }
+
+ $contentWidth += $this->GetStringWidth( $chunk, true, (isset($cOTLdata[$k]) ? $cOTLdata[$k] : false), $this->textvar ) * _MPDFK; // mPDF 5.7.1
+ if (!empty($this->spanborddet)) {
+ if (isset($this->spanborddet['L']['w']) && strpos($contentB[$k],'L')!==false) $contentWidth += $this->spanborddet['L']['w'] * _MPDFK;
+ if (isset($this->spanborddet['R']['w']) && strpos($contentB[$k],'R')!==false) $contentWidth += $this->spanborddet['R']['w'] * _MPDFK;
+ }
+ }
+
+ }
+
+ $lastfontreqstyle = (isset($font[count($font)-1]['ReqFontStyle']) ? $font[count($font)-1]['ReqFontStyle'] : '');
+ $lastfontstyle = (isset($font[count($font)-1]['style']) ? $font[count($font)-1]['style'] : '');
+ if ($blockdir == 'ltr' && strpos($lastfontreqstyle,"I") !== false && strpos($lastfontstyle,"I") === false) { // Artificial italic
+ $lastitalic = $this->FontSize*0.15*_MPDFK;
+ }
+ else { $lastitalic = 0; }
+
+
+
+
+ // NOW FORMAT THE LINE TO OUTPUT
+if (!$table_draft) {
+ // DIRECTIONALITY RTL
+ $chunkorder = range(0, count($content)-1); // mPDF 5.7
+/*-- OTL --*/
+ // mPDF 6
+ if ($blockdir == 'rtl' || $this->biDirectional) {
+ $this->otl->_bidiReorder($chunkorder, $content, $cOTLdata, $blockdir);
+ // From this point on, $content and $cOTLdata may contain more elements (and re-ordered) compared to
+ // $this->objectbuffer and $font ($chunkorder contains the mapping)
+ }
+
+/*-- END OTL --*/
+ // Remove any XAdvance from OTL data at end of line
+ foreach($chunkorder AS $aord=>$k) {
+ if (count($cOTLdata)) {
+ $this->restoreFont( $font[ $k ], false);
+ // ...WriteFlowingBlock...
+ if ($aord == count($chunkorder)-1 && isset($cOTLdata[$aord]['group'])) { // Last chunk on line
+ $nGPOS = strlen($cOTLdata[$aord]['group'])-1; // Last character
+ if (isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL']) || isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'])) {
+ if (isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'])) {
+ $w = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'] * 1000/$this->CurrentFont['unitsPerEm'];
+ }
+ else {
+ $w = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'] * 1000/$this->CurrentFont['unitsPerEm'];
+ }
+ $w *= ($this->FontSize/ 1000);
+ $contentWidth -= $w * _MPDFK;
+ $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'] = 0;
+ $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'] = 0;
+ }
+
+ // If last character has an XPlacement set, adjust width calculation, and add to XAdvance to account for it
+ if (isset($cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'])) {
+ $w = -$cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'] * 1000/$this->CurrentFont['unitsPerEm'];
+ $w *= ($this->FontSize/ 1000);
+ $contentWidth -= $w * _MPDFK;
+ $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceL'] = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'];
+ $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XAdvanceR'] = $cOTLdata[$aord]['GPOSinfo'][$nGPOS]['XPlacement'];
+ }
+
+ }
+ }
+ }
+
+ // JUSTIFICATION J
+ $jcharspacing = 0;
+ $jws = 0;
+ $nb_carac = 0;
+ $nb_spaces = 0;
+ $jkashida = 0;
+ // if it's justified, we need to find the char/word spacing (or if hanger $this->CJKforceend)
+ if ( ($align == 'J' && !$CJKoverflow) || (($contentWidth + $lastitalic > $maxWidth - $WidthCorrection - (($this->cMarginL+$this->cMarginR)*_MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) ) + 0.001) && (!$CJKoverflow || ($CJKoverflow && !$this->allowCJKoverflow))) || $CJKoverflow && $align=='J' && $this->allowCJKoverflow && $hanger && $this->CJKforceend) { // 0.001 is to correct for deviations converting mm=>pts
+
+ // JUSTIFY J (Use character spacing)
+ // WORD SPACING
+ foreach($chunkorder AS $aord=>$k) { // mPDF 5.7
+ $chunk = $content[$aord];
+ if (!isset($this->objectbuffer[$k]) || (isset($this->objectbuffer[$k]) && !$this->objectbuffer[$k])) {
+ $nb_carac += mb_strlen( $chunk, $this->mb_enc ) ;
+ $nb_spaces += mb_substr_count( $chunk,' ', $this->mb_enc ) ;
+ // Use GPOS OTL
+ if (isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF)) {
+ if (isset($cOTLdata[$aord]['group']) && $cOTLdata[$aord]['group']) {
+ $nb_carac -= substr_count($cOTLdata[$aord]['group'], 'M');
+ }
+ }
+ }
+ else { $nb_carac ++ ; } // mPDF 6 allow spacing for inline object
+ }
+ // GetJSpacing adds kashida spacing to GPOSinfo if appropriate for Font
+ list($jcharspacing,$jws,$jkashida) = $this->GetJspacing($nb_carac,$nb_spaces,($maxWidth-$lastitalic-$contentWidth-$WidthCorrection-(($this->cMarginL+$this->cMarginR)*_MPDFK)-($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) )),$inclCursive,$cOTLdata);
+ }
+
+ // WORD SPACING
+ $empty = $maxWidth - $lastitalic - $WidthCorrection - $contentWidth - (($this->cMarginL+$this->cMarginR)* _MPDFK) - ($paddingL+$paddingR +(($fpaddingL + $fpaddingR) * _MPDFK) );
+
+ $empty -= ($jcharspacing * ($nb_carac-1)); // mPDF 6 nb_carac MINUS 1
+ $empty -= ($jws * $nb_spaces);
+ $empty -= ($jkashida);
+ $empty /= _MPDFK;
+
+ $b = ''; //do not use borders
+ // Get PAGEBREAK TO TEST for height including the top border/padding
+ $check_h = max($this->divheight,$stackHeight);
+ if (($newblock) && ($blockstate==1 || $blockstate==3) && ($this->blklvl > 0) && ($lineCount == 1) && (!$is_table)) {
+ $check_h += ($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['border_top']['w']);
+ }
+
+ if ($this->ColActive && $check_h > ($this->PageBreakTrigger - $this->y0)) {
+ $this->SetCol($this->NbCol-1);
+ }
+
+ // PAGEBREAK
+ // 'If' below used in order to fix "first-line of other page with justify on" bug
+ if(!$is_table && ($this->y+$check_h) > $this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak()) {
+ $bak_x=$this->x;//Current X position
+
+ // WORD SPACING
+ $ws=$this->ws;//Word Spacing
+ $charspacing=$this->charspacing;//Character Spacing
+ $this->ResetSpacing();
+
+ $this->AddPage($this->CurOrientation);
+
+ $this->x = $bak_x;
+ // Added to correct for OddEven Margins
+ $currentx += $this->MarginCorrection;
+ $this->x += $this->MarginCorrection;
+
+ // WORD SPACING
+ $this->SetSpacing($charspacing,$ws);
+ }
+
+ if ($this->kwt && !$is_table) { // mPDF 5.7+
+ $this->printkwtbuffer();
+ $this->kwt = false;
+ }
+
+
+/*-- COLUMNS --*/
+ // COLS
+ // COLUMN CHANGE
+ if ($this->CurrCol != $oldcolumn) {
+ $currentx += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
+ $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
+ $oldcolumn = $this->CurrCol;
+ }
+
+ if ($this->ColActive && !$is_table) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
+/*-- END COLUMNS --*/
+
+ // TOP MARGIN
+ if (($newblock) && ($blockstate==1 || $blockstate==3) && ($this->blk[$this->blklvl]['margin_top']) && ($lineCount == 1) && (!$is_table)) {
+ $this->DivLn($this->blk[$this->blklvl]['margin_top'],$this->blklvl-1,true,$this->blk[$this->blklvl]['margin_collapse']);
+ if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
+ }
+
+
+ // Update y0 for top of block (used to paint border)
+ if (($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 1) && (!$is_table)) {
+ $this->blk[$this->blklvl]['y0'] = $this->y;
+ $this->blk[$this->blklvl]['startpage'] = $this->page;
+ if ($this->blk[$this->blklvl]['float']) { $this->blk[$this->blklvl]['float_start_y'] = $this->y; }
+ }
+
+ // TOP PADDING and BORDER spacing/fill
+ if (($newblock) && ($blockstate==1 || $blockstate==3) && (($this->blk[$this->blklvl]['padding_top']) || ($this->blk[$this->blklvl]['border_top'])) && ($lineCount == 1) && (!$is_table)) {
+ // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
+ $this->DivLn($this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'],-3,true,false,1);
+ if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
+ }
+
+ $arraysize = count($chunkorder);
+
+ $margins = ($this->cMarginL+$this->cMarginR) + ($ipaddingL+$ipaddingR + $fpaddingR + $fpaddingR );
+
+ // PAINT BACKGROUND FOR THIS LINE
+ if (!$is_table) { $this->DivLn($stackHeight,$this->blklvl,false); } // false -> don't advance y
+
+ $this->x = $currentx + $this->cMarginL + $ipaddingL + $fpaddingL ;
+ if ($align == 'R') { $this->x += $empty; }
+ else if ($align == 'C') { $this->x += ($empty / 2); }
+
+ // Paragraph INDENT
+ if (isset($this->blk[$this->blklvl]['text_indent']) && ($newblock) && ($blockstate==1 || $blockstate==3) && ($lineCount == 1) && (!$is_table) && ($blockdir !='rtl') && ($align !='C')) {
+ $ti = $this->ConvertSize($this->blk[$this->blklvl]['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->blk[$this->blklvl]['InlineProperties']['size'],false); // mPDF 5.7.4
+ $this->x += $ti;
+ }
+
+ // BIDI magic_reverse moved upwards from here
+
+ foreach($chunkorder AS $aord=>$k) { // mPDF 5.7
+ $chunk = $content[$aord];
+
+ if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]) {
+ $xadj = $this->x - $this->objectbuffer[$k]['OUTER-X'] ;
+ $this->objectbuffer[$k]['OUTER-X'] += $xadj;
+ $this->objectbuffer[$k]['BORDER-X'] += $xadj;
+ $this->objectbuffer[$k]['INNER-X'] += $xadj;
+
+ if ($this->objectbuffer[$k]['type'] == 'listmarker') {
+ $this->objectbuffer[$k]['lineBox'] = $lineBox[-1]; // Block element details for glyph-origin
+ }
+ $yadj = $this->y - $this->objectbuffer[$k]['OUTER-Y'];
+ if ($this->objectbuffer[$k]['type'] == 'dottab') { // mPDF 6 DOTTAB
+ $this->objectbuffer[$k]['lineBox'] = $lineBox[$k]; // element details for glyph-origin
+ }
+ if ($this->objectbuffer[$k]['type'] != 'dottab') { // mPDF 6 DOTTAB
+ $yadj += $lineBox[$k]['top'];
+ }
+ $this->objectbuffer[$k]['OUTER-Y'] += $yadj;
+ $this->objectbuffer[$k]['BORDER-Y'] += $yadj;
+ $this->objectbuffer[$k]['INNER-Y'] += $yadj;
+ }
+
+ $this->restoreFont( $font[ $k ] ); // mPDF 5.7
+
+ $this->SetSpacing(($this->fixedlSpacing*_MPDFK)+$jcharspacing,($this->fixedlSpacing+$this->minwSpacing)*_MPDFK+$jws);
+ // Now unset these values so they don't influence GetStringwidth below or in fn. Cell
+ $this->fixedlSpacing = false;
+ $this->minwSpacing = 0;
+
+ $save_vis = $this->visibility;
+ if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->textparam['visibility'] != $this->visibility) {
+ $this->SetVisibility($this->textparam['visibility']);
+ }
+ // *********** SPAN BACKGROUND COLOR ***************** //
+ if ($this->spanbgcolor) {
+ $cor = $this->spanbgcolorarray;
+ $this->SetFColor($cor);
+ $save_fill = $fill; $spanfill = 1; $fill = 1;
+ }
+ if (!empty($this->spanborddet)) {
+ if (strpos($contentB[$k],'L')!==false) $this->x += (isset($this->spanborddet['L']['w']) ? $this->spanborddet['L']['w'] : 0);
+ if (strpos($contentB[$k],'L')===false) $this->spanborddet['L']['s'] = $this->spanborddet['L']['w'] = 0;
+ if (strpos($contentB[$k],'R')===false) $this->spanborddet['R']['s'] = $this->spanborddet['R']['w'] = 0;
+ }
+
+ // WORD SPACING
+ // StringWidth this time includes any kashida spacing
+ $stringWidth = $this->GetStringWidth($chunk, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, true);
+
+ $nch = mb_strlen($chunk,$this->mb_enc );
+ // Use GPOS OTL
+ if (isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF)) {
+ if (isset($cOTLdata[$aord]['group']) && $cOTLdata[$aord]['group']) {
+ $nch -= substr_count($cOTLdata[$aord]['group'], 'M');
+ }
+ }
+ $stringWidth += ( $this->charspacing * $nch / _MPDFK );
+
+ $stringWidth += ( $this->ws * mb_substr_count($chunk,' ',$this->mb_enc ) / _MPDFK );
+
+ if (isset($this->objectbuffer[$k])) {
+ // LIST MARKERS // mPDF 6 Lists
+ if ($this->objectbuffer[$k]['type'] == 'image' && isset($this->objectbuffer[$k]['listmarker']) && $this->objectbuffer[$k]['listmarker'] && $this->objectbuffer[$k]['listmarkerposition'] == 'outside') {
+ $stringWidth = 0;
+ }
+ else {
+ $stringWidth = $this->objectbuffer[$k]['OUTER-WIDTH'];
+ }
+ }
+
+ if ($stringWidth==0) { $stringWidth = 0.000001; }
+
+ if ($aord == $arraysize-1) {
+ $stringWidth -= ( $this->charspacing / _MPDFK );
+ if ($this->checkCJK && $CJKoverflow && $align=='J' && $this->allowCJKoverflow && $hanger && $this->CJKforceend) {
+ // force-end overhang
+ $this->Cell( $stringWidth, $stackHeight, $chunk, '', 0, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false));
+ $this->Cell( $this->GetStringWidth($hanger), $stackHeight, $hanger, '', 1, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false));
+ }
+ else {
+ $this->Cell( $stringWidth, $stackHeight, $chunk, '', 1, '', $fill, $this->HREF, $currentx,0,0,'M', $fill, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false)); //mono-style line or last part (skips line)
+ }
+
+ }
+ else $this->Cell( $stringWidth, $stackHeight, $chunk, '', 0, '', $fill, $this->HREF, 0, 0,0,'M', $fill, true, (isset($cOTLdata[$aord]) ? $cOTLdata[$aord] : false), $this->textvar, (isset($lineBox[$k]) ? $lineBox[$k] : false));//first or middle part
+
+ if (!empty($this->spanborddet)) {
+ if (strpos($contentB[$k],'R')!==false && $aord != $arraysize-1) $this->x += $this->spanborddet['R']['w'];
+ }
+ // *********** SPAN BACKGROUND COLOR OFF - RESET BLOCK BGCOLOR ***************** //
+ if (isset($spanfill) && $spanfill) {
+ $fill = $save_fill; $spanfill = 0;
+ if ($fill) { $this->SetFColor($bcor); }
+ }
+ if (isset($this->textparam['visibility']) && $this->textparam['visibility'] && $this->visibility != $save_vis) {
+ $this->SetVisibility($save_vis);
+ }
+
+ }
+}
+else if ($table_draft) { $this->y += $stackHeight; }
+
+ if (!$is_table) {
+ $this->maxPosR = max($this->maxPosR , ($this->w - $this->rMargin - $this->blk[$this->blklvl]['outer_right_margin']));
+ $this->maxPosL = min($this->maxPosL , ($this->lMargin + $this->blk[$this->blklvl]['outer_left_margin']));
+ }
+
+ // move on to the next line, reset variables, tack on saved content and current char
+
+ if (!$table_draft) $this->printobjectbuffer($is_table, $blockdir);
+ $this->objectbuffer = array();
+
+
+/*-- CSS-IMAGE-FLOAT --*/
+ // Update values if set to skipline
+ if ($this->floatmargins) { $this->_advanceFloatMargins(); }
+/*-- END CSS-IMAGE-FLOAT --*/
+
+ // Reset lineheight
+ $stackHeight = $this->divheight;
+ $valign = 'M';
+
+ $font = array();
+ $content = array();
+ $contentB = array();
+ $cOTLdata = array(); // mPDF 5.7.1
+ $contentWidth = 0;
+ if (!empty($savedObj)) {
+ $this->objectbuffer[] = $savedObj;
+ $font[] = $savedFont;
+ $content[] = '';
+ $contentB[] = '';
+ $cOTLdata[] = array(); // mPDF 5.7.1
+ $contentWidth += $savedObj['OUTER-WIDTH'] * _MPDFK;
+ }
+ if (count($savedPreContent) > 0) {
+ for($ix=count($savedPreContent)-1;$ix>=0;$ix--) {
+ $font[] = $savedPreFont[$ix];
+ $content[] = $savedPreContent[$ix];
+ $contentB[] = $savedPreContentB[$ix];
+ if (!empty($sOTLdata)) {
+ $cOTLdata[] = $savedPreOTLdata[$ix];
+ }
+ $this->restoreFont( $savedPreFont[$ix] );
+ $lbw = $rbw = 0; // Border widths
+ if (!empty($this->spanborddet)) {
+ $lbw = (isset($this->spanborddet['L']['w']) ? $this->spanborddet['L']['w'] : 0);
+ $rbw = (isset($this->spanborddet['R']['w']) ? $this->spanborddet['R']['w'] : 0);
+ }
+ if ($ix>0) {
+ $contentWidth += $this->GetStringWidth( $savedPreContent[$ix], true, (isset($savedPreOTLdata[$ix]) ? $savedPreOTLdata[$ix] : false), $this->textvar ) * _MPDFK; // mPDF 5.7.1
+ if (strpos($savedPreContentB[$ix],'L')!==false) $contentWidth += $lbw;
+ if (strpos($savedPreContentB[$ix],'R')!==false) $contentWidth += $rbw;
+ }
+ }
+ $savedPreContent = array();
+ $savedPreContentB = array();
+ $savedPreOTLdata = array(); // mPDF 5.7.1
+ $savedPreFont = array();
+ $content[ (count($content)-1) ] .= $c;
+ }
+ else {
+ $font[] = $savedFont;
+ $content[] = $savedContent . $c;
+ $contentB[] = $savedContentB ;
+ $cOTLdata[] = $savedOTLdata; // mPDF 5.7.1
+ }
+
+ $currContent =& $content[ (count($content)-1) ];
+ $this->restoreFont( $font[ (count($font)-1) ]); // mPDF 6.0
+
+/*-- CJK-FONTS --*/
+ // CJK - strip CJK space at start of line
+ // = \xe3\x80\x80 = CJK space
+ if ($this->checkCJK && $currContent == "\xe3\x80\x80") {
+ $currContent = '';
+ if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
+ $this->otl->trimOTLdata($cOTLdata[count($cOTLdata)-1], true, false); // left trim U+3000
+ }
+ }
+/*-- END CJK-FONTS --*/
+
+ $lbw = $rbw = 0; // Border widths
+ if (!empty($this->spanborddet)) {
+ $lbw = (isset($this->spanborddet['L']['w']) ? $this->spanborddet['L']['w'] : 0);
+ $rbw = (isset($this->spanborddet['R']['w']) ? $this->spanborddet['R']['w'] : 0);
+ }
+
+ $contentWidth += $this->GetStringWidth( $currContent, false, (isset($cOTLdata[(count($cOTLdata)-1)]) ? $cOTLdata[(count($cOTLdata)-1)] : false), $this->textvar ) * _MPDFK; // mPDF 5.7.1
+ if (strpos($savedContentB,'L')!==false) $contentWidth += $lbw;
+ $CJKoverflow = false;
+ $hanger = '';
+ }
+ // another character will fit, so add it on
+ else {
+ $contentWidth += $cw;
+ $currContent .= $c;
+ }
+ }
+
+ unset($content);
+ unset($contentB);
+}
+//----------------------END OF FLOWING BLOCK------------------------------------//
+
+
+/*-- CSS-IMAGE-FLOAT --*/
+// Update values if set to skipline
+function _advanceFloatMargins() {
+ // Update floatmargins - L
+ if (isset($this->floatmargins['L']) && $this->floatmargins['L']['skipline'] && $this->floatmargins['L']['y0'] != $this->y) {
+ $yadj = $this->y - $this->floatmargins['L']['y0'];
+ $this->floatmargins['L']['y0'] = $this->y;
+ $this->floatmargins['L']['y1'] += $yadj;
+
+ // Update objattr in floatbuffer
+ if ($this->floatbuffer[$this->floatmargins['L']['id']]['border_left']['w']) {
+ $this->floatbuffer[$this->floatmargins['L']['id']]['BORDER-Y'] += $yadj;
+ }
+ $this->floatbuffer[$this->floatmargins['L']['id']]['INNER-Y'] += $yadj;
+ $this->floatbuffer[$this->floatmargins['L']['id']]['OUTER-Y'] += $yadj;
+
+ // Unset values
+ $this->floatbuffer[$this->floatmargins['L']['id']]['skipline'] = false;
+ $this->floatmargins['L']['skipline'] = false;
+ $this->floatmargins['L']['id'] = '';
+ }
+ // Update floatmargins - R
+ if (isset($this->floatmargins['R']) && $this->floatmargins['R']['skipline'] && $this->floatmargins['R']['y0'] != $this->y) {
+ $yadj = $this->y - $this->floatmargins['R']['y0'];
+ $this->floatmargins['R']['y0'] = $this->y;
+ $this->floatmargins['R']['y1'] += $yadj;
+
+ // Update objattr in floatbuffer
+ if ($this->floatbuffer[$this->floatmargins['R']['id']]['border_left']['w']) {
+ $this->floatbuffer[$this->floatmargins['R']['id']]['BORDER-Y'] += $yadj;
+ }
+ $this->floatbuffer[$this->floatmargins['R']['id']]['INNER-Y'] += $yadj;
+ $this->floatbuffer[$this->floatmargins['R']['id']]['OUTER-Y'] += $yadj;
+
+ // Unset values
+ $this->floatbuffer[$this->floatmargins['R']['id']]['skipline'] = false;
+ $this->floatmargins['R']['skipline'] = false;
+ $this->floatmargins['R']['id'] = '';
+ }
+}
+/*-- END CSS-IMAGE-FLOAT --*/
+
+
+
+/*-- END HTML-CSS --*/
+
+function _SetTextRendering($mode) {
+ if (!(($mode == 0) || ($mode == 1) || ($mode == 2)))
+ $this->Error("Text rendering mode should be 0, 1 or 2 (value : $mode)");
+ $tr = ($mode.' Tr');
+ if($this->page>0 && ((isset($this->pageoutput[$this->page]['TextRendering']) && $this->pageoutput[$this->page]['TextRendering'] != $tr) || !isset($this->pageoutput[$this->page]['TextRendering']))) { $this->_out($tr); }
+ $this->pageoutput[$this->page]['TextRendering'] = $tr;
+
+}
+
+function SetTextOutline($params=array()) {
+ if (isset($params['outline-s']) && $params['outline-s'])
+ {
+ $this->SetLineWidth($params['outline-WIDTH']);
+ $this->SetDColor($params['outline-COLOR']);
+ $tr = ('2 Tr');
+ if($this->page>0 && ((isset($this->pageoutput[$this->page]['TextRendering']) && $this->pageoutput[$this->page]['TextRendering'] != $tr) || !isset($this->pageoutput[$this->page]['TextRendering']))) { $this->_out($tr); }
+ $this->pageoutput[$this->page]['TextRendering'] = $tr;
+ }
+ else //Now resets all values
+ {
+ $this->SetLineWidth(0.2);
+ $this->SetDColor($this->ConvertColor(0));
+ $this->_SetTextRendering(0);
+ $tr = ('0 Tr');
+ if($this->page>0 && ((isset($this->pageoutput[$this->page]['TextRendering']) && $this->pageoutput[$this->page]['TextRendering'] != $tr) || !isset($this->pageoutput[$this->page]['TextRendering']))) { $this->_out($tr); }
+ $this->pageoutput[$this->page]['TextRendering'] = $tr;
+ }
+}
+
+function Image($file,$x,$y,$w=0,$h=0,$type='',$link='',$paint=true, $constrain=true, $watermark=false, $shownoimg=true, $allowvector=true) {
+ $orig_srcpath = $file;
+ $this->GetFullPath($file);
+
+ $info=$this->_getImage($file, true, $allowvector, $orig_srcpath );
+ if(!$info && $paint) {
+ $info = $this->_getImage($this->noImageFile);
+ if ($info) {
+ $file = $this->noImageFile;
+ $w = ($info['w'] * (25.4/$this->dpi)); // 14 x 16px
+ $h = ($info['h'] * (25.4/$this->dpi)); // 14 x 16px
+ }
+ }
+ if(!$info) return false;
+ //Automatic width and height calculation if needed
+ if($w==0 and $h==0) {
+/*-- IMAGES-WMF --*/
+ if ($info['type']=='wmf') {
+ // WMF units are twips (1/20pt)
+ // divide by 20 to get points
+ // divide by k to get user units
+ $w = abs($info['w'])/(20*_MPDFK);
+ $h = abs($info['h']) / (20*_MPDFK);
+ }
+ else
+/*-- END IMAGES-WMF --*/
+ if ($info['type']=='svg') {
+ // returned SVG units are pts
+ // divide by k to get user units (mm)
+ $w = abs($info['w'])/_MPDFK;
+ $h = abs($info['h']) /_MPDFK;
+ }
+ else {
+ //Put image at default image dpi
+ $w=($info['w']/_MPDFK) * (72/$this->img_dpi);
+ $h=($info['h']/_MPDFK) * (72/$this->img_dpi);
+ }
+ }
+ if($w==0) $w=abs($h*$info['w']/$info['h']);
+ if($h==0) $h=abs($w*$info['h']/$info['w']);
+
+/*-- WATERMARK --*/
+ if ($watermark) {
+ $maxw = $this->w;
+ $maxh = $this->h;
+ // Size = D PF or array
+ if (is_array($this->watermark_size)) {
+ $w = $this->watermark_size[0];
+ $h = $this->watermark_size[1];
+ }
+ else if (!is_string($this->watermark_size)) {
+ $maxw -= $this->watermark_size*2;
+ $maxh -= $this->watermark_size*2;
+ $w = $maxw;
+ $h=abs($w*$info['h']/$info['w']);
+ if ($h > $maxh ) {
+ $h = $maxh ; $w=abs($h*$info['w']/$info['h']);
+ }
+ }
+ else if ($this->watermark_size == 'F') {
+ if ($this->ColActive) { $maxw = $this->w - ($this->DeflMargin + $this->DefrMargin); }
+ else { $maxw = $this->pgwidth; }
+ $maxh = $this->h - ($this->tMargin + $this->bMargin);
+ $w = $maxw;
+ $h=abs($w*$info['h']/$info['w']);
+ if ($h > $maxh ) {
+ $h = $maxh ; $w=abs($h*$info['w']/$info['h']);
+ }
+ }
+ else if ($this->watermark_size == 'P') { // Default P
+ $w = $maxw;
+ $h=abs($w*$info['h']/$info['w']);
+ if ($h > $maxh ) {
+ $h = $maxh ; $w=abs($h*$info['w']/$info['h']);
+ }
+ }
+ // Automatically resize to maximum dimensions of page if too large
+ if ($w > $maxw) {
+ $w = $maxw;
+ $h=abs($w*$info['h']/$info['w']);
+ }
+ if ($h > $maxh ) {
+ $h = $maxh ;
+ $w=abs($h*$info['w']/$info['h']);
+ }
+ // Position
+ if (is_array($this->watermark_pos)) {
+ $x = $this->watermark_pos[0];
+ $y = $this->watermark_pos[1];
+ }
+ else if ($this->watermark_pos == 'F') { // centred on printable area
+ if ($this->ColActive) { // *COLUMNS*
+ if (($this->mirrorMargins) && (($this->page)%2==0)) { $xadj = $this->DeflMargin-$this->DefrMargin; } // *COLUMNS*
+ else { $xadj = 0; } // *COLUMNS*
+ $x = ($this->DeflMargin - $xadj + ($this->w - ($this->DeflMargin + $this->DefrMargin))/2) - ($w/2); // *COLUMNS*
+ } // *COLUMNS*
+ else { // *COLUMNS*
+ $x = ($this->lMargin + ($this->pgwidth)/2) - ($w/2);
+ } // *COLUMNS*
+ $y = ($this->tMargin + ($this->h - ($this->tMargin + $this->bMargin))/2) - ($h/2);
+ }
+ else { // default P - centred on whole page
+ $x = ($this->w/2) - ($w/2);
+ $y = ($this->h/2) - ($h/2);
+ }
+/*-- IMAGES-WMF --*/
+ if ($info['type']=='wmf') {
+ $sx = $w*_MPDFK / $info['w'];
+ $sy = -$h*_MPDFK / $info['h'];
+ $outstring = sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, $sy, $x*_MPDFK-$sx*$info['x'], (($this->h-$y)*_MPDFK)-$sy*$info['y'], $info['i']);
+ }
+ else
+/*-- END IMAGES-WMF --*/
+ if ($info['type']=='svg') {
+ $sx = $w*_MPDFK / $info['w'];
+ $sy = -$h*_MPDFK / $info['h'];
+ $outstring = sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, $sy, $x*_MPDFK-$sx*$info['x'], (($this->h-$y)*_MPDFK)-$sy*$info['y'], $info['i']);
+ }
+ else {
+ $outstring = sprintf("q %.3F 0 0 %.3F %.3F %.3F cm /I%d Do Q",$w*_MPDFK,$h*_MPDFK,$x*_MPDFK,($this->h-($y+$h))*_MPDFK,$info['i']);
+ }
+
+ if ($this->watermarkImgBehind) {
+ $outstring = $this->watermarkImgAlpha . "\n" . $outstring . "\n" . $this->SetAlpha(1, 'Normal', true) . "\n";
+ $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', "\n".$outstring."\n".'\\1', $this->pages[$this->page]);
+ }
+ else { $this->_out($outstring); }
+
+ return 0;
+ } // end of IF watermark
+/*-- END WATERMARK --*/
+
+ if ($constrain) {
+ // Automatically resize to maximum dimensions of page if too large
+ if (isset($this->blk[$this->blklvl]['inner_width']) && $this->blk[$this->blklvl]['inner_width']) { $maxw = $this->blk[$this->blklvl]['inner_width']; }
+ else { $maxw = $this->pgwidth; }
+ if ($w > $maxw) {
+ $w = $maxw;
+ $h=abs($w*$info['h']/$info['w']);
+ }
+ if ($h > $this->h - ($this->tMargin + $this->bMargin + 1)) { // see below - +10 to avoid drawing too close to border of page
+ $h = $this->h - ($this->tMargin + $this->bMargin + 1) ;
+ if ($this->fullImageHeight) { $h = $this->fullImageHeight; }
+ $w=abs($h*$info['w']/$info['h']);
+ }
+
+
+ //Avoid drawing out of the paper(exceeding width limits).
+ //if ( ($x + $w) > $this->fw ) {
+ if ( ($x + $w) > $this->w ) {
+ $x = $this->lMargin;
+ $y += 5;
+ }
+
+ $changedpage = false;
+ $oldcolumn = $this->CurrCol;
+ //Avoid drawing out of the page.
+ if($y+$h>$this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak()) {
+ $this->AddPage($this->CurOrientation);
+ // Added to correct for OddEven Margins
+ $x=$x +$this->MarginCorrection;
+ $y = $this->tMargin; // mPDF 5.7.3
+ $changedpage = true;
+ }
+/*-- COLUMNS --*/
+ // COLS
+ // COLUMN CHANGE
+ if ($this->CurrCol != $oldcolumn) {
+ $y = $this->y0;
+ $x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
+ $this->x += $this->ChangeColumn * ($this->ColWidth+$this->ColGap);
+ }
+/*-- END COLUMNS --*/
+ } // end of IF constrain
+
+/*-- IMAGES-WMF --*/
+ if ($info['type']=='wmf') {
+ $sx = $w*_MPDFK / $info['w'];
+ $sy = -$h*_MPDFK / $info['h'];
+ $outstring = sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, $sy, $x*_MPDFK-$sx*$info['x'], (($this->h-$y)*_MPDFK)-$sy*$info['y'], $info['i']);
+ }
+ else
+/*-- END IMAGES-WMF --*/
+ if ($info['type']=='svg') {
+ $sx = $w*_MPDFK / $info['w'];
+ $sy = -$h*_MPDFK / $info['h'];
+ $outstring = sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $sx, $sy, $x*_MPDFK-$sx*$info['x'], (($this->h-$y)*_MPDFK)-$sy*$info['y'], $info['i']);
+ }
+ else {
+ $outstring = sprintf("q %.3F 0 0 %.3F %.3F %.3F cm /I%d Do Q",$w*_MPDFK,$h*_MPDFK,$x*_MPDFK,($this->h-($y+$h))*_MPDFK,$info['i']);
+ }
+
+ if($paint) {
+ $this->_out($outstring);
+ if($link) $this->Link($x,$y,$w,$h,$link);
+
+ // Avoid writing text on top of the image. // THIS WAS OUTSIDE THE if ($paint) bit!!!!!!!!!!!!!!!!
+ $this->y = $y + $h;
+ }
+
+ //Return width-height array
+ $sizesarray['WIDTH'] = $w;
+ $sizesarray['HEIGHT'] = $h;
+ $sizesarray['X'] = $x; //Position before painting image
+ $sizesarray['Y'] = $y; //Position before painting image
+ $sizesarray['OUTPUT'] = $outstring;
+
+ $sizesarray['IMAGE_ID'] = $info['i'];
+ $sizesarray['itype'] = $info['type'];
+ $sizesarray['set-dpi'] = (isset($info['set-dpi']) ? $info['set-dpi'] : 0);
+ return $sizesarray;
+}
+
+
+
+//=============================================================
+//=============================================================
+//=============================================================
+//=============================================================
+//=============================================================
+/*-- HTML-CSS --*/
+
+function _getObjAttr($t) {
+ $c = explode("\xbb\xa4\xac",$t,2);
+ $c = explode(",",$c[1],2);
+ foreach($c as $v) {
+ $v = explode("=",$v,2);
+ $sp[$v[0]] = $v[1];
+ }
+ return (unserialize($sp['objattr']));
+}
+
+
+function inlineObject($type,$x,$y,$objattr,$Lmargin,$widthUsed,$maxWidth,$lineHeight,$paint=false,$is_table=false)
+{
+ if ($is_table) { $k = $this->shrin_k; } else { $k = 1; }
+
+ // NB $x is only used when paint=true
+ // Lmargin not used
+ $w = 0;
+ if (isset($objattr['width'])) { $w = $objattr['width']/$k; }
+ $h = 0;
+ if (isset($objattr['height'])) { $h = abs($objattr['height']/$k); }
+ $widthLeft = $maxWidth - $widthUsed;
+ $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 10) ;
+ if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
+ // For Images
+ if (isset($objattr['border_left'])) {
+ $extraWidth = ($objattr['border_left']['w'] + $objattr['border_right']['w'] + $objattr['margin_left']+ $objattr['margin_right'])/$k;
+ $extraHeight = ($objattr['border_top']['w'] + $objattr['border_bottom']['w'] + $objattr['margin_top']+ $objattr['margin_bottom'])/$k;
+
+ if ($type == 'image' || $type == 'barcode' || $type == 'textcircle') {
+ $extraWidth += ($objattr['padding_left'] + $objattr['padding_right'])/$k;
+ $extraHeight += ($objattr['padding_top'] + $objattr['padding_bottom'])/$k;
+ }
+ }
+
+ if (!isset($objattr['vertical-align'])) {
+ if ($objattr['type'] == 'select') { $objattr['vertical-align'] = 'M'; }
+ else { $objattr['vertical-align'] = 'BS'; }
+ } // mPDF 6
+
+ if ($type == 'image' || (isset($objattr['subtype']) && $objattr['subtype'] == 'IMAGE')) {
+ if (isset($objattr['itype']) && ($objattr['itype'] == 'wmf' || $objattr['itype'] == 'svg')) {
+ $file = $objattr['file'];
+ $info=$this->formobjects[$file];
+ }
+ else if (isset($objattr['file'])) {
+ $file = $objattr['file'];
+ $info=$this->images[$file];
+ }
+ }
+ if ($type == 'annot' || $type == 'bookmark' || $type == 'indexentry' || $type == 'toc') {
+ $w = 0.00001;
+ $h = 0.00001;
+ }
+
+ // TEST whether need to skipline
+ if (!$paint) {
+ if ($type == 'hr') { // always force new line
+ if (($y + $h + $lineHeight > $this->PageBreakTrigger) && !$this->InFooter && !$is_table) { return array(-2, $w ,$h ); } // New page + new line
+ else { return array(1, $w ,$h ); } // new line
+ }
+ else {
+ // LIST MARKERS // mPDF 6 Lists
+ $displayheight = $h; $displaywidth = $w;
+ if ($objattr['type'] == 'image' && isset($objattr['listmarker']) && $objattr['listmarker']) {
+ $displayheight = 0;
+ if ($objattr['listmarkerposition'] == 'outside') { $displaywidth = 0; }
+ }
+
+ if ($widthUsed > 0 && $displaywidth > $widthLeft && (!$is_table || $type != 'image')) { // New line needed
+ // mPDF 6 Lists
+ if (($y + $displayheight + $lineHeight > $this->PageBreakTrigger) && !$this->InFooter) { return array(-2,$w ,$h ); } // New page + new line
+ return array(1,$w ,$h ); // new line
+ }
+ else if ($widthUsed > 0 && $displaywidth > $widthLeft && $is_table) { // New line needed in TABLE
+ return array(1,$w ,$h ); // new line
+ }
+ // Will fit on line but NEW PAGE REQUIRED
+ else if (($y + $displayheight > $this->PageBreakTrigger) && !$this->InFooter && !$is_table) { return array(-1,$w ,$h ); } // mPDF 6 Lists
+ else { return array(0,$w ,$h ); }
+ }
+ }
+
+ if ($type == 'annot' || $type == 'bookmark' || $type == 'indexentry' || $type == 'toc') {
+ $w = 0.00001;
+ $h = 0.00001;
+ $objattr['BORDER-WIDTH'] = 0;
+ $objattr['BORDER-HEIGHT'] = 0;
+ $objattr['BORDER-X'] = $x;
+ $objattr['BORDER-Y'] = $y;
+ $objattr['INNER-WIDTH'] = 0;
+ $objattr['INNER-HEIGHT'] = 0;
+ $objattr['INNER-X'] = $x;
+ $objattr['INNER-Y'] = $y;
+ }
+
+ if ($type == 'image') {
+ // Automatically resize to width remaining
+ if ($w > ($widthLeft + 0.0001) && !$is_table ) { // mPDF 5.7.4 0.0001 to allow for rounding errors when w==maxWidth
+ $w = $widthLeft ;
+ $h=abs($w*$info['h']/$info['w']);
+ }
+ $img_w = $w - $extraWidth ;
+ $img_h = $h - $extraHeight ;
+
+ $objattr['BORDER-WIDTH'] = $img_w + $objattr['padding_left']/$k + $objattr['padding_right']/$k + (($objattr['border_left']['w']/$k + $objattr['border_right']['w']/$k)/2) ;
+ $objattr['BORDER-HEIGHT'] = $img_h + $objattr['padding_top']/$k + $objattr['padding_bottom']/$k + (($objattr['border_top']['w']/$k + $objattr['border_bottom']['w']/$k)/2) ;
+ $objattr['BORDER-X'] = $x + $objattr['margin_left']/$k + (($objattr['border_left']['w']/$k)/2) ;
+ $objattr['BORDER-Y'] = $y + $objattr['margin_top']/$k + (($objattr['border_top']['w']/$k)/2) ;
+ $objattr['INNER-WIDTH'] = $img_w;
+ $objattr['INNER-HEIGHT'] = $img_h;
+ $objattr['INNER-X'] = $x + $objattr['padding_left']/$k + $objattr['margin_left']/$k + ($objattr['border_left']['w']/$k);
+ $objattr['INNER-Y'] = $y + $objattr['padding_top']/$k + $objattr['margin_top']/$k + ($objattr['border_top']['w']/$k) ;
+ $objattr['ID'] = $info['i'];
+ }
+
+ if ($type == 'input' && $objattr['subtype'] == 'IMAGE') {
+ $img_w = $w - $extraWidth ;
+ $img_h = $h - $extraHeight ;
+ $objattr['BORDER-WIDTH'] = $img_w + (($objattr['border_left']['w']/$k + $objattr['border_right']['w']/$k)/2) ;
+ $objattr['BORDER-HEIGHT'] = $img_h + (($objattr['border_top']['w']/$k + $objattr['border_bottom']['w']/$k)/2) ;
+ $objattr['BORDER-X'] = $x + $objattr['margin_left']/$k + (($objattr['border_left']['w']/$k)/2) ;
+ $objattr['BORDER-Y'] = $y + $objattr['margin_top']/$k + (($objattr['border_top']['w']/$k)/2) ;
+ $objattr['INNER-WIDTH'] = $img_w;
+ $objattr['INNER-HEIGHT'] = $img_h;
+ $objattr['INNER-X'] = $x + $objattr['margin_left']/$k + ($objattr['border_left']['w']/$k);
+ $objattr['INNER-Y'] = $y + $objattr['margin_top']/$k + ($objattr['border_top']['w']/$k) ;
+ $objattr['ID'] = $info['i'];
+ }
+
+ if ($type == 'barcode' || $type == 'textcircle') {
+ $b_w = $w - $extraWidth ;
+ $b_h = $h - $extraHeight ;
+ $objattr['BORDER-WIDTH'] = $b_w + $objattr['padding_left']/$k + $objattr['padding_right']/$k + (($objattr['border_left']['w']/$k + $objattr['border_right']['w']/$k)/2) ;
+ $objattr['BORDER-HEIGHT'] = $b_h + $objattr['padding_top']/$k + $objattr['padding_bottom']/$k + (($objattr['border_top']['w']/$k + $objattr['border_bottom']['w']/$k)/2) ;
+ $objattr['BORDER-X'] = $x + $objattr['margin_left']/$k + (($objattr['border_left']['w']/$k)/2) ;
+ $objattr['BORDER-Y'] = $y + $objattr['margin_top']/$k + (($objattr['border_top']['w']/$k)/2) ;
+ $objattr['INNER-X'] = $x + $objattr['padding_left']/$k + $objattr['margin_left']/$k + ($objattr['border_left']['w']/$k);
+ $objattr['INNER-Y'] = $y + $objattr['padding_top']/$k + $objattr['margin_top']/$k + ($objattr['border_top']['w']/$k) ;
+ $objattr['INNER-WIDTH'] = $b_w;
+ $objattr['INNER-HEIGHT'] = $b_h;
+ }
+
+
+ if ($type == 'textarea') {
+ // Automatically resize to width remaining
+ if ($w > $widthLeft && !$is_table) {
+ $w = $widthLeft ;
+ }
+ // This used to resize height to maximum remaining on page ? why. Causes problems when in table and causing a new column
+// if (($y + $h > $this->PageBreakTrigger) && !$this->InFooter) {
+// $h=$this->h - $y - $this->bMargin;
+// }
+ }
+
+ if ($type == 'hr') {
+ if ($is_table) {
+ $objattr['INNER-WIDTH'] = $maxWidth * $objattr['W-PERCENT']/100;
+ $objattr['width'] = $objattr['INNER-WIDTH'];
+ $w = $maxWidth;
+ }
+ else {
+ if ($w>$maxWidth) { $w = $maxWidth; }
+ $objattr['INNER-WIDTH'] = $w;
+ $w = $maxWidth;
+ }
+ }
+
+
+
+ if (($type == 'select') || ($type == 'input' && ($objattr['subtype'] == 'TEXT' || $objattr['subtype'] == 'PASSWORD'))) {
+ // Automatically resize to width remaining
+ if ($w > $widthLeft && !$is_table) {
+ $w = $widthLeft;
+ }
+ }
+
+ if ($type == 'textarea' || $type == 'select' || $type == 'input') {
+ if (isset($objattr['fontsize'])) $objattr['fontsize'] /= $k;
+ if (isset($objattr['linewidth'])) $objattr['linewidth'] /= $k;
+ }
+
+ if (!isset($objattr['BORDER-Y'])) { $objattr['BORDER-Y'] = 0; }
+ if (!isset($objattr['BORDER-X'])) { $objattr['BORDER-X'] = 0; }
+ if (!isset($objattr['INNER-Y'])) { $objattr['INNER-Y'] = 0; }
+ if (!isset($objattr['INNER-X'])) { $objattr['INNER-X'] = 0; }
+
+ //Return width-height array
+ $objattr['OUTER-WIDTH'] = $w;
+ $objattr['OUTER-HEIGHT'] = $h;
+ $objattr['OUTER-X'] = $x;
+ $objattr['OUTER-Y'] = $y;
+ return $objattr;
+}
+
+/*-- END HTML-CSS --*/
+
+//=============================================================
+//=============================================================
+//=============================================================
+//=============================================================
+//=============================================================
+
+function SetLineJoin($mode=0)
+{
+ $s=sprintf('%d j',$mode);
+ if($this->page>0 && ((isset($this->pageoutput[$this->page]['LineJoin']) && $this->pageoutput[$this->page]['LineJoin'] != $s) || !isset($this->pageoutput[$this->page]['LineJoin']))) { $this->_out($s); }
+ $this->pageoutput[$this->page]['LineJoin'] = $s;
+
+}
+function SetLineCap($mode=2) {
+ $s=sprintf('%d J',$mode);
+ if($this->page>0 && ((isset($this->pageoutput[$this->page]['LineCap']) && $this->pageoutput[$this->page]['LineCap'] != $s) || !isset($this->pageoutput[$this->page]['LineCap']))) { $this->_out($s); }
+ $this->pageoutput[$this->page]['LineCap'] = $s;
+
+}
+
+function SetDash($black=false,$white=false)
+{
+ if($black and $white) $s=sprintf('[%.3F %.3F] 0 d',$black*_MPDFK,$white*_MPDFK);
+ else $s='[] 0 d';
+ if($this->page>0 && ((isset($this->pageoutput[$this->page]['Dash']) && $this->pageoutput[$this->page]['Dash'] != $s) || !isset($this->pageoutput[$this->page]['Dash']))) { $this->_out($s); }
+ $this->pageoutput[$this->page]['Dash'] = $s;
+
+}
+
+function SetDisplayPreferences($preferences) {
+ // String containing any or none of /HideMenubar/HideToolbar/HideWindowUI/DisplayDocTitle/CenterWindow/FitWindow
+ $this->DisplayPreferences .= $preferences;
+}
+
+
+function Ln($h='',$collapsible=0) {
+ // Added collapsible to allow collapsible top-margin on new page
+ //Line feed; default value is last cell height
+ $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
+ if ($collapsible && ($this->y==$this->tMargin) && (!$this->ColActive)) { $h = 0; }
+ if(is_string($h)) $this->y+=$this->lasth;
+ else $this->y+=$h;
+}
+
+/*-- HTML-CSS --*/
+function DivLn($h,$level=-3,$move_y=true,$collapsible=false,$state=0) {
+ // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
+ // Used in Columns and keep-with-table i.e. "kwt"
+ // writes background block by block so it can be repositioned
+ // and also used in writingFlowingBlock at top and bottom of blocks to move y (not to draw/paint anything)
+ // adds lines (y) where DIV bgcolors are filled in
+ // this->x is returned as it was
+ // allows .00001 as nominal height used for bookmarks/annotations etc.
+ if ($collapsible && (sprintf("%0.4f", $this->y)==sprintf("%0.4f", $this->tMargin)) && (!$this->ColActive)) { return; }
+
+ // mPDF 6 Columns
+ // if ($collapsible && (sprintf("%0.4f", $this->y)==sprintf("%0.4f", $this->y0)) && ($this->ColActive) && $this->CurrCol == 0) { return; } // *COLUMNS*
+ if ($collapsible && (sprintf("%0.4f", $this->y)==sprintf("%0.4f", $this->y0)) && ($this->ColActive)) { return; } // *COLUMNS*
+
+ // Still use this method if columns or keep-with-table, as it allows repositioning later
+ // otherwise, now uses PaintDivBB()
+ if (!$this->ColActive && !$this->kwt) {
+ if ($move_y && !$this->ColActive) { $this->y += $h; }
+ return;
+ }
+
+ if ($level == -3) { $level = $this->blklvl; }
+ $firstblockfill = $this->GetFirstBlockFill();
+ if ($firstblockfill && $this->blklvl > 0 && $this->blklvl >= $firstblockfill) {
+ $last_x = 0;
+ $last_w = 0;
+ $last_fc = $this->FillColor;
+ $bak_x = $this->x;
+ $bak_h = $this->divheight;
+ $this->divheight = 0; // Temporarily turn off divheight - as Cell() uses it to check for PageBreak
+ for ($blvl=$firstblockfill;$blvl<=$level;$blvl++) {
+ $this->x = $this->lMargin + $this->blk[$blvl]['outer_left_margin'];
+ // mPDF 6
+ if ($this->blk[$blvl]['bgcolor']) {
+ $this->SetFColor($this->blk[$blvl]['bgcolorarray']);
+ }
+ if ($last_x != ($this->lMargin + $this->blk[$blvl]['outer_left_margin']) || ($last_w != $this->blk[$blvl]['width']) || $last_fc != $this->FillColor || (isset($this->blk[$blvl]['border_top']['s']) && $this->blk[$blvl]['border_top']['s']) || (isset($this->blk[$blvl]['border_bottom']['s']) && $this->blk[$blvl]['border_bottom']['s']) || (isset($this->blk[$blvl]['border_left']['s']) && $this->blk[$blvl]['border_left']['s']) || (isset($this->blk[$blvl]['border_right']['s']) && $this->blk[$blvl]['border_right']['s'])) {
+ $x = $this->x;
+ $this->Cell( ($this->blk[$blvl]['width']), $h, '', '', 0, '', 1);
+ $this->x = $x;
+ if (!$this->keep_block_together && !$this->writingHTMLheader && !$this->writingHTMLfooter) {
+ // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
+ if ($blvl == $this->blklvl) { $this->PaintDivLnBorder($state,$blvl,$h); }
+ else { $this->PaintDivLnBorder(0,$blvl,$h); }
+ }
+ }
+ $last_x = $this->lMargin + $this->blk[$blvl]['outer_left_margin'];
+ $last_w = $this->blk[$blvl]['width'];
+ $last_fc = $this->FillColor;
+ }
+ // Reset current block fill
+ if (isset($this->blk[$this->blklvl]['bgcolorarray'])) {
+ $bcor = $this->blk[$this->blklvl]['bgcolorarray'];
+ $this->SetFColor($bcor);
+ }
+ $this->x = $bak_x;
+ $this->divheight = $bak_h;
+ }
+ if ($move_y) { $this->y += $h; }
+}
+/*-- END HTML-CSS --*/
+
+
+function SetX($x)
+{
+ //Set x position
+ if($x >= 0) $this->x=$x;
+ else $this->x = $this->w + $x;
+}
+
+function SetY($y)
+{
+ //Set y position and reset x
+ $this->x=$this->lMargin;
+ if($y>=0)
+ $this->y=$y;
+ else
+ $this->y=$this->h+$y;
+}
+
+function SetXY($x,$y)
+{
+ //Set x and y positions
+ $this->SetY($y);
+ $this->SetX($x);
+}
+
+
+function Output($name='',$dest='')
+{
+ //Output PDF to some destination
+ if ($this->showStats) {
+ echo 'Generated in '.sprintf('%.2F',(microtime(true) - $this->time0)).' seconds ';
+ }
+ //Finish document if necessary
+ if ($this->progressBar) { $this->UpdateProgressBar(1,'100','Finished'); } // *PROGRESS-BAR*
+ if($this->state < 3) $this->Close();
+ if ($this->progressBar) { $this->UpdateProgressBar(2,'100','Finished'); } // *PROGRESS-BAR*
+ // fn. error_get_last is only in PHP>=5.2
+ if ($this->debug && function_exists('error_get_last') && error_get_last()) {
+ $e = error_get_last();
+ if (($e['type'] < 2048 && $e['type'] != 8) || (intval($e['type']) & intval(ini_get("error_reporting")))) {
+ echo "Error message detected - PDF file generation aborted. ";
+ echo $e['message'].' ';
+ echo 'File: '.$e['file'].' ';
+ echo 'Line: '.$e['line'].' ';
+ exit;
+ }
+ }
+
+
+ if (($this->PDFA || $this->PDFX) && $this->encrypted) { $this->Error("PDFA1-b or PDFX/1-a does not permit encryption of documents."); }
+ if (count($this->PDFAXwarnings) && (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto))) {
+ if ($this->PDFA) {
+ echo 'WARNING - This file could not be generated as it stands as a PDFA1-b compliant file. ';
+ echo 'These issues can be automatically fixed by mPDF using $mpdf->PDFAauto=true; ';
+ echo 'Action that mPDF will take to automatically force PDFA1-b compliance are shown in brackets. ';
+ }
+ else {
+ echo 'WARNING - This file could not be generated as it stands as a PDFX/1-a compliant file. ';
+ echo 'These issues can be automatically fixed by mPDF using $mpdf->PDFXauto=true; ';
+ echo 'Action that mPDF will take to automatically force PDFX/1-a compliance are shown in brackets. ';
+ }
+ echo 'Warning(s) generated: ';
+ $this->PDFAXwarnings = array_unique($this->PDFAXwarnings);
+ foreach($this->PDFAXwarnings AS $w) {
+ echo '- '.$w.'
';
+ }
+ echo ' ';
+ exit;
+ }
+
+ if ($this->showStats) {
+ echo 'Compiled in '.sprintf('%.2F',(microtime(true) - $this->time0)).' seconds (total) ';
+ echo 'Peak Memory usage '.number_format((memory_get_peak_usage(true)/(1024*1024)),2).' MB ';
+ echo 'PDF file size '.number_format((strlen($this->buffer)/1024)).' kB ';
+ echo 'Number of fonts '.count($this->fonts).' ';
+ exit;
+ }
+
+
+ if(is_bool($dest)) $dest=$dest ? 'D' : 'F';
+ $dest=strtoupper($dest);
+ if($dest=='') {
+ if($name=='') {
+ $name='mpdf.pdf';
+ $dest='I';
+ }
+ else { $dest='F'; }
+ }
+
+/*-- PROGRESS-BAR --*/
+ if ($this->progressBar && ($dest=='D' || $dest=='I')) {
+ if($name=='') { $name='mpdf.pdf'; }
+ $tempfile = '_tempPDF'.uniqid(rand(1,100000),true);
+ //Save to local file
+ $f=fopen(_MPDF_TEMP_PATH.$tempfile.'.pdf','wb');
+ if(!$f) $this->Error('Unable to create temporary output file: '.$tempfile.'.pdf');
+ fwrite($f,$this->buffer,strlen($this->buffer));
+ fclose($f);
+ $this->UpdateProgressBar(3,'','Finished');
+
+ echo '
+
+
+ ';
+ exit;
+ }
+ else {
+ if ($this->progressBar) { $this->UpdateProgressBar(3,'','Finished'); }
+/*-- END PROGRESS-BAR --*/
+
+ switch($dest) {
+ case 'I':
+ if ($this->debug && !$this->allow_output_buffering && ob_get_contents()) { echo "Output has already been sent from the script - PDF file generation aborted. "; exit; }
+ //Send to standard output
+ if(PHP_SAPI!='cli') {
+ //We send to a browser
+ header('Content-Type: application/pdf');
+ if(headers_sent())
+ $this->Error('Some data has already been output to browser, can\'t send PDF file');
+ if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
+ // don't use length if server using compression
+ header('Content-Length: '.strlen($this->buffer));
+ }
+ header('Content-disposition: inline; filename="'.$name.'"');
+ header('Cache-Control: public, must-revalidate, max-age=0');
+ header('Pragma: public');
+ header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
+ header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
+ }
+ echo $this->buffer;
+ break;
+ case 'D':
+ //Download file
+ header('Content-Description: File Transfer');
+ if (headers_sent())
+ $this->Error('Some data has already been output to browser, can\'t send PDF file');
+ header('Content-Transfer-Encoding: binary');
+ header('Cache-Control: public, must-revalidate, max-age=0');
+ header('Pragma: public');
+ header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
+ header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
+ header('Content-Type: application/force-download');
+ header('Content-Type: application/octet-stream', false);
+ header('Content-Type: application/download', false);
+ header('Content-Type: application/pdf', false);
+ if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
+ // don't use length if server using compression
+ header('Content-Length: '.strlen($this->buffer));
+ }
+ header('Content-disposition: attachment; filename="'.$name.'"');
+ echo $this->buffer;
+ break;
+ case 'F':
+ //Save to local file
+ $f=fopen($name,'wb');
+ if(!$f) $this->Error('Unable to create output file: '.$name);
+ fwrite($f,$this->buffer,strlen($this->buffer));
+ fclose($f);
+ break;
+ case 'S':
+ //Return as a string
+ return $this->buffer;
+ default:
+ $this->Error('Incorrect output destination: '.$dest);
+ }
+
+ } // *PROGRESS-BAR*
+ //======================================================================================================
+ // DELETE OLD TMP FILES - Housekeeping
+ // Delete any files in tmp/ directory that are >1 hrs old
+ $interval = 3600;
+ if ($handle = @opendir(preg_replace('/\/$/','',_MPDF_TEMP_PATH))) { // mPDF 5.7.3
+ while (false !== ($file = readdir($handle))) {
+ if (($file != "..") && ($file != ".") && !is_dir($file) && ((filemtime(_MPDF_TEMP_PATH.$file)+$interval) < time()) && (substr($file, 0, 1) !== '.') && ($file !='dummy.txt')) { // mPDF 5.7.3
+ unlink(_MPDF_TEMP_PATH.$file);
+ }
+ }
+ closedir($handle);
+ }
+ //==============================================================================================================
+
+ return '';
+}
+
+
+// *****************************************************************************
+// *
+// Protected methods *
+// *
+// *****************************************************************************
+function _dochecks()
+{
+ //Check for locale-related bug
+ if(1.1==1)
+ $this->Error('Don\'t alter the locale before including mPDF');
+ //Check for decimal separator
+ if(sprintf('%.1f',1.0)!='1.0')
+ setlocale(LC_NUMERIC,'C');
+ $mqr=ini_get("magic_quotes_runtime");
+ if ($mqr) { $this->Error('mPDF requires magic_quotes_runtime to be turned off e.g. by using ini_set("magic_quotes_runtime", 0);'); }
+}
+
+
+
+function _puthtmlheaders() {
+ $this->state=2;
+ $nb=$this->page;
+ for($n=1;$n<=$nb;$n++) {
+ if ($this->mirrorMargins && $n%2==0) { $OE = 'E'; } // EVEN
+ else { $OE = 'O'; }
+ $this->page = $n;
+ $pn = $this->docPageNum($n);
+ if ($pn)
+ $pnstr = $this->pagenumPrefix.$pn.$this->pagenumSuffix;
+ else { $pnstr = ''; }
+ $pnt = $this->docPageNumTotal($n);
+ if ($pnt)
+ $pntstr = $this->nbpgPrefix.$pnt.$this->nbpgSuffix;
+ else { $pntstr = ''; }
+ if (isset($this->saveHTMLHeader[$n][$OE])) {
+ $html = $this->saveHTMLHeader[$n][$OE]['html'];
+ $this->lMargin = $this->saveHTMLHeader[$n][$OE]['ml'];
+ $this->rMargin = $this->saveHTMLHeader[$n][$OE]['mr'];
+ $this->tMargin = $this->saveHTMLHeader[$n][$OE]['mh'];
+ $this->bMargin = $this->saveHTMLHeader[$n][$OE]['mf'];
+ $this->margin_header = $this->saveHTMLHeader[$n][$OE]['mh'];
+ $this->margin_footer = $this->saveHTMLHeader[$n][$OE]['mf'];
+ $this->w = $this->saveHTMLHeader[$n][$OE]['pw'];
+ $this->h = $this->saveHTMLHeader[$n][$OE]['ph'];
+ $rotate = (isset($this->saveHTMLHeader[$n][$OE]['rotate']) ? $this->saveHTMLHeader[$n][$OE]['rotate'] : null);
+ $this->Reset();
+ $this->pageoutput[$n] = array();
+ $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
+ $this->x = $this->lMargin;
+ $this->y = $this->margin_header;
+ $html = str_replace('{PAGENO}',$pnstr,$html);
+ $html = str_replace($this->aliasNbPgGp,$pntstr,$html ); // {nbpg}
+ $html = str_replace($this->aliasNbPg,$nb,$html ); // {nb}
+ $html = preg_replace_callback('/\{DATE\s+(.*?)\}/', array($this, 'date_callback'),$html ); // mPDF 5.7
+
+ $this->HTMLheaderPageLinks = array();
+ $this->HTMLheaderPageAnnots = array();
+ $this->HTMLheaderPageForms = array();
+ $this->pageBackgrounds = array();
+
+ $this->writingHTMLheader = true;
+ $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
+ $this->writingHTMLheader = false;
+ $this->Reset();
+ $this->pageoutput[$n] = array();
+
+ $s = $this->PrintPageBackgrounds();
+ $this->headerbuffer = $s . $this->headerbuffer;
+ $os = '';
+ if ($rotate) {
+ $os .= sprintf('q 0 -1 1 0 0 %.3F cm ',($this->w*_MPDFK));
+ // To rotate the other way i.e. Header to left of page:
+ //$os .= sprintf('q 0 1 -1 0 %.3F %.3F cm ',($this->h*_MPDFK), (($this->rMargin - $this->lMargin )*_MPDFK));
+ }
+ $os .= $this->headerbuffer ;
+ if ($rotate) {
+ $os .= ' Q' . "\n";
+ }
+
+ // Writes over the page background but behind any other output on page
+ $os = preg_replace('/\\\\/','\\\\\\\\',$os);
+ $this->pages[$n] = preg_replace('/(___HEADER___MARKER'.$this->uniqstr.')/', "\n".$os."\n".'\\1', $this->pages[$n]);
+
+ $lks = $this->HTMLheaderPageLinks;
+ foreach($lks AS $lk) {
+ if ($rotate) {
+ $lw = $lk[2];
+ $lh = $lk[3];
+ $lk[2] = $lh;
+ $lk[3] = $lw; // swap width and height
+ $ax = $lk[0]/_MPDFK;
+ $ay = $lk[1]/_MPDFK;
+ $bx = $ay-($lh/_MPDFK);
+ $by = $this->w-$ax;
+ $lk[0] = $bx*_MPDFK;
+ $lk[1] = ($this->h-$by)*_MPDFK - $lw;
+ }
+ $this->PageLinks[$n][]=$lk;
+ }
+/*-- FORMS --*/
+ foreach($this->HTMLheaderPageForms AS $f) {
+ $this->mpdfform->forms[$f['n']] = $f;
+ }
+/*-- END FORMS --*/
+
+
+ }
+ if (isset($this->saveHTMLFooter[$n][$OE])) {
+ $html = $this->saveHTMLFooter[$this->page][$OE]['html'];
+ $this->lMargin = $this->saveHTMLFooter[$n][$OE]['ml'];
+ $this->rMargin = $this->saveHTMLFooter[$n][$OE]['mr'];
+ $this->tMargin = $this->saveHTMLFooter[$n][$OE]['mh'];
+ $this->bMargin = $this->saveHTMLFooter[$n][$OE]['mf'];
+ $this->margin_header = $this->saveHTMLFooter[$n][$OE]['mh'];
+ $this->margin_footer = $this->saveHTMLFooter[$n][$OE]['mf'];
+ $this->w = $this->saveHTMLFooter[$n][$OE]['pw'];
+ $this->h = $this->saveHTMLFooter[$n][$OE]['ph'];
+ $rotate = (isset($this->saveHTMLFooter[$n][$OE]['rotate']) ? $this->saveHTMLFooter[$n][$OE]['rotate'] : null);
+ $this->Reset();
+ $this->pageoutput[$n] = array();
+ $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
+ $this->x = $this->lMargin;
+ $top_y = $this->y = $this->h - $this->margin_footer;
+
+ // if bottom-margin==0, corrects to avoid division by zero
+ if ($this->y == $this->h) { $top_y = $this->y = ($this->h - 0.1); }
+ $html = str_replace('{PAGENO}',$pnstr,$html);
+ $html = str_replace($this->aliasNbPgGp,$pntstr,$html ); // {nbpg}
+ $html = str_replace($this->aliasNbPg,$nb,$html ); // {nb}
+ $html = preg_replace_callback('/\{DATE\s+(.*?)\}/', array($this, 'date_callback'),$html ); // mPDF 5.7
+
+
+ $this->HTMLheaderPageLinks = array();
+ $this->HTMLheaderPageAnnots = array();
+ $this->HTMLheaderPageForms = array();
+ $this->pageBackgrounds = array();
+
+ $this->writingHTMLfooter = true;
+ $this->InFooter = true;
+ $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
+ $this->InFooter = false;
+ $this->Reset();
+ $this->pageoutput[$n] = array();
+
+ $fheight = $this->y - $top_y;
+ $adj = -$fheight;
+
+ $s = $this->PrintPageBackgrounds(-$adj);
+ $this->headerbuffer = $s . $this->headerbuffer;
+ $this->writingHTMLfooter = false; // mPDF 5.7.3 (moved after PrintPageBackgrounds so can adjust position of images in footer)
+
+ $os = '';
+ $os .= $this->StartTransform(true)."\n";
+ if ($rotate) {
+ $os .= sprintf('q 0 -1 1 0 0 %.3F cm ',($this->w*_MPDFK));
+ // To rotate the other way i.e. Header to left of page:
+ //$os .= sprintf('q 0 1 -1 0 %.3F %.3F cm ',($this->h*_MPDFK), (($this->rMargin - $this->lMargin )*_MPDFK));
+ }
+ $os .= $this->transformTranslate(0, $adj, true)."\n";
+ $os .= $this->headerbuffer ;
+ if ($rotate) {
+ $os .= ' Q' . "\n";
+ }
+ $os .= $this->StopTransform(true)."\n";
+ // Writes over the page background but behind any other output on page
+ $os = preg_replace('/\\\\/','\\\\\\\\',$os);
+ $this->pages[$n] = preg_replace('/(___HEADER___MARKER'.$this->uniqstr.')/', "\n".$os."\n".'\\1', $this->pages[$n]);
+
+ $lks = $this->HTMLheaderPageLinks;
+ foreach($lks AS $lk) {
+ $lk[1] -= $adj*_MPDFK;
+ if ($rotate) {
+ $lw = $lk[2];
+ $lh = $lk[3];
+ $lk[2] = $lh;
+ $lk[3] = $lw; // swap width and height
+
+ $ax = $lk[0]/_MPDFK;
+ $ay = $lk[1]/_MPDFK;
+ $bx = $ay-($lh/_MPDFK);
+ $by = $this->w-$ax;
+ $lk[0] = $bx*_MPDFK;
+ $lk[1] = ($this->h-$by)*_MPDFK - $lw;
+ }
+ $this->PageLinks[$n][]=$lk;
+ }
+/*-- FORMS --*/
+ foreach($this->HTMLheaderPageForms AS $f) {
+ $f['y'] += $adj;
+ $this->mpdfform->forms[$f['n']] = $f;
+ }
+/*-- END FORMS --*/
+ }
+ }
+ $this->page=$nb;
+ $this->state=1;
+}
+
+
+
+function _putpages()
+{
+ $nb=$this->page;
+ $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
+
+ if($this->DefOrientation=='P') {
+ $defwPt=$this->fwPt;
+ $defhPt=$this->fhPt;
+ }
+ else {
+ $defwPt=$this->fhPt;
+ $defhPt=$this->fwPt;
+ }
+ $annotid=(3+2*$nb);
+
+ // Active Forms
+ $totaladdnum = 0;
+ for($n=1;$n<=$nb;$n++) {
+ if (isset($this->PageLinks[$n])) { $totaladdnum += count($this->PageLinks[$n]); }
+/*-- ANNOTATIONS --*/
+ if (isset($this->PageAnnots[$n])) {
+ foreach ($this->PageAnnots[$n] as $k => $pl) {
+ if (!empty($pl['opt']['popup']) || !empty($pl['opt']['file'])) { $totaladdnum += 2 ; }
+ else { $totaladdnum++; }
+ }
+ }
+/*-- END ANNOTATIONS --*/
+
+/*-- FORMS --*/
+ if ( count($this->mpdfform->forms) > 0 ) {
+ $this->mpdfform->countPageForms($n, $totaladdnum);
+ }
+/*-- END FORMS --*/
+ }
+/*-- FORMS --*/
+ // Make a note in the radio button group of the obj_id it will have
+ $ctr = 0;
+ if (count($this->mpdfform->form_radio_groups)) {
+ foreach($this->mpdfform->form_radio_groups AS $name=>$frg) {
+ $this->mpdfform->form_radio_groups[$name]['obj_id'] = $annotid + $totaladdnum + $ctr;
+ $ctr++;
+ }
+ }
+/*-- END FORMS --*/
+
+ // Select unused fonts (usually default font)
+ $unused = array();
+ foreach($this->fonts as $fk=>$font) {
+ if (isset($font['type']) && $font['type']=='TTF' && !$font['used']) {
+ $unused[] = $fk;
+ }
+ }
+
+
+ for($n=1;$n<=$nb;$n++)
+ {
+ $thispage = $this->pages[$n];
+ if(isset($this->OrientationChanges[$n])) {
+ $hPt=$this->pageDim[$n]['w']*_MPDFK;
+ $wPt=$this->pageDim[$n]['h']*_MPDFK;
+ $owidthPt_LR = $this->pageDim[$n]['outer_width_TB']*_MPDFK;
+ $owidthPt_TB = $this->pageDim[$n]['outer_width_LR']*_MPDFK;
+ }
+ else {
+ $wPt=$this->pageDim[$n]['w']*_MPDFK;
+ $hPt=$this->pageDim[$n]['h']*_MPDFK;
+ $owidthPt_LR = $this->pageDim[$n]['outer_width_LR']*_MPDFK;
+ $owidthPt_TB = $this->pageDim[$n]['outer_width_TB']*_MPDFK;
+ }
+ // Remove references to unused fonts (usually default font)
+ foreach($unused as $fk) {
+ if ($this->fonts[$fk]['sip'] || $this->fonts[$fk]['smp']) {
+ foreach($this->fonts[$fk]['subsetfontids'] AS $k => $fid) {
+ $thispage = preg_replace('/\s\/F'.$fid.' \d[\d.]* Tf\s/is',' ',$thispage);
+ }
+ }
+ else {
+ $thispage = preg_replace('/\s\/F'.$this->fonts[$fk]['i'].' \d[\d.]* Tf\s/is',' ',$thispage);
+ }
+ }
+ // Clean up repeated /GS1 gs statements
+ // For some reason using + for repetition instead of {2,20} crashes PHP Script Interpreter ???
+ $thispage = preg_replace('/(\/GS1 gs\n){2,20}/', "/GS1 gs\n", $thispage);
+
+ $thispage = preg_replace('/(\s*___BACKGROUND___PATTERNS'.$this->uniqstr.'\s*)/', " ", $thispage);
+ $thispage = preg_replace('/(\s*___HEADER___MARKER'.$this->uniqstr.'\s*)/', " ", $thispage);
+ $thispage = preg_replace('/(\s*___PAGE___START'.$this->uniqstr.'\s*)/', " ", $thispage);
+ $thispage = preg_replace('/(\s*___TABLE___BACKGROUNDS'.$this->uniqstr.'\s*)/', " ", $thispage);
+ // mPDF 5.7.3 TRANSFORMS
+ while (preg_match('/(\% BTR(.*?)\% ETR)/is', $thispage, $m)) {
+ $thispage = preg_replace('/(\% BTR.*?\% ETR)/is', '', $thispage, 1)."\n".$m[2];
+ }
+
+ //Page
+ $this->_newobj();
+ $this->_out('<_out('/Parent 1 0 R');
+ if(isset($this->OrientationChanges[$n])) {
+ $this->_out(sprintf('/MediaBox [0 0 %.3F %.3F]',$hPt,$wPt));
+ //If BleedBox is defined, it must be larger than the TrimBox, but smaller than the MediaBox
+ $bleedMargin = $this->pageDim[$n]['bleedMargin']*_MPDFK;
+ if ($bleedMargin && ($owidthPt_TB || $owidthPt_LR)) {
+ $x0 = $owidthPt_TB-$bleedMargin;
+ $y0 = $owidthPt_LR-$bleedMargin;
+ $x1 = $hPt-$owidthPt_TB+$bleedMargin;
+ $y1 = $wPt-$owidthPt_LR+$bleedMargin;
+ $this->_out(sprintf('/BleedBox [%.3F %.3F %.3F %.3F]', $x0, $y0, $x1, $y1));
+ }
+ $this->_out(sprintf('/TrimBox [%.3F %.3F %.3F %.3F]', $owidthPt_TB, $owidthPt_LR, ($hPt-$owidthPt_TB), ($wPt-$owidthPt_LR)));
+ if (isset($this->OrientationChanges[$n]) && $this->displayDefaultOrientation) {
+ if ($this->DefOrientation=='P') { $this->_out('/Rotate 270'); }
+ else { $this->_out('/Rotate 90'); }
+ }
+ }
+ //else if($wPt != $defwPt || $hPt != $defhPt) {
+ else {
+ $this->_out(sprintf('/MediaBox [0 0 %.3F %.3F]',$wPt,$hPt));
+ $bleedMargin = $this->pageDim[$n]['bleedMargin']*_MPDFK;
+ if ($bleedMargin && ($owidthPt_TB || $owidthPt_LR)) {
+ $x0 = $owidthPt_LR-$bleedMargin;
+ $y0 = $owidthPt_TB-$bleedMargin;
+ $x1 = $wPt-$owidthPt_LR+$bleedMargin;
+ $y1 = $hPt-$owidthPt_TB+$bleedMargin;
+ $this->_out(sprintf('/BleedBox [%.3F %.3F %.3F %.3F]', $x0, $y0, $x1, $y1));
+ }
+ $this->_out(sprintf('/TrimBox [%.3F %.3F %.3F %.3F]', $owidthPt_LR, $owidthPt_TB, ($wPt-$owidthPt_LR), ($hPt-$owidthPt_TB)));
+ }
+ $this->_out('/Resources 2 0 R');
+
+ // Important to keep in RGB colorSpace when using transparency
+ if (!$this->PDFA && !$this->PDFX) {
+ if ($this->restrictColorSpace == 3)
+ $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceCMYK >> ');
+ else if ($this->restrictColorSpace == 1)
+ $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceGray >> ');
+ else
+ $this->_out('/Group << /Type /Group /S /Transparency /CS /DeviceRGB >> ');
+ }
+
+ $annotsnum = 0;
+ $embeddedfiles = array(); // mPDF 5.7.2 /EmbeddedFiles
+
+ if (isset($this->PageLinks[$n])) { $annotsnum += count($this->PageLinks[$n]); }
+/*-- ANNOTATIONS --*/
+ if (isset($this->PageAnnots[$n])) {
+ foreach ($this->PageAnnots[$n] as $k => $pl) {
+ if (!empty($pl['opt']['file'])) { $embeddedfiles[$annotsnum+1] = true ; } // mPDF 5.7.2 /EmbeddedFiles
+ if (!empty($pl['opt']['popup']) || !empty($pl['opt']['file'])) { $annotsnum += 2 ; }
+ else { $annotsnum++; }
+ $this->PageAnnots[$n][$k]['pageobj'] = $this->n;
+ }
+ }
+/*-- END ANNOTATIONS --*/
+
+/*-- FORMS --*/
+ // Active Forms
+ $formsnum = 0;
+ if ( count($this->mpdfform->forms) > 0 ) {
+ foreach( $this->mpdfform->forms as $val ) {
+ if ( $val['page'] == $n )
+ $formsnum++;
+ }
+ }
+/*-- END FORMS --*/
+ if ($annotsnum || $formsnum) {
+ $s = '/Annots [ ';
+ for($i=0;$i<$annotsnum;$i++) {
+ if (!isset($embeddedfiles[$i])) { $s .= ($annotid + $i) . ' 0 R '; } // mPDF 5.7.2 /EmbeddedFiles
+ }
+ $annotid += $annotsnum;
+/*-- FORMS --*/
+ if ( count($this->mpdfform->forms) > 0 ) {
+ $this->mpdfform->addFormIds($n, $s, $annotid);
+ }
+/*-- END FORMS --*/
+ $s .= '] ';
+ $this->_out($s);
+ }
+
+ $this->_out('/Contents '.($this->n+1).' 0 R>>');
+ $this->_out('endobj');
+
+ //Page content
+ $this->_newobj();
+ $p=($this->compress) ? gzcompress($thispage) : $thispage;
+ $this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
+ $this->_putstream($p);
+ $this->_out('endobj');
+ }
+ $this->_putannots(); // mPDF 5.7.2
+
+ //Pages root
+ $this->offsets[1]=strlen($this->buffer);
+ $this->_out('1 0 obj');
+ $this->_out('<_out($kids.']');
+ $this->_out('/Count '.$nb);
+ $this->_out(sprintf('/MediaBox [0 0 %.3F %.3F]',$defwPt,$defhPt));
+ $this->_out('>>');
+ $this->_out('endobj');
+}
+
+
+function _putannots() { // mPDF 5.7.2
+ $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
+ $nb=$this->page;
+ for($n=1;$n<=$nb;$n++)
+ {
+ $annotobjs = array();
+ if(isset($this->PageLinks[$n]) || isset($this->PageAnnots[$n]) || count($this->mpdfform->forms) > 0 ) {
+ $wPt=$this->pageDim[$n]['w']*_MPDFK;
+ $hPt=$this->pageDim[$n]['h']*_MPDFK;
+
+ //Links
+ if(isset($this->PageLinks[$n])) {
+ foreach($this->PageLinks[$n] as $key => $pl) {
+ $this->_newobj();
+ $annot='';
+ $rect=sprintf('%.3F %.3F %.3F %.3F',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]);
+ $annot .= '<_UTF16BEtextstring($pl[4]);
+ $annot .= ' /NM '.$this->_textstring(sprintf('%04u-%04u', $n, $key));
+ $annot .= ' /M '.$this->_textstring('D:'.date('YmdHis'));
+ $annot .= ' /Border [0 0 0]';
+ // Use this (instead of /Border) to specify border around link
+ // $annot .= ' /BS <>';
+ // $annot .= ' /C [1 0 0]'; // Color RGB
+
+ if ($this->PDFA || $this->PDFX) { $annot .= ' /F 28'; }
+ if (strpos($pl[4],'@')===0) {
+ $p=substr($pl[4],1);
+ // $h=isset($this->OrientationChanges[$p]) ? $wPt : $hPt;
+ $htarg=$this->pageDim[$p]['h']*_MPDFK;
+ $annot.=sprintf(' /Dest [%d 0 R /XYZ 0 %.3F null]>>',1+2*$p,$htarg);
+ }
+ else if(is_string($pl[4])) {
+ $annot .= ' /A <_textstring($pl[4]).'>> >>';
+ }
+ else {
+ $l=$this->links[$pl[4]];
+ // may not be set if #link points to non-existent target
+ if (isset($this->pageDim[$l[0]]['h'])) { $htarg=$this->pageDim[$l[0]]['h']*_MPDFK; }
+ else { $htarg=$this->h*_MPDFK; } // doesn't really matter
+ $annot.=sprintf(' /Dest [%d 0 R /XYZ 0 %.3F null]>>',1+2*$l[0],$htarg-$l[1]*_MPDFK);
+ }
+ $this->_out($annot);
+ $this->_out('endobj');
+ }
+ }
+
+
+/*-- ANNOTATIONS --*/
+ if(isset($this->PageAnnots[$n])) {
+ foreach ($this->PageAnnots[$n] as $key => $pl) {
+ if ($pl['opt']['file']) { $FileAttachment=true; }
+ else { $FileAttachment=false; }
+ $this->_newobj();
+ $annot='';
+ $pl['opt'] = array_change_key_case($pl['opt'], CASE_LOWER);
+ $x = $pl['x'];
+ if ($this->annotMargin <> 0 || $x==0 || $x<0) { // Odd page
+ $x = ($wPt/_MPDFK) - $this->annotMargin;
+ }
+ $w = $h = 0;
+ $a = $x * _MPDFK;
+ $b = $hPt - ($pl['y'] * _MPDFK);
+ $annot .= '<n+1).' 0 R>>';
+ $annot .= '>>';
+ }
+ else {
+ $annot .= '/Subtype /Text';
+ $w=20; $h=20; // mPDF 6
+ }
+ $rect = sprintf('%.3F %.3F %.3F %.3F', $a, $b-$h, $a+$w, $b);
+ $annot .= ' /Rect ['.$rect.']';
+
+ // contents = description of file in free text
+ $annot .= ' /Contents '.$this->_UTF16BEtextstring($pl['txt']);
+
+ $annot .= ' /NM '.$this->_textstring(sprintf('%04u-%04u', $n, (2000 + $key)));
+ $annot .= ' /M '.$this->_textstring('D:'.date('YmdHis'));
+ $annot .= ' /CreationDate '.$this->_textstring('D:'.date('YmdHis'));
+ $annot .= ' /Border [0 0 0]';
+ if ($this->PDFA || $this->PDFX) {
+ $annot .= ' /F 28';
+ $annot .= ' /CA 1';
+ }
+ else if ($pl['opt']['ca']>0) { $annot .= ' /CA '.$pl['opt']['ca']; }
+
+ $annotcolor = ' /C [';
+ if (isset($pl['opt']['c']) AND $pl['opt']['c']) {
+ $col = $pl['opt']['c'];
+ if ($col{0}==3 || $col{0}==5) { $annotcolor .= sprintf("%.3F %.3F %.3F", ord($col{1})/255,ord($col{2})/255,ord($col{3})/255); }
+ else if ($col{0}==1) { $annotcolor .= sprintf("%.3F", ord($col{1})/255); }
+ else if ($col{0}==4 || $col{0}==6) { $annotcolor .= sprintf("%.3F %.3F %.3F %.3F", ord($col{1})/100,ord($col{2})/100,ord($col{3})/100,ord($col{4})/100); }
+ else { $annotcolor .= '1 1 0'; }
+ }
+ else { $annotcolor .= '1 1 0'; }
+ $annotcolor .= ']';
+ $annot .= $annotcolor;
+ // Usually Author
+ // Use as Title for fileattachment
+ if (isset($pl['opt']['t']) AND is_string($pl['opt']['t'])) {
+ $annot .= ' /T '.$this->_UTF16BEtextstring($pl['opt']['t']);
+ }
+ if ($FileAttachment) {
+ $iconsapp = array('Paperclip', 'Graph', 'PushPin', 'Tag');
+ }
+ else { $iconsapp = array('Comment', 'Help', 'Insert', 'Key', 'NewParagraph', 'Note', 'Paragraph'); }
+ if (isset($pl['opt']['icon']) AND in_array($pl['opt']['icon'], $iconsapp)) {
+ $annot .= ' /Name /'.$pl['opt']['icon'];
+ }
+ else if ($FileAttachment) { $annot .= ' /Name /PushPin'; }
+ else { $annot .= ' /Name /Note'; }
+ if (!$FileAttachment) {
+ // /Subj is PDF 1.5 spec.
+ if (isset($pl['opt']['subj']) && !$this->PDFA && !$this->PDFX) {
+ $annot .= ' /Subj '.$this->_UTF16BEtextstring($pl['opt']['subj']);
+ }
+ if (!empty($pl['opt']['popup'])) {
+ $annot .= ' /Open true';
+ $annot .= ' /Popup '.($this->n+1).' 0 R';
+ }
+ else { $annot .= ' /Open false'; }
+ }
+ $annot .= ' /P '.$pl['pageobj'].' 0 R';
+ $annot .= '>>';
+ $this->_out($annot);
+ $this->_out('endobj');
+
+ if ($FileAttachment) {
+ $file = @file_get_contents($pl['opt']['file']) or die('mPDF Error: Cannot access file attachment - '.$pl['opt']['file']);
+ $filestream = gzcompress($file);
+ $this->_newobj();
+ $this->_out('<_out('/Length '.strlen($filestream));
+ $this->_out('/Filter /FlateDecode');
+ $this->_out('>>');
+ $this->_putstream($filestream);
+ $this->_out('endobj');
+ }
+ else if (!empty($pl['opt']['popup'])) {
+ $this->_newobj();
+ $annot='';
+ if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][0])) { $x = $pl['opt']['popup'][0] * _MPDFK; }
+ else { $x = $pl['x'] * _MPDFK; }
+ if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][1])) { $y = $hPt - ($pl['opt']['popup'][1] * _MPDFK); }
+ else { $y = $hPt - ($pl['y'] * _MPDFK); }
+ if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][2])) { $w = $pl['opt']['popup'][2] * _MPDFK; }
+ else { $w = 180; }
+ if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][3])) { $h = $pl['opt']['popup'][3] * _MPDFK; }
+ else { $h = 120; }
+ $rect = sprintf('%.3F %.3F %.3F %.3F', $x, $y-$h, $x+$w, $y);
+ $annot .= '<_textstring('D:'.date('YmdHis'));
+ if ($this->PDFA || $this->PDFX) { $annot .= ' /F 28'; }
+ $annot .= ' /Parent '.($this->n-1).' 0 R';
+ $annot .= '>>';
+ $this->_out($annot);
+ $this->_out('endobj');
+ }
+
+ }
+ }
+/*-- END ANNOTATIONS --*/
+
+/*-- FORMS --*/
+ // Active Forms
+ if ( count($this->mpdfform->forms) > 0 ) {
+ $this->mpdfform->_putFormItems($n, $hPt);
+ }
+/*-- END FORMS --*/
+ }
+ }
+/*-- FORMS --*/
+ // Active Forms - Radio Button Group entries
+ // Output Radio Button Group form entries (radio_on_obj_id already determined)
+ if (count($this->mpdfform->form_radio_groups)) {
+ $this->mpdfform->_putRadioItems($n);
+ }
+/*-- END FORMS --*/
+}
+
+
+/*-- ANNOTATIONS --*/
+function Annotation($text, $x=0, $y=0, $icon='Note', $author='', $subject='', $opacity=0, $colarray=false, $popup='', $file='') {
+ if (is_array($colarray) && count($colarray)==3) { $colarray = $this->ConvertColor('rgb('.$colarray[0].','.$colarray[1].','.$colarray[2].')'); }
+ if ($colarray === false) { $colarray = $this->ConvertColor('yellow'); }
+ if ($x==0) { $x = $this->x; }
+ if ($y==0) { $y = $this->y; }
+ $page = $this->page;
+ if ($page < 1) { // Document has not been started - assume it's for first page
+ $page = 1;
+ if ($x==0) { $x = $this->lMargin; }
+ if ($y==0) { $y = $this->tMargin; }
+ }
+
+ if ($this->PDFA || $this->PDFX) {
+ if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "Annotation markers cannot be semi-transparent in PDFA1-b or PDFX/1-a, so they may make underlying text unreadable. (Annotation markers moved to right margin)"; }
+ $x = ($this->w) - $this->rMargin*0.66;
+ }
+ if (!$this->annotMargin) { $y -= $this->FontSize / 2; }
+
+ if (!$opacity && $this->annotMargin) { $opacity = 1; }
+ else if (!$opacity) { $opacity = $this->annotOpacity; }
+
+ $an = array('txt' => $text, 'x' => $x, 'y' => $y, 'opt' => array('Icon'=>$icon, 'T'=>$author, 'Subj'=>$subject, 'C'=>$colarray, 'CA'=>$opacity, 'popup'=>$popup, 'file'=>$file));
+
+ if ($this->keep_block_together) { // don't write yet
+ return;
+ }
+ else if ($this->table_rotate) {
+ $this->tbrot_Annots[$this->page][]= $an;
+ return;
+ }
+ else if ($this->kwt) {
+ $this->kwt_Annots[$this->page][]= $an;
+ return;
+ }
+ if ($this->writingHTMLheader || $this->writingHTMLfooter) {
+ $this->HTMLheaderPageAnnots[]= $an;
+ return;
+ }
+ //Put an Annotation on the page
+ $this->PageAnnots[$page][] = $an;
+/*-- COLUMNS --*/
+ // Save cross-reference to Column buffer
+ $ref = count($this->PageAnnots[$this->page])-1;
+ $this->columnAnnots[$this->CurrCol][INTVAL($this->x)][INTVAL($this->y)] = $ref;
+/*-- END COLUMNS --*/
+}
+/*-- END ANNOTATIONS --*/
+
+
+function _putfonts() {
+ $nf=$this->n;
+ foreach($this->FontFiles as $fontkey=>$info) {
+ // TrueType embedded
+ if (isset($info['type']) && $info['type']=='TTF' && !$info['sip'] && !$info['smp']) {
+ $used = true;
+ $asSubset = false;
+ foreach($this->fonts AS $k=>$f) {
+ if (isset($f['fontkey']) && $f['fontkey'] == $fontkey && $f['type']=='TTF') {
+ $used = $f['used'];
+ if ($used) {
+ $nChars = (ord($f['cw'][0]) << 8) + ord($f['cw'][1]);
+ $usage = intval(count($f['subset'])*100 / $nChars);
+ $fsize = $info['length1'];
+ // Always subset the very large TTF files
+ if ($fsize > ($this->maxTTFFilesize *1024)) { $asSubset = true; }
+ else if ($usage < $this->percentSubset) { $asSubset = true; }
+ }
+ if ($this->PDFA || $this->PDFX) $asSubset = false;
+ $this->fonts[$k]['asSubset'] = $asSubset;
+ break;
+ }
+ }
+ if ($used && !$asSubset) {
+ //Font file embedding
+ $this->_newobj();
+ $this->FontFiles[$fontkey]['n']=$this->n;
+ $font='';
+ $originalsize = $info['length1'];
+ if ($this->repackageTTF || $this->fonts[$fontkey]['TTCfontID']>0 || $this->fonts[$fontkey]['useOTL']>0) { // mPDF 5.7.1
+ // First see if there is a cached compressed file
+ if (file_exists(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.z')) {
+ $f=fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.z','rb');
+ if(!$f) { $this->Error('Font file .ps.z not found'); }
+ while(!feof($f)) { $font .= fread($f, 2048); }
+ fclose($f);
+ include(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.php'); // sets $originalsize (of repackaged font)
+ }
+ else {
+ if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
+ $ttf = new TTFontFile();
+ $font = $ttf->repackageTTF($this->FontFiles[$fontkey]['ttffile'], $this->fonts[$fontkey]['TTCfontID'], $this->debugfonts, $this->fonts[$fontkey]['useOTL']); // mPDF 5.7.1
+
+ $originalsize = strlen($font);
+ $font = gzcompress($font);
+ unset($ttf);
+ if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
+ $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.z',"wb");
+ fwrite($fh,$font,strlen($font));
+ fclose($fh);
+ $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.php',"wb");
+ $len = "";
+ fwrite($fh,$len,strlen($len));
+ fclose($fh);
+ }
+ }
+ }
+ else {
+ // First see if there is a cached compressed file
+ if (file_exists(_MPDF_TTFONTDATAPATH.$fontkey.'.z')) {
+ $f=fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.z','rb');
+ if(!$f) { $this->Error('Font file not found'); }
+ while(!feof($f)) { $font .= fread($f, 2048); }
+ fclose($f);
+ }
+ else {
+ $f=fopen($this->FontFiles[$fontkey]['ttffile'],'rb');
+ if(!$f) { $this->Error('Font file not found'); }
+ while(!feof($f)) { $font .= fread($f, 2048); }
+ fclose($f);
+ $font = gzcompress($font);
+ if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
+ $fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.z',"wb");
+ fwrite($fh,$font,strlen($font));
+ fclose($fh);
+ }
+ }
+ }
+
+ $this->_out('<_out('/Filter /FlateDecode');
+ $this->_out('/Length1 '.$originalsize);
+ $this->_out('>>');
+ $this->_putstream($font);
+ $this->_out('endobj');
+ }
+ }
+ }
+
+ $nfonts = count($this->fonts);
+ $fctr = 1;
+ foreach($this->fonts as $k=>$font) {
+ //Font objects
+ $type=$font['type'];
+ $name=$font['name'];
+ if ((!isset($font['used']) || !$font['used']) && $type=='TTF') { continue; }
+ if ($this->progressBar) { $this->UpdateProgressBar(2,intval($fctr*100/$nfonts),'Writing Fonts'); $fctr++; } // *PROGRESS-BAR*
+ if (isset($font['asSubset'])) { $asSubset = $font['asSubset']; }
+ else { $asSubset = ''; }
+/*-- CJK-FONTS --*/
+ if($type=='Type0') { // = Adobe CJK Fonts
+ $this->fonts[$k]['n']=$this->n+1;
+ $this->_newobj();
+ $this->_out('<_putType0($font);
+ }
+ else
+/*-- END CJK-FONTS --*/
+ if($type=='core') {
+ //Standard font
+ $this->fonts[$k]['n']=$this->n+1;
+ if ($this->PDFA || $this->PDFX) { $this->Error('Core fonts are not allowed in PDF/A1-b or PDFX/1-a files (Times, Helvetica, Courier etc.)'); }
+ $this->_newobj();
+ $this->_out('<_out('/BaseFont /'.$name);
+ $this->_out('/Subtype /Type1');
+ if($name!='Symbol' && $name!='ZapfDingbats') {
+ $this->_out('/Encoding /WinAnsiEncoding');
+ }
+ $this->_out('>>');
+ $this->_out('endobj');
+ }
+ // TrueType embedded SUBSETS for SIP (CJK extB containing Supplementary Ideographic Plane 2)
+ // Or Unicode Plane 1 - Supplementary Multilingual Plane
+ else if ($type=='TTF' && ($font['sip'] || $font['smp'])) {
+ if (!$font['used']) { continue; }
+ $ssfaid="AA";
+ if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
+ $ttf = new TTFontFile();
+ for($sfid=0;$sfidfonts[$k]['n'][$sfid]=$this->n+1; // NB an array for subset
+ $subsetname = 'MPDF'.$ssfaid.'+'.$font['name'];
+ $ssfaid++;
+
+ /* For some strange reason a subset ($sfid > 0) containing less than 97 characters causes an error
+ so fill up the array */
+ for($j=count($font['subsets'][$sfid]);$j<98;$j++) {
+ $font['subsets'][$sfid][$j]=0;
+ }
+
+ $subset = $font['subsets'][$sfid];
+ unset($subset[0]);
+ $ttfontstream = $ttf->makeSubsetSIP($font['ttffile'], $subset, $font['TTCfontID'], $this->debugfonts, $font['useOTL']); // mPDF 5.7.1
+ $ttfontsize = strlen($ttfontstream);
+ $fontstream = gzcompress($ttfontstream);
+ $widthstring = '';
+ $toUnistring = '';
+
+
+ foreach($font['subsets'][$sfid] AS $cp=>$u) {
+ $w = $this->_getCharWidth($font['cw'], $u);
+ if ($w !== false) {
+ $widthstring .= $w.' ';
+ }
+ else {
+ $widthstring .= round($ttf->defaultWidth).' ';
+ }
+ if ($u > 65535) {
+ $utf8 = chr(($u>>18)+240).chr((($u>>12)&63)+128).chr((($u>>6)&63)+128) .chr(($u&63)+128);
+ $utf16 = mb_convert_encoding($utf8, 'UTF-16BE', 'UTF-8');
+ $l1 = ord($utf16[0]);
+ $h1 = ord($utf16[1]);
+ $l2 = ord($utf16[2]);
+ $h2 = ord($utf16[3]);
+ $toUnistring .= sprintf("<%02s> <%02s%02s%02s%02s>\n", strtoupper(dechex($cp)), strtoupper(dechex($l1)), strtoupper(dechex($h1)), strtoupper(dechex($l2)), strtoupper(dechex($h2)));
+ }
+ else {
+ $toUnistring .= sprintf("<%02s> <%04s>\n", strtoupper(dechex($cp)), strtoupper(dechex($u)));
+ }
+ }
+
+ //Additional Type1 or TrueType font
+ $this->_newobj();
+ $this->_out('<_out('/BaseFont /'.$subsetname);
+ $this->_out('/Subtype /TrueType');
+ $this->_out('/FirstChar 0 /LastChar '.(count($font['subsets'][$sfid])-1));
+ $this->_out('/Widths '.($this->n+1).' 0 R');
+ $this->_out('/FontDescriptor '.($this->n+2).' 0 R');
+ $this->_out('/ToUnicode '.($this->n + 3).' 0 R');
+ $this->_out('>>');
+ $this->_out('endobj');
+
+ //Widths
+ $this->_newobj();
+ $this->_out('['.$widthstring.']');
+ $this->_out('endobj');
+
+ //Descriptor
+ $this->_newobj();
+ $s='<$v) {
+ if ($kd == 'Flags') { $v = $v | 4; $v = $v & ~32; } // SYMBOLIC font flag
+ $s.=' /'.$kd.' '.$v."\n";
+ }
+ $s.='/FontFile2 '.($this->n + 2).' 0 R';
+ $this->_out($s.'>>');
+ $this->_out('endobj');
+
+ // ToUnicode
+ $this->_newobj();
+ $toUni = "/CIDInit /ProcSet findresource begin\n";
+ $toUni .= "12 dict begin\n";
+ $toUni .= "begincmap\n";
+ $toUni .= "/CIDSystemInfo\n";
+ $toUni .= "<> def\n";
+ $toUni .= "/CMapName /Adobe-Identity-UCS def\n";
+ $toUni .= "/CMapType 2 def\n";
+ $toUni .= "1 begincodespacerange\n";
+ $toUni .= "<00> \n";
+ //$toUni .= sprintf("<00> <%02s>\n", strtoupper(dechex(count($font['subsets'][$sfid])-1)));
+ $toUni .= "endcodespacerange\n";
+ $toUni .= count($font['subsets'][$sfid])." beginbfchar\n";
+ $toUni .= $toUnistring;
+ $toUni .= "endbfchar\n";
+ $toUni .= "endcmap\n";
+ $toUni .= "CMapName currentdict /CMap defineresource pop\n";
+ $toUni .= "end\n";
+ $toUni .= "end\n";
+ $this->_out('<>');
+ $this->_putstream($toUni);
+ $this->_out('endobj');
+
+ //Font file
+ $this->_newobj();
+ $this->_out('<_out('/Filter /FlateDecode');
+ $this->_out('/Length1 '.$ttfontsize);
+ $this->_out('>>');
+ $this->_putstream($fontstream);
+ $this->_out('endobj');
+ } // foreach subset
+ unset($ttf);
+ }
+ // TrueType embedded SUBSETS or FULL
+ else if ($type=='TTF') {
+ $this->fonts[$k]['n']=$this->n+1;
+ if ($asSubset ) {
+ $ssfaid="A";
+ if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
+ $ttf = new TTFontFile();
+ $fontname = 'MPDFA'.$ssfaid.'+'.$font['name'];
+ $subset = $font['subset'];
+ unset($subset[0]);
+ $ttfontstream = $ttf->makeSubset($font['ttffile'], $subset, $font['TTCfontID'], $this->debugfonts, $font['useOTL']);
+ $ttfontsize = strlen($ttfontstream);
+ $fontstream = gzcompress($ttfontstream);
+ $codeToGlyph = $ttf->codeToGlyph;
+ unset($codeToGlyph[0]);
+ }
+ else { $fontname = $font['name']; }
+ // Type0 Font
+ // A composite font - a font composed of other fonts, organized hierarchically
+ $this->_newobj();
+ $this->_out('<_out('/Subtype /Type0');
+ $this->_out('/BaseFont /'.$fontname.'');
+ $this->_out('/Encoding /Identity-H');
+ $this->_out('/DescendantFonts ['.($this->n + 1).' 0 R]');
+ $this->_out('/ToUnicode '.($this->n + 2).' 0 R');
+ $this->_out('>>');
+ $this->_out('endobj');
+
+ // CIDFontType2
+ // A CIDFont whose glyph descriptions are based on TrueType font technology
+ $this->_newobj();
+ $this->_out('<_out('/Subtype /CIDFontType2');
+ $this->_out('/BaseFont /'.$fontname.'');
+ $this->_out('/CIDSystemInfo '.($this->n + 2).' 0 R');
+ $this->_out('/FontDescriptor '.($this->n + 3).' 0 R');
+ if (isset($font['desc']['MissingWidth'])){
+ $this->_out('/DW '.$font['desc']['MissingWidth'].'');
+ }
+
+ if (!$asSubset && file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw')) {
+ $w = '';
+ $w=file_get_contents(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw');
+ $this->_out($w);
+ }
+ else {
+ $this->_putTTfontwidths($font, $asSubset, ($asSubset ? $ttf->maxUni : 0));
+ }
+
+ $this->_out('/CIDToGIDMap '.($this->n + 4).' 0 R');
+ $this->_out('>>');
+ $this->_out('endobj');
+
+ // ToUnicode
+ $this->_newobj();
+ $toUni = "/CIDInit /ProcSet findresource begin\n";
+ $toUni .= "12 dict begin\n";
+ $toUni .= "begincmap\n";
+ $toUni .= "/CIDSystemInfo\n";
+ $toUni .= "<> def\n";
+ $toUni .= "/CMapName /Adobe-Identity-UCS def\n";
+ $toUni .= "/CMapType 2 def\n";
+ $toUni .= "1 begincodespacerange\n";
+ $toUni .= "<0000> \n";
+ $toUni .= "endcodespacerange\n";
+ $toUni .= "1 beginbfrange\n";
+ $toUni .= "<0000> <0000>\n";
+ $toUni .= "endbfrange\n";
+ $toUni .= "endcmap\n";
+ $toUni .= "CMapName currentdict /CMap defineresource pop\n";
+ $toUni .= "end\n";
+ $toUni .= "end\n";
+ $this->_out('<>');
+ $this->_putstream($toUni);
+ $this->_out('endobj');
+
+
+ // CIDSystemInfo dictionary
+ $this->_newobj();
+ $this->_out('<_out('/Ordering (UCS)');
+ $this->_out('/Supplement 0');
+ $this->_out('>>');
+ $this->_out('endobj');
+
+ // Font descriptor
+ $this->_newobj();
+ $this->_out('<_out('/FontName /'.$fontname);
+ foreach($font['desc'] as $kd=>$v) {
+ if ($asSubset && $kd == 'Flags') { $v = $v | 4; $v = $v & ~32; } // SYMBOLIC font flag
+ $this->_out(' /'.$kd.' '.$v);
+ }
+ if ($font['panose']) {
+ $this->_out(' /Style << /Panose <'.$font['panose'].'> >>');
+ }
+ if ($asSubset ) {
+ $this->_out('/FontFile2 '.($this->n + 2).' 0 R');
+ }
+ else if ($font['fontkey']) {
+ // obj ID of a stream containing a TrueType font program
+ $this->_out('/FontFile2 '.$this->FontFiles[$font['fontkey']]['n'].' 0 R');
+ }
+ $this->_out('>>');
+ $this->_out('endobj');
+
+ // Embed CIDToGIDMap
+ // A specification of the mapping from CIDs to glyph indices
+ if ($asSubset ) {
+ $cidtogidmap = '';
+ $cidtogidmap = str_pad('', 256*256*2, "\x00");
+ foreach($codeToGlyph as $cc=>$glyph) {
+ $cidtogidmap[$cc*2] = chr($glyph >> 8);
+ $cidtogidmap[$cc*2 + 1] = chr($glyph & 0xFF);
+ }
+ $cidtogidmap = gzcompress($cidtogidmap);
+ }
+ else {
+ // First see if there is a cached CIDToGIDMapfile
+ $cidtogidmap = '';
+ if (file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cgm')) {
+ $f=fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cgm','rb');
+ while(!feof($f)) { $cidtogidmap .= fread($f, 2048); }
+ fclose($f);
+ }
+ else {
+ if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
+ $ttf = new TTFontFile();
+ $charToGlyph = $ttf->getCTG($font['ttffile'], $font['TTCfontID'], $this->debugfonts, $font['useOTL']);
+ $cidtogidmap = str_pad('', 256*256*2, "\x00");
+ foreach($charToGlyph as $cc=>$glyph) {
+ $cidtogidmap[$cc*2] = chr($glyph >> 8);
+ $cidtogidmap[$cc*2 + 1] = chr($glyph & 0xFF);
+ }
+ unset($ttf);
+ $cidtogidmap = gzcompress($cidtogidmap);
+ if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
+ $fh = fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cgm',"wb");
+ fwrite($fh,$cidtogidmap,strlen($cidtogidmap));
+ fclose($fh);
+ }
+ }
+ }
+ $this->_newobj();
+ $this->_out('<_out('/Filter /FlateDecode');
+ $this->_out('>>');
+ $this->_putstream($cidtogidmap);
+ $this->_out('endobj');
+
+ //Font file
+ if ($asSubset ) {
+ $this->_newobj();
+ $this->_out('<_out('/Filter /FlateDecode');
+ $this->_out('/Length1 '.$ttfontsize);
+ $this->_out('>>');
+ $this->_putstream($fontstream);
+ $this->_out('endobj');
+ unset($ttf);
+ }
+ }
+ else { $this->Error('Unsupported font type: '.$type.' ('.$name.')'); }
+ }
+}
+
+
+
+function _putTTfontwidths(&$font, $asSubset, $maxUni) {
+ if ($asSubset && file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php')) {
+ include(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php') ;
+ $startcid = 128;
+ }
+ else {
+ $rangeid = 0;
+ $range = array();
+ $prevcid = -2;
+ $prevwidth = -1;
+ $interval = false;
+ $startcid = 1;
+ }
+ if ($asSubset) { $cwlen = $maxUni + 1; }
+ else { $cwlen = (strlen($font['cw'])/2); }
+
+ // for each character
+ for ($cid=$startcid; $cid<$cwlen; $cid++) {
+ if ($cid==128 && $asSubset && (!file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php'))) {
+ if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
+ $fh = fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw127.php',"wb");
+ $cw127='";
+ fwrite($fh,$cw127,strlen($cw127));
+ fclose($fh);
+ }
+ }
+ if ($font['cw'][$cid*2] == "\00" && $font['cw'][$cid*2+1] == "\00") { continue; }
+ $width = (ord($font['cw'][$cid*2]) << 8) + ord($font['cw'][$cid*2+1]);
+ if ($width == 65535) { $width = 0; }
+ if ($asSubset && $cid > 255 && (!isset($font['subset'][$cid]) || !$font['subset'][$cid])) {
+ continue;
+ }
+ if ($asSubset && $cid > 0xFFFF) { continue; } // mPDF 6
+ if (!isset($font['dw']) || (isset($font['dw']) && $width != $font['dw'])) {
+ if ($cid == ($prevcid + 1)) {
+ // consecutive CID
+ if ($width == $prevwidth) {
+ if ($width == $range[$rangeid][0]) {
+ $range[$rangeid][] = $width;
+ } else {
+ array_pop($range[$rangeid]);
+ // new range
+ $rangeid = $prevcid;
+ $range[$rangeid] = array();
+ $range[$rangeid][] = $prevwidth;
+ $range[$rangeid][] = $width;
+ }
+ $interval = true;
+ $range[$rangeid]['interval'] = true;
+ } else {
+ if ($interval) {
+ // new range
+ $rangeid = $cid;
+ $range[$rangeid] = array();
+ $range[$rangeid][] = $width;
+ } else {
+ $range[$rangeid][] = $width;
+ }
+ $interval = false;
+ }
+ } else {
+ // new range
+ $rangeid = $cid;
+ $range[$rangeid] = array();
+ $range[$rangeid][] = $width;
+ $interval = false;
+ }
+ $prevcid = $cid;
+ $prevwidth = $width;
+ }
+ }
+ $w = $this->_putfontranges($range);
+ $this->_out($w);
+ if (!$asSubset) {
+ if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
+ $fh = fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw',"wb");
+ fwrite($fh,$w,strlen($w));
+ fclose($fh);
+ }
+ }
+}
+
+function _putfontranges(&$range) {
+ // optimize ranges
+ $prevk = -1;
+ $nextk = -1;
+ $prevint = false;
+ foreach ($range as $k => $ws) {
+ $cws = count($ws);
+ if (($k == $nextk) AND (!$prevint) AND ((!isset($ws['interval'])) OR ($cws < 4))) {
+ if (isset($range[$k]['interval'])) {
+ unset($range[$k]['interval']);
+ }
+ $range[$prevk] = array_merge($range[$prevk], $range[$k]);
+ unset($range[$k]);
+ } else {
+ $prevk = $k;
+ }
+ $nextk = $k + $cws;
+ if (isset($ws['interval'])) {
+ if ($cws > 3) {
+ $prevint = true;
+ } else {
+ $prevint = false;
+ }
+ unset($range[$k]['interval']);
+ --$nextk;
+ } else {
+ $prevint = false;
+ }
+ }
+ // output data
+ $w = '';
+ foreach ($range as $k => $ws) {
+ if (count(array_count_values($ws)) == 1) {
+ // interval mode is more compact
+ $w .= ' '.$k.' '.($k + count($ws) - 1).' '.$ws[0];
+ } else {
+ // range mode
+ $w .= ' '.$k.' [ '.implode(' ', $ws).' ]' . "\n";
+ }
+ }
+ return '/W ['.$w.' ]';
+}
+
+
+function _putfontwidths(&$font, $cidoffset=0) {
+ ksort($font['cw']);
+ unset($font['cw'][65535]);
+ $rangeid = 0;
+ $range = array();
+ $prevcid = -2;
+ $prevwidth = -1;
+ $interval = false;
+ // for each character
+ foreach ($font['cw'] as $cid => $width) {
+ $cid -= $cidoffset;
+ if (!isset($font['dw']) || (isset($font['dw']) && $width != $font['dw'])) {
+ if ($cid == ($prevcid + 1)) {
+ // consecutive CID
+ if ($width == $prevwidth) {
+ if ($width == $range[$rangeid][0]) {
+ $range[$rangeid][] = $width;
+ } else {
+ array_pop($range[$rangeid]);
+ // new range
+ $rangeid = $prevcid;
+ $range[$rangeid] = array();
+ $range[$rangeid][] = $prevwidth;
+ $range[$rangeid][] = $width;
+ }
+ $interval = true;
+ $range[$rangeid]['interval'] = true;
+ } else {
+ if ($interval) {
+ // new range
+ $rangeid = $cid;
+ $range[$rangeid] = array();
+ $range[$rangeid][] = $width;
+ } else {
+ $range[$rangeid][] = $width;
+ }
+ $interval = false;
+ }
+ } else {
+ // new range
+ $rangeid = $cid;
+ $range[$rangeid] = array();
+ $range[$rangeid][] = $width;
+ $interval = false;
+ }
+ $prevcid = $cid;
+ $prevwidth = $width;
+ }
+ }
+ $this->_out($this->_putfontranges($range));
+}
+
+
+/*-- CJK-FONTS --*/
+
+// from class PDF_Chinese CJK EXTENSIONS
+function _putType0(&$font)
+{
+ //Type0
+ $this->_out('/Subtype /Type0');
+ $this->_out('/BaseFont /'.$font['name'].'-'.$font['CMap']);
+ $this->_out('/Encoding /'.$font['CMap']);
+ $this->_out('/DescendantFonts ['.($this->n+1).' 0 R]');
+ $this->_out('>>');
+ $this->_out('endobj');
+ //CIDFont
+ $this->_newobj();
+ $this->_out('<_out('/Subtype /CIDFontType0');
+ $this->_out('/BaseFont /'.$font['name']);
+
+ $cidinfo = '/Registry '.$this->_textstring('Adobe');
+ $cidinfo .= ' /Ordering '.$this->_textstring($font['registry']['ordering']);
+ $cidinfo .= ' /Supplement '.$font['registry']['supplement'];
+ $this->_out('/CIDSystemInfo <<'.$cidinfo.'>>');
+
+ $this->_out('/FontDescriptor '.($this->n+1).' 0 R');
+ if (isset($font['MissingWidth'])){
+ $this->_out('/DW '.$font['MissingWidth'].'');
+ }
+ $this->_putfontwidths($font, 31);
+ $this->_out('>>');
+ $this->_out('endobj');
+
+ //Font descriptor
+ $this->_newobj();
+ $s = '< $v) {
+ if ($k != 'Style') {
+ $s .= ' /'.$k.' '.$v.'';
+ }
+ }
+ $this->_out($s.'>>');
+ $this->_out('endobj');
+}
+/*-- END CJK-FONTS --*/
+
+
+
+function _putimages()
+{
+ $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
+ reset($this->images);
+ while(list($file,$info)=each($this->images)) {
+ $this->_newobj();
+ $this->images[$file]['n']=$this->n;
+ $this->_out('<_out('/Subtype /Image');
+ $this->_out('/Width '.$info['w']);
+ $this->_out('/Height '.$info['h']);
+ if (isset($info['interpolation']) && $info['interpolation']) {
+ $this->_out('/Interpolate true'); // mPDF 6 - image interpolation shall be performed by a conforming reader
+ }
+ if (isset($info['masked'])) {
+ $this->_out('/SMask '.($this->n - 1).' 0 R');
+ }
+ // set color space
+ $icc = false;
+ if (isset($info['icc']) AND ($info['icc'] !== false)) {
+ // ICC Colour Space
+ $icc = true;
+ $this->_out('/ColorSpace [/ICCBased '.($this->n + 1).' 0 R]');
+ }
+ else if($info['cs']=='Indexed') {
+ if ($this->PDFX || ($this->PDFA && $this->restrictColorSpace==3)) { $this->Error("PDFA1-b and PDFX/1-a files do not permit using mixed colour space (".$file.")."); }
+ $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]');
+ }
+ else {
+ $this->_out('/ColorSpace /'.$info['cs']);
+ if($info['cs']=='DeviceCMYK') {
+ if ($this->PDFA && $this->restrictColorSpace!=3) { $this->Error("PDFA1-b does not permit Images using mixed colour space (".$file.")."); }
+ if($info['type']=='jpg') { $this->_out('/Decode [1 0 1 0 1 0 1 0]'); }
+ }
+ else if ($info['cs']=='DeviceRGB' && ($this->PDFX || ($this->PDFA && $this->restrictColorSpace==3))) { $this->Error("PDFA1-b and PDFX/1-a files do not permit using mixed colour space (".$file.")."); }
+ }
+ $this->_out('/BitsPerComponent '.$info['bpc']);
+ if (isset($info['f']) && $info['f']) { $this->_out('/Filter /'.$info['f']); }
+ if(isset($info['parms'])) { $this->_out($info['parms']); }
+ if(isset($info['trns']) and is_array($info['trns'])) {
+ $trns='';
+ for($i=0;$i_out('/Mask ['.$trns.']');
+ }
+ $this->_out('/Length '.strlen($info['data']).'>>');
+ $this->_putstream($info['data']);
+ unset($this->images[$file]['data']);
+ $this->_out('endobj');
+
+ // ICC colour profile
+ if ($icc) {
+ $this->_newobj();
+ $icc = ($this->compress) ? gzcompress($info['icc']) : $info['icc'];
+ $this->_out('<>');
+ $this->_putstream($icc);
+ $this->_out('endobj');
+ }
+ //Palette
+ else if($info['cs']=='Indexed') {
+ $this->_newobj();
+ $pal=($this->compress) ? gzcompress($info['pal']) : $info['pal'];
+ $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
+ $this->_putstream($pal);
+ $this->_out('endobj');
+ }
+ }
+}
+
+function _putinfo()
+{
+ $this->_out('/Producer '.$this->_UTF16BEtextstring('mPDF '.mPDF_VERSION));
+ if(!empty($this->title))
+ $this->_out('/Title '.$this->_UTF16BEtextstring($this->title));
+ if(!empty($this->subject))
+ $this->_out('/Subject '.$this->_UTF16BEtextstring($this->subject));
+ if(!empty($this->author))
+ $this->_out('/Author '.$this->_UTF16BEtextstring($this->author));
+ if(!empty($this->keywords))
+ $this->_out('/Keywords '.$this->_UTF16BEtextstring($this->keywords));
+ if(!empty($this->creator))
+ $this->_out('/Creator '.$this->_UTF16BEtextstring($this->creator));
+
+ $z = date('O'); // +0200
+ $offset = substr($z,0,3)."'".substr($z,3,2)."'";
+ $this->_out('/CreationDate '.$this->_textstring(date('YmdHis').$offset));
+ $this->_out('/ModDate '.$this->_textstring(date('YmdHis').$offset));
+ if ($this->PDFX) {
+ $this->_out('/Trapped/False');
+ $this->_out('/GTS_PDFXVersion(PDF/X-1a:2003)');
+ }
+}
+
+function _putmetadata() {
+ $this->_newobj();
+ $this->MetadataRoot = $this->n;
+ $Producer = 'mPDF '.mPDF_VERSION;
+ $z = date('O'); // +0200
+ $offset = substr($z,0,3).':'.substr($z,3,2);
+ $CreationDate = date('Y-m-d\TH:i:s').$offset; // 2006-03-10T10:47:26-05:00 2006-06-19T09:05:17Z
+ $uuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff),
+ mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000,
+ mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff) );
+
+
+ $m = ''."\n"; // begin = FEFF BOM
+ $m .= ' '."\n";
+ $m .= ' '."\n";
+ $m .= ' '."\n";
+ $m .= ' '.$Producer.''."\n";
+ if(!empty($this->keywords)) { $m .= ' '.$this->keywords.''."\n"; }
+ $m .= ' '."\n";
+
+ $m .= ' '."\n";
+ $m .= ' '.$CreationDate.''."\n";
+ $m .= ' '.$CreationDate.''."\n";
+ $m .= ' '.$CreationDate.''."\n";
+ if(!empty($this->creator)) { $m .= ' '.$this->creator.''."\n"; }
+ $m .= ' '."\n";
+
+ // DC elements
+ $m .= ' '."\n";
+ $m .= ' application/pdf'."\n";
+ if(!empty($this->title)) {
+ $m .= '
+
+ '.$this->title.'
+
+ '."\n";
+ }
+ if(!empty($this->keywords)) {
+ $m .= '
+
+ '.$this->keywords.'
+
+ '."\n";
+ }
+ if(!empty($this->subject)) {
+ $m .= '
+
+ '.$this->subject.'
+
+ '."\n";
+ }
+ if(!empty($this->author)) {
+ $m .= '
+
+ '.$this->author.'
+
+ '."\n";
+ }
+ $m .= ' '."\n";
+
+
+ // This bit is specific to PDFX-1a
+ if ($this->PDFX) {
+ $m .= ' '."\n";
+ }
+
+ // This bit is specific to PDFA-1b
+ else if ($this->PDFA) {
+ $m .= ' '."\n";
+ $m .= ' 1'."\n";
+ $m .= ' B'."\n";
+ $m .= ' 2005'."\n";
+ $m .= ' '."\n";
+ }
+
+ $m .= ' '."\n";
+ $m .= ' uuid:'.$uuid.''."\n";
+ $m .= ' '."\n";
+ $m .= ' '."\n";
+ $m .= ' '."\n";
+ $m .= str_repeat(str_repeat(' ',100)."\n",20); // 2-4kB whitespace padding required
+ $m .= ''; // "r" read only
+ $this->_out('<>');
+ $this->_putstream($m);
+ $this->_out('endobj');
+}
+
+function _putoutputintent() {
+ $this->_newobj();
+ $this->OutputIntentRoot = $this->n;
+ $this->_out('<PDFA) {
+ $this->_out('/S /GTS_PDFA1');
+ if ($this->ICCProfile) {
+ $this->_out('/Info ('.preg_replace('/_/',' ',$this->ICCProfile).')');
+ $this->_out('/OutputConditionIdentifier (Custom)');
+ $this->_out('/OutputCondition ()');
+ }
+ else {
+ $this->_out('/Info (sRGB IEC61966-2.1)');
+ $this->_out('/OutputConditionIdentifier (sRGB IEC61966-2.1)');
+ $this->_out('/OutputCondition ()');
+ }
+ $this->_out('/DestOutputProfile '.($this->n+1).' 0 R');
+ }
+ else if ($this->PDFX) { // always a CMYK profile
+ $this->_out('/S /GTS_PDFX');
+ if ($this->ICCProfile) {
+ $this->_out('/Info ('.preg_replace('/_/',' ',$this->ICCProfile).')');
+ $this->_out('/OutputConditionIdentifier (Custom)');
+ $this->_out('/OutputCondition ()');
+ $this->_out('/DestOutputProfile '.($this->n+1).' 0 R');
+ }
+ else {
+ $this->_out('/Info (CGATS TR 001)');
+ $this->_out('/OutputConditionIdentifier (CGATS TR 001)');
+ $this->_out('/OutputCondition (CGATS TR 001 (SWOP))');
+ $this->_out('/RegistryName (http://www.color.org)');
+ }
+ }
+ $this->_out('>>');
+ $this->_out('endobj');
+
+ if ($this->PDFX && !$this->ICCProfile) { return; } // no ICCProfile embedded
+
+ $this->_newobj();
+ if ($this->ICCProfile)
+ $s = file_get_contents(_MPDF_PATH.'iccprofiles/'.$this->ICCProfile.'.icc');
+ else
+ $s = file_get_contents(_MPDF_PATH.'iccprofiles/sRGB_IEC61966-2-1.icc');
+ if ($this->compress) { $s = gzcompress($s); }
+ $this->_out('<<');
+ if ($this->PDFX || ($this->PDFA && $this->restrictColorSpace == 3)) { $this->_out('/N 4'); }
+ else { $this->_out('/N 3'); }
+ if ($this->compress)
+ $this->_out('/Filter /FlateDecode ');
+ $this->_out('/Length '.strlen($s).'>>');
+ $this->_putstream($s);
+ $this->_out('endobj');
+}
+
+
+function _putcatalog() {
+ $this->_out('/Type /Catalog');
+ $this->_out('/Pages 1 0 R');
+ if($this->ZoomMode=='fullpage') $this->_out('/OpenAction [3 0 R /Fit]');
+ elseif($this->ZoomMode=='fullwidth') $this->_out('/OpenAction [3 0 R /FitH null]');
+ elseif($this->ZoomMode=='real') $this->_out('/OpenAction [3 0 R /XYZ null null 1]');
+ elseif(!is_string($this->ZoomMode)) $this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode/100).']');
+ else $this->_out('/OpenAction [3 0 R /XYZ null null null]');
+ if($this->LayoutMode=='single') $this->_out('/PageLayout /SinglePage');
+ elseif($this->LayoutMode=='continuous') $this->_out('/PageLayout /OneColumn');
+ elseif($this->LayoutMode=='twoleft') $this->_out('/PageLayout /TwoColumnLeft');
+ elseif($this->LayoutMode=='tworight') $this->_out('/PageLayout /TwoColumnRight');
+ elseif($this->LayoutMode=='two') {
+ if ($this->mirrorMargins) { $this->_out('/PageLayout /TwoColumnRight'); }
+ else { $this->_out('/PageLayout /TwoColumnLeft'); }
+ }
+
+/*-- BOOKMARKS --*/
+ if(count($this->BMoutlines)>0) {
+ $this->_out('/Outlines '.$this->OutlineRoot.' 0 R');
+ $this->_out('/PageMode /UseOutlines');
+ }
+/*-- END BOOKMARKS --*/
+ if(is_int(strpos($this->DisplayPreferences,'FullScreen'))) $this->_out('/PageMode /FullScreen');
+
+ // Metadata
+ if ($this->PDFA || $this->PDFX) {
+ $this->_out('/Metadata '.$this->MetadataRoot.' 0 R');
+ }
+ // OutputIntents
+ if ($this->PDFA || $this->PDFX || $this->ICCProfile) {
+ $this->_out('/OutputIntents ['.$this->OutputIntentRoot.' 0 R]');
+ }
+
+/*-- FORMS --*/
+ if (count($this->mpdfform->forms)>0) {
+ $this->mpdfform->_putFormsCatalog();
+ }
+/*-- END FORMS --*/
+ if ( isset($this->js) ) {
+ $this->_out('/Names << /JavaScript '.($this->n_js).' 0 R >> ');
+ }
+
+ if($this->DisplayPreferences || $this->directionality == 'rtl' || $this->mirrorMargins) {
+ $this->_out('/ViewerPreferences<<');
+ if(is_int(strpos($this->DisplayPreferences,'HideMenubar'))) $this->_out('/HideMenubar true');
+ if(is_int(strpos($this->DisplayPreferences,'HideToolbar'))) $this->_out('/HideToolbar true');
+ if(is_int(strpos($this->DisplayPreferences,'HideWindowUI'))) $this->_out('/HideWindowUI true');
+ if(is_int(strpos($this->DisplayPreferences,'DisplayDocTitle'))) $this->_out('/DisplayDocTitle true');
+ if(is_int(strpos($this->DisplayPreferences,'CenterWindow'))) $this->_out('/CenterWindow true');
+ if(is_int(strpos($this->DisplayPreferences,'FitWindow'))) $this->_out('/FitWindow true');
+ // /PrintScaling is PDF 1.6 spec.
+ if(is_int(strpos($this->DisplayPreferences,'NoPrintScaling')) && !$this->PDFA && !$this->PDFX)
+ $this->_out('/PrintScaling /None');
+ if($this->directionality == 'rtl') $this->_out('/Direction /R2L');
+ // /Duplex is PDF 1.7 spec.
+ if($this->mirrorMargins && !$this->PDFA && !$this->PDFX) {
+ // if ($this->DefOrientation=='P') $this->_out('/Duplex /DuplexFlipShortEdge');
+ $this->_out('/Duplex /DuplexFlipLongEdge'); // PDF v1.7+
+ }
+ $this->_out('>>');
+ }
+ if($this->open_layer_pane && ($this->hasOC || count($this->layers)))
+ $this->_out('/PageMode /UseOC');
+
+ if ($this->hasOC || count($this->layers)) {
+ $p = $v = $h = $l = $loff = $lall = $as = '';
+ if ($this->hasOC) {
+ if (($this->hasOC & 1) == 1) $p=$this->n_ocg_print.' 0 R';
+ if (($this->hasOC & 2) == 2) $v=$this->n_ocg_view.' 0 R';
+ if (($this->hasOC & 4) == 4) $h=$this->n_ocg_hidden.' 0 R';
+ $as="<> <>";
+ }
+
+ if(count($this->layers)) {
+ foreach($this->layers as $k=>$layer) {
+ if (strtolower($this->layerDetails[$k]['state'])=='hidden') { $loff .= $layer['n'].' 0 R '; }
+ else { $l .= $layer['n'].' 0 R '; }
+ $lall .= $layer['n'].' 0 R ';
+ }
+ }
+ $this->_out("/OCProperties <_out("/Order [$v $p $h $lall] ");
+ if ($as) $this->_out("/AS [$as] ");
+ $this->_out(">>>>");
+
+ }
+
+}
+
+// Inactive function left for backwards compatability
+function SetUserRights($enable=true, $annots="", $form="", $signature="") {
+ // Does nothing
+}
+
+function _enddoc() {
+ if ($this->progressBar) { $this->UpdateProgressBar(2,'10','Writing Headers & Footers'); } // *PROGRESS-BAR*
+ $this->_puthtmlheaders();
+ if ($this->progressBar) { $this->UpdateProgressBar(2,'20','Writing Pages'); } // *PROGRESS-BAR*
+
+ // Remove references to unused fonts (usually default font)
+ foreach($this->fonts as $fk=>$font) {
+ if (isset($font['type']) && $font['type']=='TTF' && !$font['used']) {
+ if ($font['sip'] || $font['smp']) {
+ foreach($font['subsetfontids'] AS $k => $fid) {
+ foreach($this->pages AS $pn=>$page) {
+ $this->pages[$pn] = preg_replace('/\s\/F'.$fid.' \d[\d.]* Tf\s/is',' ',$this->pages[$pn]);
+ }
+ }
+ }
+ else {
+ foreach($this->pages AS $pn=>$page) {
+ $this->pages[$pn] = preg_replace('/\s\/F'.$font['i'].' \d[\d.]* Tf\s/is',' ',$this->pages[$pn]);
+ }
+ }
+ }
+ }
+
+ if (count($this->layers)) {
+ foreach($this->pages AS $pn=>$page) {
+ preg_match_all('/\/OCZ-index \/ZI(\d+) BDC(.*?)(EMCZ)-index/is',$this->pages[$pn],$m1);
+ preg_match_all('/\/OCBZ-index \/ZI(\d+) BDC(.*?)(EMCBZ)-index/is',$this->pages[$pn],$m2);
+ preg_match_all('/\/OCGZ-index \/ZI(\d+) BDC(.*?)(EMCGZ)-index/is',$this->pages[$pn],$m3);
+ $m = array();
+ for ($i=0;$i<4;$i++) {
+ $m[$i] = array_merge($m1[$i],$m2[$i],$m3[$i]);
+ }
+ if (count($m[0])) {
+ $sortarr = array();
+ for($i=0;$i$k) {
+ $this->pages[$pn] = str_replace($m[0][$i],'',$this->pages[$pn] );
+ $this->pages[$pn] .= "\n".$m[0][$i]."\n";
+ }
+ $this->pages[$pn] = preg_replace('/\/OC[BG]{0,1}Z-index \/ZI(\d+) BDC/is','/OC /ZI\\1 BDC ',$this->pages[$pn]);
+ $this->pages[$pn] = preg_replace('/EMC[BG]{0,1}Z-index/is','EMC',$this->pages[$pn]);
+ }
+ }
+ }
+
+ $this->_putpages();
+ if ($this->progressBar) { $this->UpdateProgressBar(2,'30','Writing document resources'); } // *PROGRESS-BAR*
+
+ $this->_putresources();
+ //Info
+ $this->_newobj();
+ $this->InfoRoot = $this->n;
+ $this->_out('<<');
+ if ($this->progressBar) { $this->UpdateProgressBar(2,'80','Writing document info'); } // *PROGRESS-BAR*
+ $this->_putinfo();
+ $this->_out('>>');
+ $this->_out('endobj');
+
+ // METADATA
+ if ($this->PDFA || $this->PDFX) { $this->_putmetadata(); }
+ // OUTPUTINTENT
+ if ($this->PDFA || $this->PDFX || $this->ICCProfile) { $this->_putoutputintent(); }
+
+ //Catalog
+ $this->_newobj();
+ $this->_out('<<');
+ if ($this->progressBar) { $this->UpdateProgressBar(2,'90','Writing document catalog'); } // *PROGRESS-BAR*
+ $this->_putcatalog();
+ $this->_out('>>');
+ $this->_out('endobj');
+ //Cross-ref
+ $o=strlen($this->buffer);
+ $this->_out('xref');
+ $this->_out('0 '.($this->n+1));
+ $this->_out('0000000000 65535 f ');
+ for($i=1; $i <= $this->n ; $i++)
+ $this->_out(sprintf('%010d 00000 n ',$this->offsets[$i]));
+ //Trailer
+ $this->_out('trailer');
+ $this->_out('<<');
+ $this->_puttrailer();
+ $this->_out('>>');
+ $this->_out('startxref');
+ $this->_out($o);
+
+ $this->buffer .= '%%EOF';
+ $this->state=3;
+/*-- IMPORTS --*/
+
+ if ($this->enableImports && count($this->parsers) > 0) {
+ foreach ($this->parsers as $k => $_){
+ $this->parsers[$k]->closeFile();
+ $this->parsers[$k] = null;
+ unset($this->parsers[$k]);
+ }
+ }
+/*-- END IMPORTS --*/
+}
+
+function _beginpage($orientation,$mgl='',$mgr='',$mgt='',$mgb='',$mgh='',$mgf='',$ohname='',$ehname='',$ofname='',$efname='',$ohvalue=0,$ehvalue=0,$ofvalue=0,$efvalue=0,$pagesel='',$newformat='') {
+ if (!($pagesel && $this->page==1 && (sprintf("%0.4f", $this->y)==sprintf("%0.4f", $this->tMargin)))) {
+ $this->page++;
+ $this->pages[$this->page]='';
+ }
+ $this->state=2;
+ $resetHTMLHeadersrequired = false;
+
+ if ($newformat) { $this->_setPageSize($newformat, $orientation); }
+/*-- CSS-PAGE --*/
+ // Paged media (page-box)
+ if ($pagesel || (isset($this->page_box['using']) && $this->page_box['using'])) {
+ if ($pagesel || $this->page==1) { $first = true; }
+ else { $first = false; }
+ if ($this->mirrorMargins && ($this->page % 2==0)) { $oddEven = 'E'; }
+ else { $oddEven = 'O'; }
+ if ($pagesel) { $psel = $pagesel; }
+ else if ($this->page_box['current']) { $psel = $this->page_box['current']; }
+ else { $psel = ''; }
+ list($orientation,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$hname,$fname,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat) = $this->SetPagedMediaCSS($psel, $first, $oddEven);
+ if ($this->mirrorMargins && ($this->page % 2==0)) {
+ if ($hname) { $ehvalue = 1; $ehname = $hname; } else { $ehvalue = -1; }
+ if ($fname) { $efvalue = 1; $efname = $fname; } else { $efvalue = -1; }
+ }
+ else {
+ if ($hname) { $ohvalue = 1; $ohname = $hname; } else { $ohvalue = -1; }
+ if ($fname) { $ofvalue = 1; $ofname = $fname; } else { $ofvalue = -1; }
+ }
+ if ($resetpagenum || $pagenumstyle || $suppress) {
+ $this->PageNumSubstitutions[] = array('from'=>($this->page), 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=>$suppress);
+ }
+ // PAGED MEDIA - CROP / CROSS MARKS from @PAGE
+ $this->show_marks = $marks;
+
+ // Background color
+ if (isset($bg['BACKGROUND-COLOR'])) {
+ $cor = $this->ConvertColor($bg['BACKGROUND-COLOR']);
+ if ($cor) {
+ $this->bodyBackgroundColor = $cor;
+ }
+ }
+ else { $this->bodyBackgroundColor = false; }
+
+/*-- BACKGROUNDS --*/
+ if (isset($bg['BACKGROUND-GRADIENT'])) {
+ $this->bodyBackgroundGradient = $bg['BACKGROUND-GRADIENT'];
+ }
+ else { $this->bodyBackgroundGradient = false; }
+
+ // Tiling Patterns
+ if (isset($bg['BACKGROUND-IMAGE']) && $bg['BACKGROUND-IMAGE']) {
+ $ret = $this->SetBackground($bg, $this->pgwidth);
+ if ($ret) { $this->bodyBackgroundImage = $ret; }
+ }
+ else { $this->bodyBackgroundImage = false; }
+/*-- END BACKGROUNDS --*/
+
+ $this->page_box['current'] = $psel;
+ $this->page_box['using'] = true;
+ }
+/*-- END CSS-PAGE --*/
+
+ //Page orientation
+ if(!$orientation)
+ $orientation=$this->DefOrientation;
+ else {
+ $orientation=strtoupper(substr($orientation,0,1));
+ if($orientation!=$this->DefOrientation)
+ $this->OrientationChanges[$this->page]=true;
+ }
+ if($orientation!=$this->CurOrientation || $newformat) {
+
+ //Change orientation
+ if($orientation=='P') {
+ $this->wPt=$this->fwPt;
+ $this->hPt=$this->fhPt;
+ $this->w=$this->fw;
+ $this->h=$this->fh;
+ if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation=='P') {
+ $this->tMargin = $this->orig_tMargin;
+ $this->bMargin = $this->orig_bMargin;
+ $this->DeflMargin = $this->orig_lMargin;
+ $this->DefrMargin = $this->orig_rMargin;
+ $this->margin_header = $this->orig_hMargin;
+ $this->margin_footer = $this->orig_fMargin;
+ }
+ else { $resetHTMLHeadersrequired = true; }
+ }
+ else {
+ $this->wPt=$this->fhPt;
+ $this->hPt=$this->fwPt;
+ $this->w=$this->fh;
+ $this->h=$this->fw;
+ if (($this->forcePortraitHeaders || $this->forcePortraitMargins) && $this->DefOrientation=='P') {
+ $this->tMargin = $this->orig_lMargin;
+ $this->bMargin = $this->orig_rMargin;
+ $this->DeflMargin = $this->orig_bMargin;
+ $this->DefrMargin = $this->orig_tMargin;
+ $this->margin_header = $this->orig_hMargin;
+ $this->margin_footer = $this->orig_fMargin;
+ }
+ else { $resetHTMLHeadersrequired = true; }
+
+ }
+ $this->CurOrientation=$orientation;
+ $this->ResetMargins();
+ $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
+ $this->PageBreakTrigger=$this->h-$this->bMargin;
+ }
+
+ $this->pageDim[$this->page]['w']=$this->w ;
+ $this->pageDim[$this->page]['h']=$this->h ;
+
+ $this->pageDim[$this->page]['outer_width_LR'] = isset($this->page_box['outer_width_LR']) ? $this->page_box['outer_width_LR'] : 0;
+ $this->pageDim[$this->page]['outer_width_TB'] = isset($this->page_box['outer_width_TB']) ? $this->page_box['outer_width_TB'] : 0;
+ if (!isset($this->page_box['outer_width_LR']) && !isset($this->page_box['outer_width_TB'])) {
+ $this->pageDim[$this->page]['bleedMargin'] = 0;
+ }
+ else if ($this->bleedMargin <= $this->page_box['outer_width_LR'] && $this->bleedMargin <= $this->page_box['outer_width_TB']) {
+ $this->pageDim[$this->page]['bleedMargin'] = $this->bleedMargin;
+ }
+ else {
+ $this->pageDim[$this->page]['bleedMargin'] = min($this->page_box['outer_width_LR'], $this->page_box['outer_width_TB'])-0.01;
+ }
+
+ // If Page Margins are re-defined
+ // strlen()>0 is used to pick up (integer) 0, (string) '0', or set value
+ if ((strlen($mgl)>0 && $this->DeflMargin != $mgl) || (strlen($mgr)>0 && $this->DefrMargin != $mgr) || (strlen($mgt)>0 && $this->tMargin != $mgt) || (strlen($mgb)>0 && $this->bMargin != $mgb) || (strlen($mgh)>0 && $this->margin_header!=$mgh) || (strlen($mgf)>0 && $this->margin_footer!=$mgf)) {
+ if (strlen($mgl)>0) $this->DeflMargin = $mgl;
+ if (strlen($mgr)>0) $this->DefrMargin = $mgr;
+ if (strlen($mgt)>0) $this->tMargin = $mgt;
+ if (strlen($mgb)>0) $this->bMargin = $mgb;
+ if (strlen($mgh)>0) $this->margin_header=$mgh;
+ if (strlen($mgf)>0) $this->margin_footer=$mgf;
+ $this->ResetMargins();
+ $this->SetAutoPageBreak($this->autoPageBreak,$this->bMargin);
+ $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
+ $resetHTMLHeadersrequired = true;
+ }
+
+ $this->ResetMargins();
+ $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
+ $this->SetAutoPageBreak($this->autoPageBreak,$this->bMargin);
+
+ // Reset column top margin
+ $this->y0 = $this->tMargin;
+
+ $this->x=$this->lMargin;
+ $this->y=$this->tMargin;
+ $this->FontFamily='';
+
+ // HEADERS AND FOOTERS // mPDF 6
+ if ($ohvalue<0 || strtoupper($ohvalue)=='OFF') {
+ $this->HTMLHeader = '';
+ $resetHTMLHeadersrequired = true;
+ }
+ else if ($ohname && $ohvalue>0) {
+ if (preg_match('/^html_(.*)$/i',$ohname,$n)) { $name = $n[1]; }
+ else { $name = $ohname; }
+ if (isset($this->pageHTMLheaders[$name])) { $this->HTMLHeader = $this->pageHTMLheaders[$name]; }
+ else { $this->HTMLHeader = ''; }
+ $resetHTMLHeadersrequired = true;
+ }
+
+ if ($ehvalue<0 || strtoupper($ehvalue)=='OFF') {
+ $this->HTMLHeaderE = '';
+ $resetHTMLHeadersrequired = true;
+ }
+ else if ($ehname && $ehvalue>0) {
+ if (preg_match('/^html_(.*)$/i',$ehname,$n)) { $name = $n[1]; }
+ else { $name = $ehname; }
+ if (isset($this->pageHTMLheaders[$name])) { $this->HTMLHeaderE = $this->pageHTMLheaders[$name]; }
+ else { $this->HTMLHeaderE = ''; }
+ $resetHTMLHeadersrequired = true;
+ }
+
+ if ($ofvalue<0 || strtoupper($ofvalue)=='OFF') {
+ $this->HTMLFooter = '';
+ $resetHTMLHeadersrequired = true;
+ }
+ else if ($ofname && $ofvalue>0) {
+ if (preg_match('/^html_(.*)$/i',$ofname,$n)) { $name = $n[1]; }
+ else { $name = $ofname; }
+ if (isset($this->pageHTMLfooters[$name])) { $this->HTMLFooter = $this->pageHTMLfooters[$name]; }
+ else { $this->HTMLFooter = ''; }
+ $resetHTMLHeadersrequired = true;
+ }
+
+ if ($efvalue<0 || strtoupper($efvalue)=='OFF') {
+ $this->HTMLFooterE = '';
+ $resetHTMLHeadersrequired = true;
+ }
+ else if ($efname && $efvalue>0) {
+ if (preg_match('/^html_(.*)$/i',$efname,$n)) { $name = $n[1]; }
+ else { $name = $efname; }
+ if (isset($this->pageHTMLfooters[$name])) { $this->HTMLFooterE = $this->pageHTMLfooters[$name]; }
+ else { $this->HTMLFooterE = ''; }
+ $resetHTMLHeadersrequired = true;
+ }
+ if ($resetHTMLHeadersrequired) {
+ $this->SetHTMLHeader($this->HTMLHeader );
+ $this->SetHTMLHeader($this->HTMLHeaderE ,'E');
+ $this->SetHTMLFooter($this->HTMLFooter );
+ $this->SetHTMLFooter($this->HTMLFooterE ,'E');
+ }
+
+
+ if (($this->mirrorMargins) && (($this->page)%2==0)) { // EVEN
+ $this->_setAutoHeaderHeight($this->HTMLHeaderE);
+ $this->_setAutoFooterHeight($this->HTMLFooterE);
+ }
+ else { // ODD or DEFAULT
+ $this->_setAutoHeaderHeight($this->HTMLHeader);
+ $this->_setAutoFooterHeight($this->HTMLFooter);
+ }
+ // Reset column top margin
+ $this->y0 = $this->tMargin;
+
+ $this->x=$this->lMargin;
+ $this->y=$this->tMargin;
+}
+
+
+// mPDF 6
+function _setAutoHeaderHeight(&$htmlh) {
+ if ($this->setAutoTopMargin=='pad') {
+ if (isset($htmlh['h']) && $htmlh['h']) { $h = $htmlh['h']; } // 5.7.3
+ else { $h = 0; }
+ $this->tMargin = $this->margin_header + $h + $this->orig_tMargin;
+ }
+ else if ($this->setAutoTopMargin=='stretch') {
+ if (isset($htmlh['h']) && $htmlh['h']) { $h = $htmlh['h']; } // 5.7.3
+ else { $h = 0; }
+ $this->tMargin = max($this->orig_tMargin, $this->margin_header + $h + $this->autoMarginPadding);
+ }
+}
+
+
+// mPDF 6
+function _setAutoFooterHeight(&$htmlf) {
+ if ($this->setAutoBottomMargin=='pad') {
+ if (isset($htmlf['h']) && $htmlf['h']) { $h = $htmlf['h']; } // 5.7.3
+ else { $h = 0; }
+ $this->bMargin = $this->margin_footer + $h + $this->orig_bMargin;
+ $this->PageBreakTrigger=$this->h-$this->bMargin ;
+ }
+ else if ($this->setAutoBottomMargin=='stretch') {
+ if (isset($htmlf['h']) && $htmlf['h']) { $h = $htmlf['h']; } // 5.7.3
+ else { $h = 0; }
+ $this->bMargin = max($this->orig_bMargin, $this->margin_footer + $h + $this->autoMarginPadding);
+ $this->PageBreakTrigger=$this->h-$this->bMargin ;
+ }
+}
+
+
+function _endpage() {
+/*-- CSS-IMAGE-FLOAT --*/
+ $this->printfloatbuffer();
+/*-- END CSS-IMAGE-FLOAT --*/
+
+ if($this->visibility!='visible')
+ $this->SetVisibility('visible');
+ $this->EndLayer();
+ //End of page contents
+ $this->state=1;
+}
+
+function _newobj($obj_id=false,$onlynewobj=false) {
+ if (!$obj_id) {
+ $obj_id = ++$this->n;
+ }
+ //Begin a new object
+ if (!$onlynewobj) {
+ $this->offsets[$obj_id] = strlen($this->buffer);
+ $this->_out($obj_id.' 0 obj');
+ $this->_current_obj_id = $obj_id; // for later use with encryption
+ }
+}
+
+function _dounderline($x,$y,$txt,$OTLdata=false,$textvar=0) {
+ // Now print line exactly where $y secifies - called from Text() and Cell() - adjust position there
+ // WORD SPACING
+ $w =($this->GetStringWidth($txt,false,$OTLdata,$textvar)*_MPDFK) + ($this->charspacing * mb_strlen( $txt, $this->mb_enc ))
+ + ( $this->ws * mb_substr_count( $txt, ' ', $this->mb_enc ));
+ //Draw a line
+ return sprintf('%.3F %.3F m %.3F %.3F l S',$x*_MPDFK,($this->h-$y)*_MPDFK,($x*_MPDFK)+$w,($this->h-$y)*_MPDFK);
+}
+
+
+function _imageError($file, $firsttime, $msg) {
+ // Save re-trying image URL's which have already failed
+ $this->failedimages[$file] = true;
+ if ($firsttime && ($this->showImageErrors || $this->debug)) {
+ $this->Error("IMAGE Error (".$file."): ".$msg);
+ }
+ return false;
+}
+
+
+function _getImage(&$file, $firsttime=true, $allowvector=true, $orig_srcpath=false, $interpolation=false) { // mPDF 6
+ // firsttime i.e. whether to add to this->images - use false when calling iteratively
+ // Image Data passed directly as var:varname
+ if (preg_match('/var:\s*(.*)/',$file, $v)) {
+ $data = $this->$v[1];
+ $file = md5($data);
+ }
+ if (preg_match('/data:image\/(gif|jpeg|png);base64,(.*)/',$file, $v)) {
+ $type = $v[1];
+ $data = base64_decode($v[2]);
+ $file = md5($data);
+ }
+
+ // mPDF 5.7.4 URLs
+ if ($firsttime && $file && substr($file,0,5)!='data:') { $file = str_replace(" ","%20",$file ); }
+ if ($firsttime && $orig_srcpath) {
+ // If orig_srcpath is a relative file path (and not a URL), then it needs to be URL decoded
+ if (substr($orig_srcpath,0,5)!='data:') { $orig_srcpath = str_replace(" ","%20",$orig_srcpath); }
+ if (!preg_match('/^(http|ftp)/',$orig_srcpath)) { $orig_srcpath = urldecode_parts($orig_srcpath ); }
+ }
+
+ $ppUx = 0;
+ if ($orig_srcpath && isset($this->images[$orig_srcpath])) { $file=$orig_srcpath; return $this->images[$orig_srcpath]; }
+ if (isset($this->images[$file])) { return $this->images[$file]; }
+ else if ($orig_srcpath && isset($this->formobjects[$orig_srcpath])) { $file=$orig_srcpath; return $this->formobjects[$file]; }
+ else if (isset($this->formobjects[$file])) { return $this->formobjects[$file]; }
+ // Save re-trying image URL's which have already failed
+ else if ($firsttime && isset($this->failedimages[$file])) { return $this->_imageError($file, $firsttime, ''); }
+ if (empty($data)) {
+ $type = '';
+ $data = '';
+
+ if ($orig_srcpath && $this->basepathIsLocal && $check = @fopen($orig_srcpath,"rb")) {
+ fclose($check);
+ $file=$orig_srcpath;
+ $data = file_get_contents($file);
+ $type = $this->_imageTypeFromString($data);
+ }
+ if (!$data && $check = @fopen($file,"rb")) {
+ fclose($check);
+ $data = file_get_contents($file);
+ $type = $this->_imageTypeFromString($data);
+ }
+ if ((!$data || !$type) && !ini_get('allow_url_fopen') ) { // only worth trying if remote file and !ini_get('allow_url_fopen')
+ $this->file_get_contents_by_socket($file, $data); // needs full url?? even on local (never needed for local)
+ if ($data) { $type = $this->_imageTypeFromString($data); }
+ }
+ if ((!$data || !$type) && function_exists("curl_init")) { // mPDF 5.7.4
+ $this->file_get_contents_by_curl($file, $data); // needs full url?? even on local (never needed for local)
+ if ($data) { $type = $this->_imageTypeFromString($data); }
+ }
+
+ }
+ if (!$data) { return $this->_imageError($file, $firsttime, 'Could not find image file'); }
+ if (empty($type)) { $type = $this->_imageTypeFromString($data); }
+ if (($type == 'wmf' || $type == 'svg') && !$allowvector) { return $this->_imageError($file, $firsttime, 'WMF or SVG image file not supported in this context'); }
+
+ // SVG
+ if ($type == 'svg') {
+ if (!class_exists('SVG', false)) { include(_MPDF_PATH .'classes/svg.php'); }
+ $svg = new SVG($this);
+ $family=$this->FontFamily;
+ $style=$this->FontStyle;
+ $size=$this->FontSizePt;
+ $info = $svg->ImageSVG($data);
+ //Restore font
+ if($family) $this->SetFont($family,$style,$size,false);
+ if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing SVG file'); }
+ $info['type']='svg';
+ $info['i']=count($this->formobjects)+1;
+ $this->formobjects[$file]=$info;
+ return $info;
+ }
+
+ // JPEG
+ if ($type == 'jpeg' || $type == 'jpg') {
+ $hdr = $this->_jpgHeaderFromString($data);
+ if (!$hdr) { return $this->_imageError($file, $firsttime, 'Error parsing JPG header'); }
+ $a = $this->_jpgDataFromHeader($hdr);
+ $channels = intval($a[4]);
+ $j = strpos($data,'JFIF');
+ if ($j) {
+ //Read resolution
+ $unitSp=ord(substr($data,($j+7),1));
+ if ($unitSp > 0) {
+ $ppUx=$this->_twobytes2int(substr($data,($j+8),2)); // horizontal pixels per meter, usually set to zero
+ if ($unitSp == 2) { // = dots per cm (if == 1 set as dpi)
+ $ppUx=round($ppUx/10 *25.4);
+ }
+ }
+ }
+ if ($a[2] == 'DeviceCMYK' && (($this->PDFA && $this->restrictColorSpace!=3) || $this->restrictColorSpace==2)) {
+ // convert to RGB image
+ if (!function_exists("gd_info")) { $this->Error("JPG image may not use CMYK color space (".$file.")."); }
+ if ($this->PDFA && !$this->PDFAauto) { $this->PDFAXwarnings[] = "JPG image may not use CMYK color space - ".$file." - (Image converted to RGB. NB This will alter the colour profile of the image.)"; }
+ $im = @imagecreatefromstring($data);
+ if ($im) {
+ $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.md5($file).RAND(1,10000).'.png';
+ imageinterlace($im, false);
+ $check = @imagepng($im, $tempfile);
+ if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary file ('.$tempfile.') whilst using GD library to parse JPG(CMYK) image'); }
+ $info = $this->_getImage($tempfile, false);
+ if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse JPG(CMYK) image'); }
+ imagedestroy($im);
+ unlink($tempfile);
+ $info['type']='jpg';
+ if ($firsttime) {
+ $info['i']=count($this->images)+1;
+ $info['interpolation']=$interpolation; // mPDF 6
+ $this->images[$file]=$info;
+ }
+ return $info;
+ }
+ else { return $this->_imageError($file, $firsttime, 'Error creating GD image file from JPG(CMYK) image'); }
+ }
+ else if ($a[2] == 'DeviceRGB' && ($this->PDFX || $this->restrictColorSpace==3)) {
+ // Convert to CMYK image stream - nominally returned as type='png'
+ $info = $this->_convImage($data, $a[2], 'DeviceCMYK', $a[0], $a[1], $ppUx, false);
+ if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "JPG image may not use RGB color space - ".$file." - (Image converted to CMYK. NB This will alter the colour profile of the image.)"; }
+ }
+ else if (($a[2] == 'DeviceRGB' || $a[2] == 'DeviceCMYK') && $this->restrictColorSpace==1) {
+ // Convert to Grayscale image stream - nominally returned as type='png'
+ $info = $this->_convImage($data, $a[2], 'DeviceGray', $a[0], $a[1], $ppUx, false);
+ }
+ else {
+
+ // mPDF 6 Detect Adobe APP14 Tag
+ //$pos = strpos($data, "\xFF\xEE\x00\x0EAdobe\0");
+ //if ($pos !== false) {
+ //}
+
+ // mPDF 6 ICC profile
+ $offset = 0;
+ $icc = array();
+ while (($pos = strpos($data, "ICC_PROFILE\0", $offset)) !== false) {
+ // get ICC sequence length
+ $length = $this->_twobytes2int(substr($data, ($pos - 2),2)) - 16;
+ $sn = max(1, ord($data[($pos + 12)]));
+ $nom = max(1, ord($data[($pos + 13)]));
+ $icc[($sn - 1)] = substr($data, ($pos + 14), $length);
+ $offset = ($pos + 14 + $length);
+ }
+ // order and compact ICC segments
+ if (count($icc) > 0) {
+ ksort($icc);
+ $icc = implode('', $icc);
+ if (substr($icc, 36, 4) != 'acsp') {
+ // invalid ICC profile
+ $icc = false;
+ }
+ $input = substr($icc, 16, 4);
+ $output = substr($icc, 20, 4);
+ // Ignore Color profiles for conversion to other colorspaces e.g. CMYK/Lab
+ if ($input != 'RGB ' || $output != 'XYZ ') { $icc = false; }
+ }
+ else { $icc = false; }
+
+ $info = array('w'=>$a[0],'h'=>$a[1],'cs'=>$a[2],'bpc'=>$a[3],'f'=>'DCTDecode','data'=>$data, 'type'=>'jpg', 'ch' => $channels, 'icc' => $icc);
+ if ($ppUx) { $info['set-dpi'] = $ppUx; }
+ }
+ if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing or converting JPG image'); }
+ if ($firsttime) {
+ $info['i']=count($this->images)+1;
+ $info['interpolation']=$interpolation; // mPDF 6
+ $this->images[$file]=$info;
+ }
+ return $info;
+ }
+
+ // PNG
+ else if ($type == 'png') {
+ //Check signature
+ if(substr($data,0,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
+ return $this->_imageError($file, $firsttime, 'Error parsing PNG identifier');
+ }
+ //Read header chunk
+ if(substr($data,12,4)!='IHDR') {
+ return $this->_imageError($file, $firsttime, 'Incorrect PNG file (no IHDR block found)');
+ }
+
+ $w=$this->_fourbytes2int(substr($data,16,4));
+ $h=$this->_fourbytes2int(substr($data,20,4));
+ $bpc=ord(substr($data,24,1));
+ $errpng = false;
+ $pngalpha = false;
+ $channels = 0;
+
+ // if($bpc>8) { $errpng = 'not 8-bit depth'; } // mPDF 6 Allow through to be handled as native PNG
+
+ $ct=ord(substr($data,25,1));
+ if($ct==0) { $colspace='DeviceGray'; $channels = 1; }
+ elseif($ct==2) { $colspace='DeviceRGB'; $channels = 3; }
+ elseif($ct==3) { $colspace='Indexed'; $channels = 1; }
+ elseif($ct==4) { $colspace='DeviceGray'; $channels = 1; $errpng = 'alpha channel'; $pngalpha = true; }
+ else { $colspace='DeviceRGB'; $channels = 3; $errpng = 'alpha channel'; $pngalpha = true; }
+
+ if ($ct < 4 && strpos($data,'tRNS')!==false) { $errpng = 'transparency'; $pngalpha = true; } // mPDF 6
+
+ if ($ct == 3 && strpos($data,'iCCP')!==false) { $errpng = 'indexed plus ICC'; } // mPDF 6
+
+ // $pngalpha is used as a FLAG of any kind of transparency which COULD be tranferred to an alpha channel
+ // incl. single-color tarnsparency, depending which type of handling occurs later
+
+ if(ord(substr($data,26,1))!=0) { $errpng = 'compression method'; } // only 0 should be specified
+ if(ord(substr($data,27,1))!=0) { $errpng = 'filter method'; } // only 0 should be specified
+ if(ord(substr($data,28,1))!=0) { $errpng = 'interlaced file'; }
+
+ $j = strpos($data,'pHYs');
+ if ($j) {
+ //Read resolution
+ $unitSp=ord(substr($data,($j+12),1));
+ if ($unitSp == 1) {
+ $ppUx=$this->_fourbytes2int(substr($data,($j+4),4)); // horizontal pixels per meter, usually set to zero
+ $ppUx=round($ppUx/1000 *25.4);
+ }
+ }
+
+ // mPDF 6 Gamma correction
+ $gamma_correction = 0;
+ $gAMA = 0;
+ $j = strpos($data,'gAMA');
+ if ($j && strpos($data,'sRGB')===false) { // sRGB colorspace - overrides gAMA
+ $gAMA=$this->_fourbytes2int(substr($data,($j+4),4)); // Gamma value times 100000
+ $gAMA /= 100000;
+
+ // http://www.libpng.org/pub/png/spec/1.2/PNG-Encoders.html
+ // "If the source file's gamma value is greater than 1.0, it is probably a display system exponent,..."
+ // ("..and you should use its reciprocal for the PNG gamma.")
+ //if ($gAMA > 1) { $gAMA = 1/$gAMA; }
+ // (Some) Applications seem to ignore it... appearing how it was probably intended
+ // Test Case - image(s) on http://www.w3.org/TR/CSS21/intro.html - PNG has gAMA set as 1.45454
+ // Probably unintentional as mentioned above and should be 0.45454 which is 1 / 2.2
+ // Tested on Windows PC
+ // Firefox and Opera display gray as 234 (correct, but looks wrong)
+ // IE9 and Safari display gray as 193 (incorrect but looks right)
+ // See test different gamma chunks at http://www.libpng.org/pub/png/pngsuite-all-good.html
+ }
+
+ if ($gAMA) { $gamma_correction = 1/$gAMA; }
+
+ // Don't need to apply gamma correction if == default i.e. 2.2
+ if ($gamma_correction > 2.15 && $gamma_correction < 2.25) { $gamma_correction = 0; }
+
+ // NOT supported at present
+ //$j = strpos($data,'sRGB'); // sRGB colorspace - overrides gAMA
+ //$j = strpos($data,'cHRM'); // Chromaticity and Whitepoint
+
+ // $firsttime added mPDF 6 so when PNG Grayscale with alpha using resrtictcolorspace to CMYK
+ // the alpha channel is sent through as secondtime as Indexed and should not be converted to CMYK
+ if ($firsttime && ($colspace == 'DeviceRGB' || $colspace == 'Indexed') && ($this->PDFX || $this->restrictColorSpace==3)) {
+ // Convert to CMYK image stream - nominally returned as type='png'
+ $info = $this->_convImage($data, $colspace, 'DeviceCMYK', $w, $h, $ppUx, $pngalpha, $gamma_correction, $ct); // mPDF 5.7.2 Gamma correction
+ if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "PNG image may not use RGB color space - ".$file." - (Image converted to CMYK. NB This will alter the colour profile of the image.)"; }
+ }
+ // $firsttime added mPDF 6 so when PNG Grayscale with alpha using resrtictcolorspace to CMYK
+ // the alpha channel is sent through as secondtime as Indexed and should not be converted to CMYK
+ else if ($firsttime && ($colspace == 'DeviceRGB' || $colspace == 'Indexed') && $this->restrictColorSpace==1) {
+ // Convert to Grayscale image stream - nominally returned as type='png'
+ $info = $this->_convImage($data, $colspace, 'DeviceGray', $w, $h, $ppUx, $pngalpha, $gamma_correction, $ct); // mPDF 5.7.2 Gamma correction
+ }
+ else if (($this->PDFA || $this->PDFX) && $pngalpha) {
+
+ // Remove alpha channel
+ if ($this->restrictColorSpace==1) { // Grayscale
+ $info = $this->_convImage($data, $colspace, 'DeviceGray', $w, $h, $ppUx, $pngalpha, $gamma_correction, $ct); // mPDF 5.7.2 Gamma correction
+ }
+ else if ($this->restrictColorSpace==3) { // CMYK
+ $info = $this->_convImage($data, $colspace, 'DeviceCMYK', $w, $h, $ppUx, $pngalpha, $gamma_correction, $ct); // mPDF 5.7.2 Gamma correction
+ }
+ else if ($this->PDFA ) { // RGB
+ $info = $this->_convImage($data, $colspace, 'DeviceRGB', $w, $h, $ppUx, $pngalpha, $gamma_correction, $ct); // mPDF 5.7.2 Gamma correction
+ }
+ if (($this->PDFA && !$this->PDFAauto) || ($this->PDFX && !$this->PDFXauto)) { $this->PDFAXwarnings[] = "Transparency (alpha channel) not permitted in PDFA or PDFX files - ".$file." - (Image converted to one without transparency.)"; }
+ }
+ else if ($firsttime && ($errpng || $pngalpha || $gamma_correction)) { // mPDF 5.7.2 Gamma correction
+ if (function_exists('gd_info')) { $gd = gd_info(); }
+ else {$gd = array(); }
+ if (!isset($gd['PNG Support'])) { return $this->_imageError($file, $firsttime, 'GD library required for PNG image ('.$errpng.')'); }
+ $im = imagecreatefromstring($data);
+
+ if (!$im) { return $this->_imageError($file, $firsttime, 'Error creating GD image from PNG file ('.$errpng.')'); }
+ $w = imagesx($im);
+ $h = imagesy($im);
+ if ($im) {
+ $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.md5($file).RAND(1,10000).'.png';
+
+ // Alpha channel set (including using tRNS for Paletted images)
+ if ($pngalpha) {
+ if ($this->PDFA) { $this->Error("PDFA1-b does not permit images with alpha channel transparency (".$file.")."); }
+
+ $imgalpha = imagecreate($w, $h);
+ // generate gray scale pallete
+ for ($c = 0; $c < 256; ++$c) { imagecolorallocate($imgalpha, $c, $c, $c); }
+
+ // mPDF 6
+ if ($colspace=='Indexed') { // generate Alpha channel values from tRNS
+ //Read transparency info
+ $transparency = '';
+ $p = strpos($data,'tRNS');
+ if ($p) {
+ $n=$this->_fourbytes2int(substr($data,($p-4),4));
+ $transparency = substr($data,($p+4),$n);
+ // ord($transparency{$index}) = the alpha value for that index
+ // generate alpha channel
+ for ($ypx = 0; $ypx < $h; ++$ypx) {
+ for ($xpx = 0; $xpx < $w; ++$xpx) {
+ $colorindex = imagecolorat($im, $xpx, $ypx);
+ if ($colorindex >= $n) { $alpha = 255; }
+ else { $alpha = ord($transparency{$colorindex}); } // 0-255
+ if ($alpha > 0) {
+ imagesetpixel($imgalpha, $xpx, $ypx, $alpha);
+ }
+ }
+ }
+ }
+ }
+ else if ($ct===0 || $ct==2) { // generate Alpha channel values from tRNS
+ // Get transparency as array of RGB
+ $p = strpos($data,'tRNS');
+ if ($p) {
+ $trns = '';
+ $n=$this->_fourbytes2int(substr($data,($p-4),4));
+ $t = substr($data,($p+4),$n);
+ if ($colspace=='DeviceGray') { // ct===0
+ $trns=array($this->_trnsvalue(substr($t,0,2), $bpc));
+ }
+ else /* $colspace=='DeviceRGB' */ { // ct==2
+ $trns=array();
+ $trns[0]=$this->_trnsvalue(substr($t,0,2), $bpc);
+ $trns[1]=$this->_trnsvalue(substr($t,2,2), $bpc);
+ $trns[2]=$this->_trnsvalue(substr($t,4,2), $bpc);
+ }
+
+ // generate alpha channel
+ for ($ypx = 0; $ypx < $h; ++$ypx) {
+ for ($xpx = 0; $xpx < $w; ++$xpx) {
+ $rgb = imagecolorat($im, $xpx, $ypx);
+ $r = ($rgb >> 16) & 0xFF;
+ $g = ($rgb >> 8) & 0xFF;
+ $b = $rgb & 0xFF;
+ if ($colspace=='DeviceGray' && $b==$trns[0]) { $alpha = 0; }
+ else if ($r==$trns[0] && $g==$trns[1] && $b==$trns[2]) { $alpha = 0; } // ct==2
+ else { $alpha = 255; }
+ if ($alpha > 0) {
+ imagesetpixel($imgalpha, $xpx, $ypx, $alpha);
+ }
+ }
+ }
+ }
+ }
+ else {
+ // extract alpha channel
+ for ($ypx = 0; $ypx < $h; ++$ypx) {
+ for ($xpx = 0; $xpx < $w; ++$xpx) {
+ $alpha = (imagecolorat($im, $xpx, $ypx) & 0x7F000000) >> 24;
+ if ($alpha < 127) {
+ imagesetpixel($imgalpha, $xpx, $ypx, (255-($alpha * 2)));
+ }
+ }
+ }
+ }
+
+
+ // NB This must happen after the Alpha channel is extracted
+ // imagegammacorrect() removes the alpha channel data in $im - (I think this is a bug in PHP)
+ if ($gamma_correction) { imagegammacorrect($im, $gamma_correction, 2.2); } // mPDF 6 Gamma correction
+
+ // create temp alpha file
+ $tempfile_alpha = _MPDF_TEMP_PATH.'_tempMskPNG'.md5($file).RAND(1,10000).'.png';
+ if (!is_writable(_MPDF_TEMP_PATH)) { // mPDF 5.7.2
+ ob_start();
+ $check = @imagepng($imgalpha);
+ if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse PNG image'); }
+ imagedestroy($imgalpha);
+ $this->_tempimg = ob_get_contents();
+ $this->_tempimglnk = 'var:_tempimg';
+ ob_end_clean();
+ // extract image without alpha channel
+ $imgplain = imagecreatetruecolor($w, $h);
+ imagealphablending( $imgplain, false ); // mPDF 5.7.2
+ imagecopy($imgplain, $im, 0, 0, 0, 0, $w, $h);
+ // create temp image file
+ $minfo = $this->_getImage($this->_tempimglnk, false);
+ if (!$minfo) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse PNG image'); }
+ ob_start();
+ $check = @imagepng($imgplain);
+ if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse PNG image'); }
+ $this->_tempimg = ob_get_contents();
+ $this->_tempimglnk = 'var:_tempimg';
+ ob_end_clean();
+ $info = $this->_getImage($this->_tempimglnk, false);
+ if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse PNG image'); }
+ imagedestroy($imgplain);
+ $imgmask = count($this->images)+1;
+ $minfo['cs'] = 'DeviceGray';
+ $minfo['i']=$imgmask ;
+ $this->images[$tempfile_alpha] = $minfo;
+ }
+ else {
+ $check = @imagepng($imgalpha, $tempfile_alpha);
+ if (!$check) { return $this->_imageError($file, $firsttime, 'Failed to create temporary image file ('.$tempfile_alpha.') parsing PNG image with alpha channel ('.$errpng.')'); }
+ imagedestroy($imgalpha);
+ // extract image without alpha channel
+ $imgplain = imagecreatetruecolor($w, $h);
+ imagealphablending( $imgplain, false ); // mPDF 5.7.2
+ imagecopy($imgplain, $im, 0, 0, 0, 0, $w, $h);
+
+ // create temp image file
+ $check = @imagepng($imgplain, $tempfile);
+ if (!$check) { return $this->_imageError($file, $firsttime, 'Failed to create temporary image file ('.$tempfile.') parsing PNG image with alpha channel ('.$errpng.')'); }
+ imagedestroy($imgplain);
+ // embed mask image
+ $minfo = $this->_getImage($tempfile_alpha, false);
+ unlink($tempfile_alpha);
+ if (!$minfo) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile_alpha.') created with GD library to parse PNG image'); }
+ $imgmask = count($this->images)+1;
+ $minfo['cs'] = 'DeviceGray';
+ $minfo['i']=$imgmask ;
+ $this->images[$tempfile_alpha] = $minfo;
+ // embed image, masked with previously embedded mask
+ $info = $this->_getImage($tempfile, false);
+ unlink($tempfile);
+ if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse PNG image'); }
+
+ }
+ $info['masked'] = $imgmask;
+ if ($ppUx) { $info['set-dpi'] = $ppUx; }
+ $info['type']='png';
+ if ($firsttime) {
+ $info['i']=count($this->images)+1;
+ $info['interpolation']=$interpolation; // mPDF 6
+ $this->images[$file]=$info;
+ }
+
+ return $info;
+ }
+ else { // No alpha/transparency set (but cannot read directly because e.g. bit-depth != 8, interlaced etc)
+
+ // ICC profile
+ $icc = false;
+ $p = strpos($data,'iCCP');
+ if ($p && $colspace=="Indexed") { // Cannot have ICC profile and Indexed together
+ $p += 4;
+ $n=$this->_fourbytes2int(substr($data,($p-8),4));
+ $nullsep = strpos(substr($data,$p,80), chr(0));
+ $icc = substr($data, ($p+$nullsep+2), ($n-($nullsep+2)) );
+ $icc = @gzuncompress($icc); // Ignored if fails
+ if ($icc) {
+ if (substr($icc, 36, 4) != 'acsp') { $icc = false; } // invalid ICC profile
+ else {
+ $input = substr($icc, 16, 4);
+ $output = substr($icc, 20, 4);
+ // Ignore Color profiles for conversion to other colorspaces e.g. CMYK/Lab
+ if ($input != 'RGB ' || $output != 'XYZ ') { $icc = false; }
+ }
+ }
+ // Convert to RGB colorspace so can use ICC Profile
+ if ($icc) { imagepalettetotruecolor($im); $colspace = 'DeviceRGB'; $channels = 3;}
+ }
+
+ if ($gamma_correction) { imagegammacorrect($im, $gamma_correction, 2.2); } // mPDF 6 Gamma correction
+ imagealphablending($im, false);
+ imagesavealpha($im, false);
+ imageinterlace($im, false);
+ if (!is_writable(_MPDF_TEMP_PATH)) { // mPDF 5.7.2
+ ob_start();
+ $check = @imagepng($im);
+ if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse PNG image'); }
+ $this->_tempimg = ob_get_contents();
+ $this->_tempimglnk = 'var:_tempimg';
+ ob_end_clean();
+ $info = $this->_getImage($this->_tempimglnk, false);
+ if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse PNG image'); }
+ imagedestroy($im);
+ }
+ else {
+ $check = @imagepng($im, $tempfile );
+ if (!$check) { return $this->_imageError($file, $firsttime, 'Failed to create temporary image file ('.$tempfile.') parsing PNG image ('.$errpng.')'); }
+ imagedestroy($im);
+ $info = $this->_getImage($tempfile, false) ;
+ unlink($tempfile );
+ if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse PNG image'); }
+ }
+ if ($ppUx) { $info['set-dpi'] = $ppUx; }
+ $info['type']='png';
+ if ($firsttime) {
+ $info['i']=count($this->images)+1;
+ $info['interpolation']=$interpolation; // mPDF 6
+ if ($icc) { $info['ch'] = $channels; $info['icc'] = $icc; }
+ $this->images[$file]=$info;
+ }
+ return $info;
+ }
+ }
+ }
+
+ else { // PNG image with no need to convert alph channels, bpc <> 8 etc.
+ $parms='/DecodeParms <>';
+ //Scan chunks looking for palette, transparency and image data
+ $pal='';
+ $trns='';
+ $pngdata='';
+ $icc = false;
+ $p = 33;
+ do {
+ $n=$this->_fourbytes2int(substr($data,$p,4)); $p += 4;
+ $type=substr($data,$p,4); $p += 4;
+ if ($type=='PLTE') {
+ //Read palette
+ $pal=substr($data,$p,$n); $p += $n;
+ $p += 4;
+ }
+ else if($type=='tRNS') {
+ //Read transparency info
+ $t=substr($data,$p,$n); $p += $n;
+ if ($ct==0) $trns=array(ord(substr($t,1,1)));
+ else if ($ct==2) $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
+ else {
+ $pos=strpos($t,chr(0));
+ if(is_int($pos)) $trns=array($pos);
+ }
+ $p += 4;
+ }
+ else if ($type=='IDAT') {
+ $pngdata.=substr($data,$p,$n); $p += $n;
+ $p += 4;
+ }
+ else if ($type=='iCCP') {
+ $nullsep = strpos(substr($data,$p,80), chr(0));
+ $icc = substr($data, ($p+$nullsep+2), ($n-($nullsep+2)) );
+ $icc = @gzuncompress($icc); // Ignored if fails
+ if ($icc) {
+ if (substr($icc, 36, 4) != 'acsp') { $icc = false; } // invalid ICC profile
+ else {
+ $input = substr($icc, 16, 4);
+ $output = substr($icc, 20, 4);
+ // Ignore Color profiles for conversion to other colorspaces e.g. CMYK/Lab
+ if ($input != 'RGB ' || $output != 'XYZ ') { $icc = false; }
+ }
+ }
+ $p += $n;
+ $p += 4;
+ }
+ else if($type=='IEND') { break; }
+ else if (preg_match('/[a-zA-Z]{4}/',$type)) { $p += $n+4; }
+ else { return $this->_imageError($file, $firsttime, 'Error parsing PNG image data'); }
+ }
+ while($n);
+ if (!$pngdata) { return $this->_imageError($file, $firsttime, 'Error parsing PNG image data - no IDAT data found'); }
+ if ($colspace=='Indexed' && empty($pal)) { return $this->_imageError($file, $firsttime, 'Error parsing PNG image data - missing colour palette'); }
+
+ if ($colspace=='Indexed' && $icc) { $icc = false; } // mPDF 6 cannot have ICC profile and Indexed in a PDF document as both use the colorspace tag.
+
+ $info = array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$pngdata, 'ch' => $channels, 'icc' => $icc);
+ $info['type']='png';
+ if ($ppUx) { $info['set-dpi'] = $ppUx; }
+ }
+
+ if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing or converting PNG image'); }
+
+ if ($firsttime) {
+ $info['i']=count($this->images)+1;
+ $info['interpolation']=$interpolation; // mPDF 6
+ $this->images[$file]=$info;
+ }
+ return $info;
+ }
+
+ // GIF
+ else if ($type == 'gif') {
+ if (function_exists('gd_info')) { $gd = gd_info(); }
+ else {$gd = array(); }
+ if (isset($gd['GIF Read Support']) && $gd['GIF Read Support']) {
+ $im = @imagecreatefromstring($data);
+ if ($im) {
+ $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.md5($file).RAND(1,10000).'.png';
+ imagealphablending($im, false);
+ imagesavealpha($im, false);
+ imageinterlace($im, false);
+ if (!is_writable($tempfile)) {
+ ob_start();
+ $check = @imagepng($im);
+ if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary image object whilst using GD library to parse GIF image'); }
+ $this->_tempimg = ob_get_contents();
+ $this->_tempimglnk = 'var:_tempimg';
+ ob_end_clean();
+ $info = $this->_getImage($this->_tempimglnk, false);
+ if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file image object created with GD library to parse GIF image'); }
+ imagedestroy($im);
+ }
+ else {
+ $check = @imagepng($im, $tempfile);
+ if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary file ('.$tempfile.') whilst using GD library to parse GIF image'); }
+ $info = $this->_getImage($tempfile, false);
+ if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse GIF image'); }
+ imagedestroy($im);
+ unlink($tempfile);
+ }
+ $info['type']='gif';
+ if ($firsttime) {
+ $info['i']=count($this->images)+1;
+ $info['interpolation']=$interpolation; // mPDF 6
+ $this->images[$file]=$info;
+ }
+ return $info;
+ }
+ else { return $this->_imageError($file, $firsttime, 'Error creating GD image file from GIF image'); }
+ }
+
+ if (!class_exists('gif', false)) {
+ include_once(_MPDF_PATH.'classes/gif.php');
+ }
+ $gif=new CGIF();
+
+ $h=0;
+ $w=0;
+ $gif->loadFile($data, 0);
+
+ if(isset($gif->m_img->m_gih->m_bLocalClr) && $gif->m_img->m_gih->m_bLocalClr) {
+ $nColors = $gif->m_img->m_gih->m_nTableSize;
+ $pal = $gif->m_img->m_gih->m_colorTable->toString();
+ if((isset($bgColor)) and $bgColor != -1) { // mPDF 5.7.3
+ $bgColor = $gif->m_img->m_gih->m_colorTable->colorIndex($bgColor);
+ }
+ $colspace='Indexed';
+ } elseif(isset($gif->m_gfh->m_bGlobalClr) && $gif->m_gfh->m_bGlobalClr) {
+ $nColors = $gif->m_gfh->m_nTableSize;
+ $pal = $gif->m_gfh->m_colorTable->toString();
+ if((isset($bgColor)) and $bgColor != -1) {
+ $bgColor = $gif->m_gfh->m_colorTable->colorIndex($bgColor);
+ }
+ $colspace='Indexed';
+ } else {
+ $nColors = 0;
+ $bgColor = -1;
+ $colspace='DeviceGray';
+ $pal='';
+ }
+
+ $trns='';
+ if(isset($gif->m_img->m_bTrans) && $gif->m_img->m_bTrans && ($nColors > 0)) {
+ $trns=array($gif->m_img->m_nTrans);
+ }
+ $gifdata=$gif->m_img->m_data;
+ $w=$gif->m_gfh->m_nWidth;
+ $h=$gif->m_gfh->m_nHeight;
+ $gif->ClearData();
+
+ if($colspace=='Indexed' and empty($pal)) {
+ return $this->_imageError($file, $firsttime, 'Error parsing GIF image - missing colour palette');
+ }
+ if ($this->compress) {
+ $gifdata=gzcompress($gifdata);
+ $info = array( 'w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>8, 'f'=>'FlateDecode', 'pal'=>$pal, 'trns'=>$trns, 'data'=>$gifdata);
+ }
+ else {
+ $info = array( 'w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>8, 'pal'=>$pal, 'trns'=>$trns, 'data'=>$gifdata);
+ }
+ $info['type']='gif';
+ if ($firsttime) {
+ $info['i']=count($this->images)+1;
+ $info['interpolation']=$interpolation; // mPDF 6
+ $this->images[$file]=$info;
+ }
+ return $info;
+ }
+
+/*-- IMAGES-BMP --*/
+ // BMP (Windows Bitmap)
+ else if ($type == 'bmp') {
+ if (!class_exists('bmp', false)) { include(_MPDF_PATH.'classes/bmp.php'); }
+ if (empty($this->bmp)) { $this->bmp = new bmp($this); }
+ $info = $this->bmp->_getBMPimage($data, $file);
+ if (isset($info['error'])) {
+ return $this->_imageError($file, $firsttime, $info['error']);
+ }
+ if ($firsttime) {
+ $info['i']=count($this->images)+1;
+ $info['interpolation']=$interpolation; // mPDF 6
+ $this->images[$file]=$info;
+ }
+ return $info;
+ }
+/*-- END IMAGES-BMP --*/
+/*-- IMAGES-WMF --*/
+ // WMF
+ else if ($type == 'wmf') {
+ if (!class_exists('wmf', false)) { include(_MPDF_PATH.'classes/wmf.php'); }
+ if (empty($this->wmf)) { $this->wmf = new wmf($this); }
+ $wmfres = $this->wmf->_getWMFimage($data);
+ if ($wmfres[0]==0) {
+ if ($wmfres[1]) { return $this->_imageError($file, $firsttime, $wmfres[1]); }
+ return $this->_imageError($file, $firsttime, 'Error parsing WMF image');
+ }
+ $info = array('x'=>$wmfres[2][0],'y'=>$wmfres[2][1],'w'=>$wmfres[3][0],'h'=>$wmfres[3][1],'data'=>$wmfres[1]);
+ $info['i']=count($this->formobjects)+1;
+ $info['type']='wmf';
+ $this->formobjects[$file]=$info;
+ return $info;
+ }
+/*-- END IMAGES-WMF --*/
+
+ // UNKNOWN TYPE - try GD imagecreatefromstring
+ else {
+ if (function_exists('gd_info')) { $gd = gd_info(); }
+ else {$gd = array(); }
+ if (isset($gd['PNG Support']) && $gd['PNG Support']) {
+ $im = @imagecreatefromstring($data);
+ if (!$im) { return $this->_imageError($file, $firsttime, 'Error parsing image file - image type not recognised, and not supported by GD imagecreate'); }
+ $tempfile = _MPDF_TEMP_PATH.'_tempImgPNG'.md5($file).RAND(1,10000).'.png';
+ imagealphablending($im, false);
+ imagesavealpha($im, false);
+ imageinterlace($im, false);
+ $check = @imagepng($im, $tempfile);
+ if (!$check) { return $this->_imageError($file, $firsttime, 'Error creating temporary file ('.$tempfile.') whilst using GD library to parse unknown image type'); }
+ $info = $this->_getImage($tempfile, false);
+ imagedestroy($im);
+ unlink($tempfile);
+ if (!$info) { return $this->_imageError($file, $firsttime, 'Error parsing temporary file ('.$tempfile.') created with GD library to parse unknown image type'); }
+ $info['type']='png';
+ if ($firsttime) {
+ $info['i']=count($this->images)+1;
+ $info['interpolation']=$interpolation; // mPDF 6
+ $this->images[$file]=$info;
+ }
+ return $info;
+ }
+ }
+
+ return $this->_imageError($file, $firsttime, 'Error parsing image file - image type not recognised');
+}
+//==============================================================
+function _convImage(&$data, $colspace, $targetcs, $w, $h, $dpi, $mask, $gamma_correction=false, $pngcolortype=false) { // mPDF 5.7.2 Gamma correction
+ if ($this->PDFA || $this->PDFX) { $mask=false; }
+ $im = @imagecreatefromstring($data);
+ $info = array();
+ $bpc=ord(substr($data,24,1));
+ if ($im) {
+
+ $imgdata = '';
+ $mimgdata = '';
+ $minfo = array();
+
+ // mPDF 6 Gamma correction
+ // Need to extract alpha channel info before imagegammacorrect (which loses the data)
+ if ($mask) { // i.e. $pngalpha for PNG
+ // mPDF 6
+ if ($colspace=='Indexed') { // generate Alpha channel values from tRNS - only from PNG
+ //Read transparency info
+ $transparency = '';
+ $p = strpos($data,'tRNS');
+ if ($p) {
+ $n=$this->_fourbytes2int(substr($data,($p-4),4));
+ $transparency = substr($data,($p+4),$n);
+ // ord($transparency{$index}) = the alpha value for that index
+ // generate alpha channel
+ for ($ypx = 0; $ypx < $h; ++$ypx) {
+ for ($xpx = 0; $xpx < $w; ++$xpx) {
+ $colorindex = imagecolorat($im, $xpx, $ypx);
+ if ($colorindex >= $n) { $alpha = 255; }
+ else { $alpha = ord($transparency{$colorindex}); } // 0-255
+ $mimgdata .= chr($alpha);
+ }
+ }
+ }
+ }
+ else if ($pngcolortype===0 || $pngcolortype==2) { // generate Alpha channel values from tRNS
+ // Get transparency as array of RGB
+ $p = strpos($data,'tRNS');
+ if ($p) {
+ $trns = '';
+ $n=$this->_fourbytes2int(substr($data,($p-4),4));
+ $t = substr($data,($p+4),$n);
+ if ($colspace=='DeviceGray') { // ct===0
+ $trns=array($this->_trnsvalue(substr($t,0,2), $bpc));
+ }
+ else /* $colspace=='DeviceRGB' */ { // ct==2
+ $trns=array();
+ $trns[0]=$this->_trnsvalue(substr($t,0,2), $bpc);
+ $trns[1]=$this->_trnsvalue(substr($t,2,2), $bpc);
+ $trns[2]=$this->_trnsvalue(substr($t,4,2), $bpc);
+ }
+
+ // generate alpha channel
+ for ($ypx = 0; $ypx < $h; ++$ypx) {
+ for ($xpx = 0; $xpx < $w; ++$xpx) {
+ $rgb = imagecolorat($im, $xpx, $ypx);
+ $r = ($rgb >> 16) & 0xFF;
+ $g = ($rgb >> 8) & 0xFF;
+ $b = $rgb & 0xFF;
+ if ($colspace=='DeviceGray' && $b==$trns[0]) { $alpha = 0; }
+ else if ($r==$trns[0] && $g==$trns[1] && $b==$trns[2]) { $alpha = 0; } // ct==2
+ else { $alpha = 255; }
+ $mimgdata .= chr($alpha);
+ }
+ }
+ }
+ }
+ else {
+ for ($i = 0; $i < $h; $i++) {
+ for ($j = 0; $j < $w; $j++) {
+ $rgb = imagecolorat($im, $j, $i);
+ $alpha = ($rgb & 0x7F000000) >> 24;
+ if ($alpha < 127) { $mimgdata .= chr(255-($alpha * 2)); }
+ else { $mimgdata .= chr(0); }
+ }
+ }
+ }
+ }
+
+ if ($gamma_correction) { imagegammacorrect($im, $gamma_correction, 2.2); } // mPDF 6 Gamma correction
+
+ //Read transparency info
+ $trns=array();
+ $trnsrgb = false;
+ if (!$this->PDFA && !$this->PDFX && !$mask) { // mPDF 6 added NOT mask
+ $p = strpos($data,'tRNS');
+ if ($p) {
+ $n=$this->_fourbytes2int(substr($data,($p-4),4));
+ $t = substr($data,($p+4),$n);
+ if ($colspace=='DeviceGray') { // ct===0
+ $trns=array($this->_trnsvalue(substr($t,0,2), $bpc));
+ }
+ else if ($colspace=='DeviceRGB') { // ct==2
+ $trns[0]=$this->_trnsvalue(substr($t,0,2), $bpc);
+ $trns[1]=$this->_trnsvalue(substr($t,2,2), $bpc);
+ $trns[2]=$this->_trnsvalue(substr($t,4,2), $bpc);
+ $trnsrgb = $trns;
+ if ($targetcs=='DeviceCMYK') {
+ $col = $this->rgb2cmyk(array(3,$trns[0],$trns[1],$trns[2]));
+ $c1 = intval($col[1]*2.55);
+ $c2 = intval($col[2]*2.55);
+ $c3 = intval($col[3]*2.55);
+ $c4 = intval($col[4]*2.55);
+ $trns = array($c1,$c2,$c3,$c4);
+ }
+ else if ($targetcs=='DeviceGray') {
+ $c = intval(($trns[0] * .21) + ($trns[1] * .71) + ($trns[2] * .07));
+ $trns = array($c);
+ }
+ }
+ else { // Indexed
+ $pos = strpos($t,chr(0));
+ if (is_int($pos)) {
+ $pal = imagecolorsforindex($im, $pos);
+ $r = $pal['red'];
+ $g = $pal['green'];
+ $b = $pal['blue'];
+ $trns=array($r,$g,$b); // ****
+ $trnsrgb = $trns;
+ if ($targetcs=='DeviceCMYK') {
+ $col = $this->rgb2cmyk(array(3,$r,$g,$b));
+ $c1 = intval($col[1]*2.55);
+ $c2 = intval($col[2]*2.55);
+ $c3 = intval($col[3]*2.55);
+ $c4 = intval($col[4]*2.55);
+ $trns = array($c1,$c2,$c3,$c4);
+ }
+ else if ($targetcs=='DeviceGray') {
+ $c = intval(($r * .21) + ($g * .71) + ($b * .07));
+ $trns = array($c);
+ }
+ }
+ }
+ }
+ }
+ for ($i = 0; $i < $h; $i++) {
+ for ($j = 0; $j < $w; $j++) {
+ $rgb = imagecolorat($im, $j, $i);
+ $r = ($rgb >> 16) & 0xFF;
+ $g = ($rgb >> 8) & 0xFF;
+ $b = $rgb & 0xFF;
+ if ($colspace=='Indexed') {
+ $pal = imagecolorsforindex($im, $rgb);
+ $r = $pal['red'];
+ $g = $pal['green'];
+ $b = $pal['blue'];
+ }
+
+ if ($targetcs=='DeviceCMYK') {
+ $col = $this->rgb2cmyk(array(3,$r,$g,$b));
+ $c1 = intval($col[1]*2.55);
+ $c2 = intval($col[2]*2.55);
+ $c3 = intval($col[3]*2.55);
+ $c4 = intval($col[4]*2.55);
+ if ($trnsrgb) {
+ // original pixel was not set as transparent but processed color does match
+ if ($trnsrgb!=array($r,$g,$b) && $trns==array($c1,$c2,$c3,$c4)) {
+ if ($c4==0) { $c4=1; } else { $c4--; }
+ }
+ }
+ $imgdata .= chr($c1).chr($c2).chr($c3).chr($c4);
+ }
+ else if ($targetcs=='DeviceGray') {
+ $c = intval(($r * .21) + ($g * .71) + ($b * .07));
+ if ($trnsrgb) {
+ // original pixel was not set as transparent but processed color does match
+ if ($trnsrgb!=array($r,$g,$b) && $trns==array($c)) {
+ if ($c==0) { $c=1; } else { $c--; }
+ }
+ }
+ $imgdata .= chr($c);
+ }
+ else if ($targetcs=='DeviceRGB') {
+ $imgdata .= chr($r).chr($g).chr($b);
+ }
+ }
+ }
+
+ if ($targetcs=='DeviceGray') { $ncols = 1; }
+ else if ($targetcs=='DeviceRGB') { $ncols = 3; }
+ else if ($targetcs=='DeviceCMYK') { $ncols = 4; }
+
+ $imgdata = gzcompress($imgdata);
+ $info = array('w'=>$w,'h'=>$h,'cs'=>$targetcs,'bpc'=>8,'f'=>'FlateDecode','data'=>$imgdata, 'type'=>'png',
+ 'parms'=>'/DecodeParms <>');
+ if ($dpi) { $info['set-dpi'] = $dpi; }
+ if ($mask) {
+ $mimgdata = gzcompress($mimgdata);
+ $minfo = array('w'=>$w,'h'=>$h,'cs'=>'DeviceGray','bpc'=>8,'f'=>'FlateDecode','data'=>$mimgdata, 'type'=>'png',
+ 'parms'=>'/DecodeParms <>');
+ if ($dpi) { $minfo['set-dpi'] = $dpi; }
+ $tempfile = '_tempImgPNG'.md5($data).RAND(1,10000).'.png';
+ $imgmask = count($this->images)+1;
+ $minfo['i']=$imgmask ;
+ $this->images[$tempfile] = $minfo;
+ $info['masked'] = $imgmask;
+ }
+ else if ($trns) { $info['trns'] = $trns; }
+ imagedestroy($im);
+ }
+ return $info;
+}
+
+
+function _trnsvalue($s, $bpc) {
+ // Corrects 2-byte integer to 8-bit depth value
+ // If original image is bpc != 8, tRNS will be in this bpc
+ // $im from imagecreatefromstring will always be in bpc=8
+ // So why do we only need to correct 16-bit tRNS and NOT 2 or 4-bit???
+ $n=$this->_twobytes2int($s);
+ if ($bpc==16) { $n = ($n >> 8); }
+ //else if ($bpc==4) { $n = ($n << 2); }
+ //else if ($bpc==2) { $n = ($n << 4); }
+ return $n;
+}
+
+
+function _fourbytes2int($s) {
+ //Read a 4-byte integer from string
+ return (ord($s[0])<<24) + (ord($s[1])<<16) + (ord($s[2])<<8) + ord($s[3]);
+}
+
+function _twobytes2int($s) { // equivalent to _get_ushort
+ //Read a 2-byte integer from string
+ return (ord(substr($s, 0, 1))<<8) + ord(substr($s, 1, 1));
+}
+
+function _jpgHeaderFromString(&$data) {
+ $p = 4;
+ $p += $this->_twobytes2int(substr($data, $p, 2)); // Length of initial marker block
+ $marker = substr($data, $p, 2);
+ while($marker != chr(255).chr(192) && $marker != chr(255).chr(194) && $p_twobytes2int(substr($data, $p+2, 2))) + 2; // Length of marker block
+ $marker = substr($data, $p, 2);
+ }
+ if ($marker != chr(255).chr(192) && $marker != chr(255).chr(194)) { return false; }
+ return substr($data, $p+2, 10);
+}
+
+function _jpgDataFromHeader($hdr) {
+ $bpc = ord(substr($hdr, 2, 1));
+ if (!$bpc) { $bpc = 8; }
+ $h = $this->_twobytes2int(substr($hdr, 3, 2));
+ $w = $this->_twobytes2int(substr($hdr, 5, 2));
+ $channels = ord(substr($hdr, 7, 1));
+ if ($channels==3) { $colspace='DeviceRGB'; }
+ elseif($channels==4) { $colspace='DeviceCMYK'; }
+ else { $colspace='DeviceGray'; }
+ return array($w, $h, $colspace, $bpc, $channels);
+}
+
+function file_get_contents_by_curl($url, &$data) {
+ $timeout = 5;
+ $ch = curl_init($url);
+ curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:13.0) Gecko/20100101 Firefox/13.0.1'); // mPDF 5.7.4
+ curl_setopt($ch, CURLOPT_HEADER, 0);
+ curl_setopt($ch, CURLOPT_NOBODY, 0);
+ curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , 1 );
+ curl_setopt ( $ch , CURLOPT_CONNECTTIMEOUT , $timeout );
+ $data = curl_exec($ch);
+ curl_close($ch);
+}
+
+
+function file_get_contents_by_socket($url, &$data) {
+ // mPDF 5.7.3
+ $timeout = 1;
+ $p = parse_url($url);
+ $file = $p['path'];
+ if ($p['scheme']=='https') {
+ $prefix = 'ssl://';
+ $port = ($p['port'] ? $p['port'] : 443);
+ }
+ else {
+ $prefix = '';
+ $port = ($p['port'] ? $p['port'] : 80);
+ }
+ if ($p['query']) { $file .= '?'.$p['query']; }
+ if(!($fh = @fsockopen($prefix.$p['host'], $port, $errno, $errstr, $timeout))) { return false; }
+
+ $getstring =
+ "GET ".$file." HTTP/1.0 \r\n" .
+ "Host: ".$p['host']." \r\n" .
+ "Connection: close\r\n\r\n";
+ fwrite($fh, $getstring);
+ // Get rid of HTTP header
+ $s = fgets($fh, 1024);
+ if (!$s) { return false; }
+ $httpheader .= $s;
+ while (!feof($fh)) {
+ $s = fgets($fh, 1024);
+ if ( $s == "\r\n" ) { break; }
+ }
+ $data = '';
+ while (!feof($fh)) {
+ $data .= fgets($fh, 1024);
+ }
+ fclose($fh);
+}
+
+//==============================================================
+
+function _imageTypeFromString(&$data) {
+ $type = '';
+ if (substr($data, 6, 4)== 'JFIF' || substr($data, 6, 4)== 'Exif' || substr($data, 0, 2)== chr(255).chr(216)) { // 0xFF 0xD8 // mpDF 5.7.2
+ $type = 'jpeg';
+ }
+ else if (substr($data, 0, 6)== "GIF87a" || substr($data, 0, 6)== "GIF89a") {
+ $type = 'gif';
+ }
+ else if (substr($data, 0, 8)== chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
+ $type = 'png';
+ }
+/*-- IMAGES-WMF --*/
+ else if (substr($data, 0, 4)== chr(215).chr(205).chr(198).chr(154)) {
+ $type = 'wmf';
+ }
+/*-- END IMAGES-WMF --*/
+ else if (preg_match('//is',$data)) {
+ $type = 'svg';
+ }
+ // BMP images
+ else if (substr($data, 0, 2)== "BM") {
+ $type = 'bmp';
+ }
+ return $type;
+}
+//==============================================================
+
+// Moved outside WMF as also needed for SVG
+function _putformobjects() {
+ reset($this->formobjects);
+ while(list($file,$info)=each($this->formobjects)) {
+ $this->_newobj();
+ $this->formobjects[$file]['n']=$this->n;
+ $this->_out('<_out('/Subtype /Form');
+ $this->_out('/Group '.($this->n+1).' 0 R');
+ $this->_out('/BBox ['.$info['x'].' '.$info['y'].' '.($info['w']+$info['x']).' '.($info['h']+$info['y']).']');
+ if ($this->compress)
+ $this->_out('/Filter /FlateDecode');
+ $data=($this->compress) ? gzcompress($info['data']) : $info['data'];
+ $this->_out('/Length '.strlen($data).'>>');
+ $this->_putstream($data);
+ unset($this->formobjects[$file]['data']);
+ $this->_out('endobj');
+ // Required for SVG transparency (opacity) to work
+ $this->_newobj();
+ $this->_out('<_out('/S /Transparency');
+ $this->_out('>>');
+ $this->_out('endobj');
+ }
+}
+
+function _freadint($f)
+{
+ //Read a 4-byte integer from file
+ $i=ord(fread($f,1))<<24;
+ $i+=ord(fread($f,1))<<16;
+ $i+=ord(fread($f,1))<<8;
+ $i+=ord(fread($f,1));
+ return $i;
+}
+
+function _UTF16BEtextstring($s) {
+ $s = $this->UTF8ToUTF16BE($s, true);
+/*-- ENCRYPTION --*/
+ if ($this->encrypted) {
+ $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
+ }
+/*-- END ENCRYPTION --*/
+ return '('. $this->_escape($s).')';
+}
+
+function _textstring($s) {
+/*-- ENCRYPTION --*/
+ if ($this->encrypted) {
+ $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
+ }
+/*-- END ENCRYPTION --*/
+ return '('. $this->_escape($s).')';
+}
+
+
+function _escape($s)
+{
+ // the chr(13) substitution fixes the Bugs item #1421290.
+ return strtr($s, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\', chr(13) => '\r'));
+}
+
+function _putstream($s) {
+/*-- ENCRYPTION --*/
+ if ($this->encrypted) {
+ $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
+ }
+/*-- END ENCRYPTION --*/
+ $this->_out('stream');
+ $this->_out($s);
+ $this->_out('endstream');
+}
+
+
+function _out($s,$ln=true) {
+ if($this->state==2) {
+ if ($this->bufferoutput) {
+ $this->headerbuffer.= $s."\n";
+ }
+/*-- COLUMNS --*/
+ else if (($this->ColActive) && !$this->processingHeader && !$this->processingFooter) {
+ // Captures everything in buffer for columns; Almost everything is sent from fn. Cell() except:
+ // Images sent from Image() or
+ // later sent as _out($textto) in printbuffer
+ // Line()
+ if (preg_match('/q \d+\.\d\d+ 0 0 (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ cm \/(I|FO)\d+ Do Q/',$s,$m)) { // Image data
+ $h = ($m[1]/_MPDFK);
+ // Update/overwrite the lowest bottom of printing y value for a column
+ $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y+$h;
+ }
+/*-- TABLES --*/
+ else if (preg_match('/\d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ ([\-]{0,1}\d+\.\d\d+) re/',$s,$m) && $this->tableLevel>0) { // Rect in table
+ $h = ($m[1]/_MPDFK);
+ // Update/overwrite the lowest bottom of printing y value for a column
+ $this->ColDetails[$this->CurrCol]['bottom_margin'] = max($this->ColDetails[$this->CurrCol]['bottom_margin'],($this->y+$h));
+ }
+/*-- END TABLES --*/
+ else { // Td Text Set in Cell()
+ if (isset($this->ColDetails[$this->CurrCol]['bottom_margin'])) { $h = $this->ColDetails[$this->CurrCol]['bottom_margin'] - $this->y; }
+ else { $h = 0; }
+ }
+ if ($h < 0) { $h = -$h; }
+ $this->columnbuffer[] = array(
+ 's' => $s, // Text string to output
+ 'col' => $this->CurrCol, // Column when printed
+ 'x' => $this->x, // x when printed
+ 'y' => $this->y, // this->y when printed (after column break)
+ 'h' => $h // actual y at bottom when printed = y+h
+ );
+ }
+/*-- END COLUMNS --*/
+/*-- TABLES --*/
+ else if ($this->table_rotate && !$this->processingHeader && !$this->processingFooter) {
+ // Captures eveything in buffer for rotated tables;
+ $this->tablebuffer .= $s . "\n";
+ }
+/*-- END TABLES --*/
+ else if ($this->kwt && !$this->processingHeader && !$this->processingFooter) {
+ // Captures eveything in buffer for keep-with-table (h1-6);
+ $this->kwt_buffer[] = array(
+ 's' => $s, // Text string to output
+ 'x' => $this->x, // x when printed
+ 'y' => $this->y, // y when printed
+ );
+ }
+ else if (($this->keep_block_together) && !$this->processingHeader && !$this->processingFooter) {
+ // do nothing
+ }
+ else {
+ $this->pages[$this->page] .= $s.($ln == true ? "\n" : '');
+ }
+
+ }
+ else {
+ $this->buffer .= $s.($ln == true ? "\n" : '');
+ }
+}
+
+/*-- WATERMARK --*/
+// add a watermark
+function watermark( $texte, $angle=45, $fontsize=96, $alpha=0.2 ) {
+ if ($this->PDFA || $this->PDFX) { $this->Error('PDFA and PDFX do not permit transparency, so mPDF does not allow Watermarks!'); }
+ if (!$this->watermark_font) { $this->watermark_font = $this->default_font; }
+ $this->SetFont( $this->watermark_font, "B", $fontsize, false ); // Don't output
+ $texte= $this->purify_utf8_text($texte);
+ if ($this->text_input_as_HTML) {
+ $texte= $this->all_entities_to_utf8($texte);
+ }
+ if ($this->usingCoreFont) { $texte = mb_convert_encoding($texte,$this->mb_enc,'UTF-8'); }
+
+ // DIRECTIONALITY
+ if (preg_match("/([".$this->pregRTLchars."])/u", $texte)) { $this->biDirectional = true; } // *OTL*
+
+ $textvar = 0;
+ $save_OTLtags = $this->OTLtags;
+ $this->OTLtags = array();
+ if ($this->useKerning) {
+ if ($this->CurrentFont['haskernGPOS']) { $this->OTLtags['Plus'] .= ' kern'; }
+ else { $textvar = ($textvar | FC_KERNING); }
+ }
+
+/*-- OTL --*/
+ // Use OTL OpenType Table Layout - GSUB & GPOS
+ if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
+ $texte = $this->otl->applyOTL($texte, $this->CurrentFont['useOTL']);
+ $OTLdata = $this->otl->OTLdata;
+ }
+/*-- END OTL --*/
+ $this->OTLtags = $save_OTLtags ;
+
+ $this->magic_reverse_dir($texte, $this->directionality, $OTLdata);
+
+ $this->SetAlpha($alpha);
+
+ $this->SetTColor($this->ConvertColor(0));
+ $szfont = $fontsize;
+ $loop = 0;
+ $maxlen = (min($this->w,$this->h) ); // sets max length of text as 7/8 width/height of page
+ while ( $loop == 0 )
+ {
+ $this->SetFont( $this->watermark_font, "B", $szfont, false ); // Don't output
+ $offset = ((sin(deg2rad($angle))) * ($szfont/_MPDFK));
+
+ $strlen = $this->GetStringWidth($texte, true, $OTLdata, $textvar);
+ if ( $strlen > $maxlen - $offset )
+ $szfont --;
+ else
+ $loop ++;
+ }
+
+ $this->SetFont( $this->watermark_font, "B", $szfont-0.1, true, true); // Output The -0.1 is because SetFont above is not written to PDF
+ // Repeating it will not output anything as mPDF thinks it is set
+ $adj = ((cos(deg2rad($angle))) * ($strlen/2));
+ $opp = ((sin(deg2rad($angle))) * ($strlen/2));
+ $wx = ($this->w/2) - $adj + $offset/3;
+ $wy = ($this->h/2) + $opp;
+ $this->Rotate($angle,$wx,$wy);
+ $this->Text($wx,$wy,$texte,$OTLdata,$textvar);
+ $this->Rotate(0);
+ $this->SetTColor($this->ConvertColor(0));
+
+ $this->SetAlpha(1);
+
+}
+
+function watermarkImg( $src, $alpha=0.2 ) {
+ if ($this->PDFA || $this->PDFX) { $this->Error('PDFA and PDFX do not permit transparency, so mPDF does not allow Watermarks!'); }
+ if ($this->watermarkImgBehind) { $this->watermarkImgAlpha = $this->SetAlpha($alpha, 'Normal', true); }
+ else { $this->SetAlpha($alpha, $this->watermarkImgAlphaBlend); }
+ $this->Image($src,0,0,0,0,'','', true, true, true);
+ if (!$this->watermarkImgBehind) { $this->SetAlpha(1); }
+}
+/*-- END WATERMARK --*/
+
+
+function Rotate($angle,$x=-1,$y=-1)
+{
+ if($x==-1)
+ $x=$this->x;
+ if($y==-1)
+ $y=$this->y;
+ if($this->angle!=0)
+ $this->_out('Q');
+ $this->angle=$angle;
+ if($angle!=0)
+ {
+ $angle*=M_PI/180;
+ $c=cos($angle);
+ $s=sin($angle);
+ $cx=$x*_MPDFK;
+ $cy=($this->h-$y)*_MPDFK;
+ $this->_out(sprintf('q %.5F %.5F %.5F %.5F %.3F %.3F cm 1 0 0 1 %.3F %.3F cm',$c,$s,-$s,$c,$cx,$cy,-$cx,-$cy));
+ }
+}
+
+
+
+function CircularText($x, $y, $r, $text, $align='top', $fontfamily='', $fontsize=0, $fontstyle='', $kerning=120, $fontwidth=100, $divider) {
+ if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
+ if (empty($this->directw)) { $this->directw = new directw($this); }
+ $this->directw->CircularText($x, $y, $r, $text, $align, $fontfamily, $fontsize, $fontstyle, $kerning, $fontwidth, $divider);
+}
+
+
+// From Invoice
+function RoundedRect($x, $y, $w, $h, $r, $style = '')
+{
+ $hp = $this->h;
+ if($style=='F')
+ $op='f';
+ elseif($style=='FD' or $style=='DF')
+ $op='B';
+ else
+ $op='S';
+ $MyArc = 4/3 * (sqrt(2) - 1);
+ $this->_out(sprintf('%.3F %.3F m',($x+$r)*_MPDFK,($hp-$y)*_MPDFK ));
+ $xc = $x+$w-$r ;
+ $yc = $y+$r;
+ $this->_out(sprintf('%.3F %.3F l', $xc*_MPDFK,($hp-$y)*_MPDFK ));
+
+ $this->_Arc($xc + $r*$MyArc, $yc - $r, $xc + $r, $yc - $r*$MyArc, $xc + $r, $yc);
+ $xc = $x+$w-$r ;
+ $yc = $y+$h-$r;
+ $this->_out(sprintf('%.3F %.3F l',($x+$w)*_MPDFK,($hp-$yc)*_MPDFK));
+ $this->_Arc($xc + $r, $yc + $r*$MyArc, $xc + $r*$MyArc, $yc + $r, $xc, $yc + $r);
+ $xc = $x+$r ;
+ $yc = $y+$h-$r;
+ $this->_out(sprintf('%.3F %.3F l',$xc*_MPDFK,($hp-($y+$h))*_MPDFK));
+ $this->_Arc($xc - $r*$MyArc, $yc + $r, $xc - $r, $yc + $r*$MyArc, $xc - $r, $yc);
+ $xc = $x+$r ;
+ $yc = $y+$r;
+ $this->_out(sprintf('%.3F %.3F l',($x)*_MPDFK,($hp-$yc)*_MPDFK ));
+ $this->_Arc($xc - $r, $yc - $r*$MyArc, $xc - $r*$MyArc, $yc - $r, $xc, $yc - $r);
+ $this->_out($op);
+}
+
+function _Arc($x1, $y1, $x2, $y2, $x3, $y3)
+{
+ $h = $this->h;
+ $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', $x1*_MPDFK, ($h-$y1)*_MPDFK,
+ $x2*_MPDFK, ($h-$y2)*_MPDFK, $x3*_MPDFK, ($h-$y3)*_MPDFK));
+}
+
+
+
+
+//====================================================
+
+
+
+/*-- DIRECTW --*/
+function Shaded_box( $text,$font='',$fontstyle='B',$szfont='',$width='70%',$style='DF',$radius=2.5,$fill='#FFFFFF',$color='#000000',$pad=2 ) {
+ // F (shading - no line),S (line, no shading),DF (both)
+ if (!class_exists('directw', false)) { include(_MPDF_PATH.'classes/directw.php'); }
+ if (empty($this->directw)) { $this->directw = new directw($this); }
+ $this->directw->Shaded_box( $text,$font,$fontstyle,$szfont,$width,$style,$radius,$fill,$color,$pad);
+}
+/*-- END DIRECTW --*/
+
+
+function UTF8StringToArray($str, $addSubset=true) {
+ $out = array();
+ $len = strlen($str);
+ 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;
+ if ($addSubset && isset($this->CurrentFont['subset'])) {
+ $this->CurrentFont['subset'][$uni] = $uni;
+ }
+ }
+ }
+ return $out;
+}
+
+
+//Convert utf-8 string to for Font Subsets
+function UTF8toSubset($str) {
+ $ret = '<';
+ //$str = preg_replace('/'.preg_quote($this->aliasNbPg,'/').'/', chr(7), $str ); // mPDF 6 deleted
+ //$str = preg_replace('/'.preg_quote($this->aliasNbPgGp,'/').'/', chr(8), $str ); // mPDF 6 deleted
+ $unicode = $this->UTF8StringToArray($str);
+ $orig_fid = $this->CurrentFont['subsetfontids'][0];
+ $last_fid = $this->CurrentFont['subsetfontids'][0];
+ foreach($unicode as $c) {
+/* // mPDF 6 deleted
+ if ($c == 7 || $c == 8) {
+ if ($orig_fid != $last_fid) {
+ $ret .= '> Tj /F'.$orig_fid.' '.$this->FontSizePt.' Tf <';
+ $last_fid = $orig_fid;
+ }
+ if ($c == 7) { $ret .= $this->aliasNbPgHex; }
+ else { $ret .= $this->aliasNbPgGpHex; }
+ continue;
+ }
+*/
+ if (!$this->_charDefined($this->CurrentFont['cw'], $c)) { $c = 0; } // mPDF 6
+ for ($i=0; $i<99; $i++) {
+ // return c as decimal char
+ $init = array_search($c, $this->CurrentFont['subsets'][$i]);
+ if ($init!==false) {
+ if ($this->CurrentFont['subsetfontids'][$i] != $last_fid) {
+ $ret .= '> Tj /F'.$this->CurrentFont['subsetfontids'][$i].' '.$this->FontSizePt.' Tf <';
+ $last_fid = $this->CurrentFont['subsetfontids'][$i];
+ }
+ $ret .= sprintf("%02s", strtoupper(dechex($init)));
+ break;
+ }
+ // TrueType embedded SUBSETS
+ else if (count($this->CurrentFont['subsets'][$i]) < 255) {
+ $n = count($this->CurrentFont['subsets'][$i]);
+ $this->CurrentFont['subsets'][$i][$n] = $c;
+ if ($this->CurrentFont['subsetfontids'][$i] != $last_fid) {
+ $ret .= '> Tj /F'.$this->CurrentFont['subsetfontids'][$i].' '.$this->FontSizePt.' Tf <';
+ $last_fid = $this->CurrentFont['subsetfontids'][$i];
+ }
+ $ret .= sprintf("%02s", strtoupper(dechex($n)));
+ break;
+ }
+ else if (!isset($this->CurrentFont['subsets'][($i+1)])) {
+ // TrueType embedded SUBSETS
+ $this->CurrentFont['subsets'][($i+1)] = array(0=>0);
+ $new_fid = count($this->fonts)+$this->extraFontSubsets+1;
+ $this->CurrentFont['subsetfontids'][($i+1)] = $new_fid;
+ $this->extraFontSubsets++;
+ }
+ }
+ }
+ $ret .= '>';
+ if ($last_fid != $orig_fid) {
+ $ret .= ' Tj /F'.$orig_fid.' '.$this->FontSizePt.' Tf <> ';
+ }
+ return $ret;
+}
+
+
+// Converts UTF-8 strings to UTF16-BE.
+function UTF8ToUTF16BE($str, $setbom=true) {
+ if ($this->checkSIP && preg_match("/([\x{20000}-\x{2FFFF}])/u", $str)) {
+ if (!in_array($this->currentfontfamily, array('gb','big5','sjis','uhc','gbB','big5B','sjisB','uhcB','gbI','big5I','sjisI','uhcI',
+ 'gbBI','big5BI','sjisBI','uhcBI'))) {
+ $str = preg_replace("/[\x{20000}-\x{2FFFF}]/u", chr(0), $str);
+ }
+ }
+ if ($this->checkSMP && preg_match("/([\x{10000}-\x{1FFFF}])/u", $str )) {
+ $str = preg_replace("/[\x{10000}-\x{1FFFF}]/u", chr(0), $str );
+ }
+ $outstr = ""; // string to be returned
+ if ($setbom) {
+ $outstr .= "\xFE\xFF"; // Byte Order Mark (BOM)
+ }
+ $outstr .= mb_convert_encoding($str, 'UTF-16BE', 'UTF-8');
+ return $outstr;
+}
+
+
+
+
+
+// ====================================================
+// ====================================================
+/*-- CJK-FONTS --*/
+
+// from class PDF_Chinese CJK EXTENSIONS
+function AddCIDFont($family,$style,$name,&$cw,$CMap,$registry,$desc)
+{
+ $fontkey=strtolower($family).strtoupper($style);
+ if(isset($this->fonts[$fontkey]))
+ $this->Error("Font already added: $family $style");
+ $i=count($this->fonts)+$this->extraFontSubsets+1;
+ $name=str_replace(' ','',$name);
+ if ($family == 'sjis') { $up = -120; } else { $up = -130; }
+ // ? 'up' and 'ut' do not seem to be referenced anywhere
+ $this->fonts[$fontkey]=array('i'=>$i,'type'=>'Type0','name'=>$name,'up'=>$up,'ut'=>40,'cw'=>$cw,'CMap'=>$CMap,'registry'=>$registry,'MissingWidth'=>1000,'desc'=>$desc);
+}
+
+function AddCJKFont($family) {
+
+ if ($this->PDFA || $this->PDFX) {
+ $this->Error("Adobe CJK fonts cannot be embedded in mPDF (required for PDFA1-b and PDFX/1-a).");
+ }
+ if ($family == 'big5') { $this->AddBig5Font(); }
+ else if ($family == 'gb') { $this->AddGBFont(); }
+ else if ($family == 'sjis') { $this->AddSJISFont(); }
+ else if ($family == 'uhc') { $this->AddUHCFont(); }
+}
+
+function AddBig5Font()
+{
+ //Add Big5 font with proportional Latin
+ $family='big5';
+ $name='MSungStd-Light-Acro';
+ $cw=$this->Big5_widths;
+ $CMap='UniCNS-UTF16-H';
+ $registry=array('ordering'=>'CNS1','supplement'=>4);
+ $desc = array(
+ 'Ascent' => 880,
+ 'Descent' => -120,
+ 'CapHeight' => 880,
+ 'Flags' => 6,
+ 'FontBBox' => '[-160 -249 1015 1071]',
+ 'ItalicAngle' => 0,
+ 'StemV' => 93,
+ );
+ $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
+ $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
+ $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
+ $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
+}
+
+
+function AddGBFont()
+{
+ //Add GB font with proportional Latin
+ $family='gb';
+ $name='STSongStd-Light-Acro';
+ $cw=$this->GB_widths;
+ $CMap='UniGB-UTF16-H';
+ $registry=array('ordering'=>'GB1','supplement'=>4);
+ $desc = array(
+ 'Ascent' => 880,
+ 'Descent' => -120,
+ 'CapHeight' => 737,
+ 'Flags' => 6,
+ 'FontBBox' => '[-25 -254 1000 880]',
+ 'ItalicAngle' => 0,
+ 'StemV' => 58,
+ 'Style' => '<< /Panose <000000000400000000000000> >>',
+ );
+ $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
+ $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
+ $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
+ $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
+}
+
+
+function AddSJISFont()
+{
+ //Add SJIS font with proportional Latin
+ $family='sjis';
+ $name='KozMinPro-Regular-Acro';
+ $cw=$this->SJIS_widths;
+ $CMap='UniJIS-UTF16-H';
+ $registry=array('ordering'=>'Japan1','supplement'=>5);
+ $desc = array(
+ 'Ascent' => 880,
+ 'Descent' => -120,
+ 'CapHeight' => 740,
+ 'Flags' => 6,
+ 'FontBBox' => '[-195 -272 1110 1075]',
+ 'ItalicAngle' => 0,
+ 'StemV' => 86,
+ 'XHeight' => 502,
+ );
+ $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
+ $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
+ $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
+ $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
+}
+
+function AddUHCFont()
+{
+ //Add UHC font with proportional Latin
+ $family='uhc';
+ $name='HYSMyeongJoStd-Medium-Acro';
+ $cw=$this->UHC_widths;
+ $CMap='UniKS-UTF16-H';
+ $registry=array('ordering'=>'Korea1','supplement'=>2);
+ $desc = array(
+ 'Ascent' => 880,
+ 'Descent' => -120,
+ 'CapHeight' => 720,
+ 'Flags' => 6,
+ 'FontBBox' => '[-28 -148 1001 880]',
+ 'ItalicAngle' => 0,
+ 'StemV' => 60,
+ 'Style' => '<< /Panose <000000000600000000000000> >>',
+ );
+ $this->AddCIDFont($family,'',$name,$cw,$CMap,$registry,$desc);
+ $this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry,$desc);
+ $this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry,$desc);
+ $this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry,$desc);
+}
+
+/*-- END CJK-FONTS --*/
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+function SetDefaultFont($font) {
+ // Disallow embedded fonts to be used as defaults in PDFA
+ if ($this->PDFA || $this->PDFX) {
+ if (strtolower($font) == 'ctimes') { $font = 'serif'; }
+ if (strtolower($font) == 'ccourier') { $font = 'monospace'; }
+ if (strtolower($font) == 'chelvetica') { $font = 'sans-serif'; }
+ }
+ $font = $this->SetFont($font); // returns substituted font if necessary
+ $this->default_font = $font;
+ $this->original_default_font = $font;
+ if (!$this->watermark_font ) { $this->watermark_font = $font; } // *WATERMARK*
+ $this->defaultCSS['BODY']['FONT-FAMILY'] = $font;
+ $this->cssmgr->CSS['BODY']['FONT-FAMILY'] = $font;
+}
+
+function SetDefaultFontSize($fontsize) {
+ $this->default_font_size = $fontsize;
+ $this->original_default_font_size = $fontsize;
+ $this->SetFontSize($fontsize);
+ $this->defaultCSS['BODY']['FONT-SIZE'] = $fontsize . 'pt';
+ $this->cssmgr->CSS['BODY']['FONT-SIZE'] = $fontsize . 'pt';
+}
+
+function SetDefaultBodyCSS($prop, $val) {
+ if ($prop) {
+ $this->defaultCSS['BODY'][strtoupper($prop)] = $val;
+ $this->cssmgr->CSS['BODY'][strtoupper($prop)] = $val;
+ }
+}
+
+
+function SetDirectionality($dir='ltr') {
+/*-- OTL --*/
+ if (strtolower($dir) == 'rtl') {
+ if ($this->directionality != 'rtl') {
+ // Swop L/R Margins so page 1 RTL is an 'even' page
+ $tmp = $this->DeflMargin;
+ $this->DeflMargin = $this->DefrMargin;
+ $this->DefrMargin = $tmp;
+ $this->orig_lMargin = $this->DeflMargin;
+ $this->orig_rMargin = $this->DefrMargin;
+
+ $this->SetMargins($this->DeflMargin,$this->DefrMargin,$this->tMargin);
+ }
+ $this->directionality = 'rtl';
+ $this->defaultAlign = 'R';
+ $this->defaultTableAlign = 'R';
+ }
+ else {
+/*-- END OTL --*/
+ $this->directionality = 'ltr';
+ $this->defaultAlign = 'L';
+ $this->defaultTableAlign = 'L';
+ } // *OTL*
+ $this->cssmgr->CSS['BODY']['DIRECTION'] = $this->directionality;
+}
+
+
+// Return either a number (factor) - based on current set fontsize (if % or em) - or exact lineheight (with 'mm' after it)
+function fixLineheight($v) {
+ $lh = false;
+ if (preg_match('/^[0-9\.,]*$/',$v) && $v >= 0) { return ($v + 0); }
+ else if (strtoupper($v) == 'NORMAL' || $v == 'N') {
+ return 'N'; // mPDF 6
+ }
+ else {
+ $tlh = $this->ConvertSize($v,$this->FontSize,$this->FontSize,true);
+ if ($tlh) { return ($tlh.'mm'); }
+ }
+ return $this->normalLineheight;
+}
+
+
+function _getNormalLineheight($desc=false) {
+ if (!$desc) { $desc = $this->CurrentFont['desc']; }
+ if ($this->useFixedNormalLineHeight) {
+ $lh = $this->normalLineheight;
+ }
+ else if (isset($desc['Ascent']) && $desc['Ascent']) {
+ $lh = ($this->adjustFontDescLineheight * ($desc['Ascent'] - $desc['Descent'] + $desc['Leading'])/1000);
+ }
+ else {
+ $lh = $this->normalLineheight;
+ }
+ return $lh;
+}
+
+// Set a (fixed) lineheight to an actual value - either to named fontsize(pts) or default
+function SetLineHeight($FontPt='',$lh = '') {
+ if (!$FontPt) { $FontPt = $this->FontSizePt; }
+ $fs = $FontPt/_MPDFK;
+ $this->lineheight = $this->_computeLineheight($lh, $fs);
+}
+
+function _computeLineheight($lh, $fs='') {
+ if ($this->shrin_k > 1) { $k = $this->shrin_k; }
+ else { $k = 1; }
+ if (!$fs) { $fs = $this->FontSize; }
+ if ($lh == 'N') {
+ $lh = $this->_getNormalLineheight();
+ }
+ if (preg_match('/mm/',$lh)) {
+ return (($lh + 0.0) / $k); // convert to number
+ }
+ else if ($lh > 0) {
+ return ($fs * $lh);
+ }
+ return ($fs * $this->normalLineheight);
+}
+
+function _setLineYpos(&$fontsize, &$fontdesc, &$CSSlineheight, $blockYpos=false) {
+ $ypos['glyphYorigin'] = 0;
+ $ypos['baseline-shift'] = 0;
+ $linegap = 0;
+ $leading = 0;
+
+ if (isset($fontdesc['Ascent']) && $fontdesc['Ascent'] && !$this->useFixedTextBaseline) {
+ // Fontsize uses font metrics - this method seems to produce results compatible with browsers (except IE9)
+ $ypos['boxtop'] = $fontdesc['Ascent']/1000 * $fontsize;
+ $ypos['boxbottom'] = $fontdesc['Descent']/1000 * $fontsize;
+ if (isset($fontdesc['Leading'])) { $linegap = $fontdesc['Leading']/1000 * $fontsize; }
+ }
+ // Default if not set - uses baselineC
+ else {
+ $ypos['boxtop'] = (0.5 + $this->baselineC) * $fontsize;
+ $ypos['boxbottom'] = -(0.5 - $this->baselineC) * $fontsize;
+ }
+ $fontheight = $ypos['boxtop'] - $ypos['boxbottom'];
+
+ if ($this->shrin_k > 1) { $shrin_k = $this->shrin_k; }
+ else { $shrin_k = 1; }
+
+ $leading =0;
+ if ($CSSlineheight == 'N') {
+ $lh = $this->_getNormalLineheight($fontdesc);
+ $lineheight = ($fontsize * $lh);
+ $leading += $linegap; // specified in hhea or sTypo in OpenType tables ****************************************
+ }
+ else if (preg_match('/mm/',$CSSlineheight)) { $lineheight = (($CSSlineheight + 0.0) / $shrin_k); } // convert to number
+ // ??? If lineheight is a factor e.g. 1.3 ?? use factor x 1em or ? use 'normal' lineheight * factor ******************************
+ // Could depend on value for $text_height - a draft CSS value as set above for now
+ else if ($CSSlineheight > 0) { $lineheight = ($fontsize * $CSSlineheight); }
+ else { $lineheight = ($fontsize * $this->normalLineheight); }
+
+ // In general, calculate the "leading" - the difference between the fontheight and the lineheight
+ // and add half to the top and half to the bottom. BUT
+ // If an inline element has a font-size less than the block element, and the line-height is set as an em or % value
+ // it will add too much leading below the font and expand the height of the line - so just use the block element exttop/extbottom:
+ if (preg_match('/mm/',$CSSlineheight) && $ypos['boxtop'] < $blockYpos['boxtop'] && $ypos['boxbottom'] > $blockYpos['boxbottom']) {
+ $ypos['exttop'] = $blockYpos['exttop'];
+ $ypos['extbottom'] = $blockYpos['extbottom'];
+ }
+ else {
+ $leading += ($lineheight - $fontheight);
+
+ $ypos['exttop'] = $ypos['boxtop'] + $leading/2;
+ $ypos['extbottom'] = $ypos['boxbottom'] - $leading/2;
+ }
+
+
+ // TEMP ONLY FOR DEBUGGING *********************************
+ //$ypos['lineheight'] = $lineheight;
+ //$ypos['fontheight'] = $fontheight;
+ //$ypos['leading'] = $leading;
+
+ return $ypos;
+}
+
+
+
+
+/* Called from WriteFlowingBlock() and finishFlowingBlock()
+ Determines the line hieght and glyph/writing position
+ for each element in the line to be written */
+function _setInlineBlockHeights(&$lineBox, &$stackHeight, &$content, &$font, $is_table) {
+ if ($this->shrin_k > 1) { $shrin_k = $this->shrin_k; }
+ else { $shrin_k = 1; }
+
+ $ypos = array();
+ $bordypos = array();
+ $bgypos = array();
+
+ if ($is_table) {
+ // FOR TABLE
+ $fontsize = $this->FontSize;
+ $fontkey = $this->FontFamily.$this->FontStyle;
+ $fontdesc = $this->fonts[$fontkey]['desc'];
+ $CSSlineheight = $this->cellLineHeight ;
+ $line_stacking_strategy = $this->cellLineStackingStrategy; // inline-line-height [default] | block-line-height | max-height | grid-height
+ $line_stacking_shift = $this->cellLineStackingShift; // consider-shifts [default] | disregard-shifts
+ }
+ else {
+ // FOR BLOCK FONT
+ $fontsize = $this->blk[$this->blklvl]['InlineProperties']['size'];
+ $fontkey = $this->blk[$this->blklvl]['InlineProperties']['family'].$this->blk[$this->blklvl]['InlineProperties']['style'];
+ $fontdesc = $this->fonts[$fontkey]['desc'];
+ $CSSlineheight = $this->blk[$this->blklvl]['line_height'];
+ // inline-line-height | block-line-height | max-height | grid-height
+ $line_stacking_strategy = (isset($this->blk[$this->blklvl]['line_stacking_strategy']) ? $this->blk[$this->blklvl]['line_stacking_strategy'] : 'inline-line-height');
+ // consider-shifts | disregard-shifts
+ $line_stacking_shift = (isset($this->blk[$this->blklvl]['line_stacking_shift']) ? $this->blk[$this->blklvl]['line_stacking_shift'] : 'consider-shifts');
+ }
+ $boxLineHeight = $this->_computeLineheight($CSSlineheight, $fontsize);
+
+
+ // First, set a "strut" using block font at index $lineBox[-1]
+ $ypos[-1] = $this->_setLineYpos($fontsize, $fontdesc, $CSSlineheight);
+
+ // for the block element - always taking the block EXTENDED progression including leading - which may be negative
+ if ($line_stacking_strategy == 'block-line-height') {
+ $topy = $ypos[-1]['exttop'];
+ $bottomy = $ypos[-1]['extbottom'];
+ }
+ else {
+ $topy = 0;
+ $bottomy = 0;
+ }
+
+ // Get text-middle for aligning images/objects
+ $midpoint = $ypos[-1]['boxtop'] - (($ypos[-1]['boxtop']-$ypos[-1]['boxbottom'])/2);
+
+ // for images / inline objects / replaced elements
+ $mta = 0; // Maximum top-aligned
+ $mba = 0; // Maximum bottom-aligned
+ foreach ( $content as $k => $chunk ) {
+ if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]['type'] == 'listmarker') {
+ $ypos[$k] = $ypos[-1];
+ // UPDATE Maximums
+ if ($line_stacking_strategy == 'block-line-height' || $line_stacking_strategy == 'grid-height' || $line_stacking_strategy == 'max-height') { // don't include extended block progression of all inline elements
+ if ($ypos[$k]['boxtop'] > $topy) $topy = $ypos[$k]['boxtop'];
+ if ($ypos[$k]['boxbottom'] < $bottomy) $bottomy = $ypos[$k]['boxbottom'];
+ }
+ else {
+ if ($ypos[$k]['exttop'] > $topy) $topy = $ypos[$k]['exttop'];
+ if ($ypos[$k]['extbottom'] < $bottomy) $bottomy = $ypos[$k]['extbottom'];
+ }
+ }
+ else if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]['type'] == 'dottab') { // mPDF 6 DOTTAB
+ $fontsize = $font[$k]['size'];
+ $fontdesc = $font[$k]['curr']['desc'];
+ $lh = 1;
+ $ypos[$k] = $this->_setLineYpos($fontsize, $fontdesc, $lh, $ypos[-1]); // Lineheight=1 fixed
+ }
+ else if (isset($this->objectbuffer[$k])) {
+ $oh = $this->objectbuffer[$k]['OUTER-HEIGHT'];
+ $va = $this->objectbuffer[$k]['vertical-align'];
+
+ if ($va == 'BS') { // (BASELINE default)
+ if ($oh > $topy) $topy = $oh;
+ }
+ else if ($va == 'M') {
+ if (($midpoint + $oh/2) > $topy) $topy = $midpoint + $oh/2;
+ if (($midpoint - $oh/2) < $bottomy) $bottomy = $midpoint - $oh/2;
+ }
+ else if ($va == 'TT') {
+ if (($ypos[-1]['boxtop'] - $oh) < $bottomy) {
+ $bottomy = $ypos[-1]['boxtop'] - $oh;
+ $topy = max($topy, $ypos[-1]['boxtop']);
+ }
+ }
+ else if ($va == 'TB') {
+ if (($ypos[-1]['boxbottom'] + $oh) > $topy) {
+ $topy = $ypos[-1]['boxbottom'] + $oh;
+ $bottomy = min($bottomy, $ypos[-1]['boxbottom']);
+ }
+ }
+ else if ($va == 'T') {
+ if ($oh > $mta) $mta = $oh;
+ }
+ else if ($va == 'B') {
+ if ($oh > $mba) $mba = $oh;
+ }
+ }
+ else if ($content[$k] || $content[$k]==='0') {
+ // FOR FLOWING BLOCK
+ $fontsize = $font[$k]['size'];
+ $fontdesc = $font[$k]['curr']['desc'];
+ // In future could set CSS line-height from inline elements; for now, use block level:
+ $ypos[$k] = $this->_setLineYpos($fontsize, $fontdesc, $CSSlineheight, $ypos[-1]);
+
+ if (isset($font[$k]['textparam']['text-baseline']) && $font[$k]['textparam']['text-baseline'] != 0) {
+ $ypos[$k]['baseline-shift'] = $font[$k]['textparam']['text-baseline'];
+ }
+
+ // DO ALIGNMENT FOR BASELINES *******************
+ // Until most fonts have OpenType BASE tables, this won't work
+ // $ypos[$k] compared to $ypos[-1] or $ypos[$k-1] using $dominant_baseline and $baseline_table
+
+ // UPDATE Maximums
+ if ($line_stacking_strategy == 'block-line-height' || $line_stacking_strategy == 'grid-height' || $line_stacking_strategy == 'max-height') { // don't include extended block progression of all inline elements
+ if ($line_stacking_shift == 'disregard-shifts') {
+ if ($ypos[$k]['boxtop'] > $topy) $topy = $ypos[$k]['boxtop'] ;
+ if ($ypos[$k]['boxbottom'] < $bottomy) $bottomy = $ypos[$k]['boxbottom'] ;
+ }
+ else {
+ if (($ypos[$k]['boxtop'] + $ypos[$k]['baseline-shift']) > $topy) $topy = $ypos[$k]['boxtop'] + $ypos[$k]['baseline-shift'] ;
+ if (($ypos[$k]['boxbottom'] + $ypos[$k]['baseline-shift']) < $bottomy) $bottomy = $ypos[$k]['boxbottom'] + $ypos[$k]['baseline-shift'] ;
+ }
+ }
+ else {
+ if ($line_stacking_shift == 'disregard-shifts') {
+ if ($ypos[$k]['exttop'] > $topy) $topy = $ypos[$k]['exttop'] ;
+ if ($ypos[$k]['extbottom'] < $bottomy) $bottomy = $ypos[$k]['extbottom'] ;
+ }
+ else {
+ if (($ypos[$k]['exttop'] + $ypos[$k]['baseline-shift']) > $topy) $topy = $ypos[$k]['exttop'] + $ypos[$k]['baseline-shift'] ;
+ if (($ypos[$k]['extbottom'] + $ypos[$k]['baseline-shift']) < $bottomy) $bottomy = $ypos[$k]['extbottom'] + $ypos[$k]['baseline-shift'] ;
+ }
+ }
+
+ // If BORDER set on inline element
+ if (isset($font[$k]['bord']) && $font[$k]['bord']) {
+ $bordfontsize = $font[$k]['textparam']['bord-decoration']['fontsize'] / $shrin_k;
+ $bordfontkey = $font[$k]['textparam']['bord-decoration']['fontkey'] ;
+ if ($bordfontkey != $fontkey || $bordfontsize != $fontsize || isset($font[$k]['textparam']['bord-decoration']['baseline'])) {
+ $bordfontdesc = $this->fonts[$bordfontkey]['desc'];
+ $bordypos[$k] = $this->_setLineYpos($bordfontsize, $bordfontdesc, $CSSlineheight, $ypos[-1]);
+ if (isset($font[$k]['textparam']['bord-decoration']['baseline']) && $font[$k]['textparam']['bord-decoration']['baseline'] != 0) {
+ $bordypos[$k]['baseline-shift'] = $font[$k]['textparam']['bord-decoration']['baseline'] / $shrin_k;
+ }
+ }
+ }
+ // If BACKGROUND set on inline element
+ if (isset($font[$k]['spanbgcolor']) && $font[$k]['spanbgcolor']) {
+ $bgfontsize = $font[$k]['textparam']['bg-decoration']['fontsize'] / $shrin_k;
+ $bgfontkey = $font[$k]['textparam']['bg-decoration']['fontkey'] ;
+ if ($bgfontkey != $fontkey || $bgfontsize != $fontsize || isset($font[$k]['textparam']['bg-decoration']['baseline'])) {
+ $bgfontdesc = $this->fonts[$bgfontkey]['desc'];
+ $bgypos[$k] = $this->_setLineYpos($bgfontsize, $bgfontdesc, $CSSlineheight, $ypos[-1]);
+ if (isset($font[$k]['textparam']['bg-decoration']['baseline']) && $font[$k]['textparam']['bg-decoration']['baseline'] != 0) {
+ $bgypos[$k]['baseline-shift'] = $font[$k]['textparam']['bg-decoration']['baseline'] / $shrin_k;
+ }
+ }
+ }
+ }
+ }
+
+
+ // TOP or BOTTOM aligned images
+ if ($mta > ($topy - $bottomy) ) {
+ if (($topy - $mta) < $bottomy ) $bottomy = $topy - $mta ;
+ }
+ if ($mba > ($topy - $bottomy) ) {
+ if (($bottomy + $mba) > $topy) $topy = $bottomy + $mba ;
+ }
+
+ if ($line_stacking_strategy == 'block-line-height') { // fixed height set by block element (whether present or not)
+ $topy = $ypos[-1]['exttop'];
+ $bottomy = $ypos[-1]['extbottom'];
+ }
+
+ $inclusiveHeight = $topy - $bottomy;
+
+ // SET $stackHeight taking note of line_stacking_strategy
+ // NB inclusive height already takes account of need to consider block progression height (excludes leading set by lineheight)
+ // or extended block progression height (includes leading set by lineheight)
+ if ($line_stacking_strategy == 'block-line-height') { // fixed = extended block progression height of block element
+ $stackHeight = $boxLineHeight;
+ }
+ else if ($line_stacking_strategy == 'max-height') { // smallest height which includes extended block progression height of block element
+ // and block progression heights of inline elements (NOT extended)
+ $stackHeight = $inclusiveHeight;
+ }
+ else if ($line_stacking_strategy == 'grid-height') { // smallest multiple of block element lineheight to include
+ // block progression heights of inline elements (NOT extended)
+ $stackHeight = $boxLineHeight;
+ while($stackHeight < $inclusiveHeight) { $stackHeight += $boxLineHeight; }
+ }
+ else { // 'inline-line-height' = default // smallest height which includes extended block progression height of block element
+ // AND extended block progression heights of inline elements
+ $stackHeight = $inclusiveHeight;
+ }
+
+ $diff = $stackHeight - $inclusiveHeight;
+ $topy += $diff/2;
+ $bottomy -= $diff/2;
+
+ // ADJUST $ypos => lineBox using $stackHeight; lineBox are all offsets from the top of stackHeight in mm
+ // and SET IMAGE OFFSETS
+ $lineBox[-1]['boxtop'] = $topy - $ypos[-1]['boxtop'];
+ $lineBox[-1]['boxbottom'] = $topy - $ypos[-1]['boxbottom'];
+// $lineBox[-1]['exttop'] = $topy - $ypos[-1]['exttop'];
+// $lineBox[-1]['extbottom'] = $topy - $ypos[-1]['extbottom'];
+ $lineBox[-1]['glyphYorigin'] = $topy - $ypos[-1]['glyphYorigin'];
+ $lineBox[-1]['baseline-shift'] = $ypos[-1]['baseline-shift'];
+
+ $midpoint = $lineBox[-1]['boxbottom'] - (($lineBox[-1]['boxbottom']-$lineBox[-1]['boxtop'])/2);
+
+ foreach ( $content as $k => $chunk ) {
+ if (isset($this->objectbuffer[$k])) {
+ $oh = $this->objectbuffer[$k]['OUTER-HEIGHT'];
+ // LIST MARKERS
+ if ($this->objectbuffer[$k]['type'] == 'listmarker') {
+ $oh = $fontsize;
+ }
+ else if ($this->objectbuffer[$k]['type'] == 'dottab') { // mPDF 6 DOTTAB
+ $oh = $font[$k]['size']; // == $this->objectbuffer[$k]['fontsize']/_MPDFK;
+ $lineBox[$k]['boxtop'] = $topy - $ypos[$k]['boxtop'];
+ $lineBox[$k]['boxbottom'] = $topy - $ypos[$k]['boxbottom'];
+ $lineBox[$k]['glyphYorigin'] = $topy - $ypos[$k]['glyphYorigin'];
+ $lineBox[$k]['baseline-shift'] = 0;
+// continue;
+ }
+ $va = $this->objectbuffer[$k]['vertical-align']; // = $objattr['vertical-align'] = set as M,T,B,S
+
+ if ($va == 'BS') { // (BASELINE default)
+ $lineBox[$k]['top'] = $lineBox[-1]['glyphYorigin'] - $oh;
+ }
+ else if ($va == 'M') {
+ $lineBox[$k]['top'] = $midpoint - $oh/2;
+ }
+ else if ($va == 'TT') {
+ $lineBox[$k]['top'] = $lineBox[-1]['boxtop'];
+ }
+ else if ($va == 'TB') {
+ $lineBox[$k]['top'] = $lineBox[-1]['boxbottom'] - $oh;
+ }
+ else if ($va == 'T') {
+ $lineBox[$k]['top'] = 0;
+ }
+ else if ($va == 'B') {
+ $lineBox[$k]['top'] = $stackHeight-$oh;
+ }
+ }
+ else if ($content[$k] || $content[$k]==='0') {
+ $lineBox[$k]['boxtop'] = $topy - $ypos[$k]['boxtop'];
+ $lineBox[$k]['boxbottom'] = $topy - $ypos[$k]['boxbottom'];
+// $lineBox[$k]['exttop'] = $topy - $ypos[$k]['exttop'];
+// $lineBox[$k]['extbottom'] = $topy - $ypos[$k]['extbottom'];
+ $lineBox[$k]['glyphYorigin'] = $topy - $ypos[$k]['glyphYorigin'];
+ $lineBox[$k]['baseline-shift'] = $ypos[$k]['baseline-shift'];
+ if (isset($bordypos[$k]['boxtop'])) {
+ $lineBox[$k]['border-boxtop'] = $topy - $bordypos[$k]['boxtop'];
+ $lineBox[$k]['border-boxbottom'] = $topy - $bordypos[$k]['boxbottom'];
+ $lineBox[$k]['border-baseline-shift'] = $bordypos[$k]['baseline-shift'];
+ }
+ if (isset($bgypos[$k]['boxtop'])) {
+ $lineBox[$k]['background-boxtop'] = $topy - $bgypos[$k]['boxtop'];
+ $lineBox[$k]['background-boxbottom'] = $topy - $bgypos[$k]['boxbottom'];
+ $lineBox[$k]['background-baseline-shift'] = $bgypos[$k]['baseline-shift'];
+ }
+ }
+ }
+}
+
+
+function SetBasePath($str='') {
+ if ( isset($_SERVER['HTTP_HOST']) ) { $host = $_SERVER['HTTP_HOST']; }
+ else if ( isset($_SERVER['SERVER_NAME']) ) { $host = $_SERVER['SERVER_NAME']; }
+ else { $host = ''; }
+ if (!$str) {
+ if ($_SERVER['SCRIPT_NAME']) { $currentPath = dirname($_SERVER['SCRIPT_NAME']); }
+ else { $currentPath = dirname($_SERVER['PHP_SELF']); }
+ $currentPath = str_replace("\\","/",$currentPath);
+ if ($currentPath == '/') { $currentPath = ''; }
+ if ($host) { // mPDF 6
+ if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']) { $currpath = 'https://' . $host . $currentPath .'/'; }
+ else { $currpath = 'http://' . $host . $currentPath .'/'; }
+ }
+ else { $currpath = ''; }
+ $this->basepath = $currpath;
+ $this->basepathIsLocal = true;
+ return;
+ }
+ $str = preg_replace('/\?.*/','',$str);
+ if (!preg_match('/(http|https|ftp):\/\/.*\//i',$str)) { $str .= '/'; }
+ $str .= 'xxx'; // in case $str ends in / e.g. http://www.bbc.co.uk/
+ $this->basepath = dirname($str) . "/"; // returns e.g. e.g. http://www.google.com/dir1/dir2/dir3/
+ $this->basepath = str_replace("\\","/",$this->basepath); //If on Windows
+ $tr = parse_url($this->basepath);
+ if (isset($tr['host']) && ($tr['host'] == $host)) { $this->basepathIsLocal = true; }
+ else { $this->basepathIsLocal = false; }
+}
+
+
+function GetFullPath(&$path,$basepath='') {
+ // When parsing CSS need to pass temporary basepath - so links are relative to current stylesheet
+ if (!$basepath) { $basepath = $this->basepath; }
+ //Fix path value
+ $path = str_replace("\\","/",$path); //If on Windows
+
+ // mPDF 5.7.2
+ if (substr($path,0,2) == "//") {
+ $tr = parse_url($basepath);
+ $path = $tr['scheme'].':'.$path; // mPDF 6
+ }
+
+ $regexp = '|^./|'; // Inadvertently corrects "./path/etc" and "//www.domain.com/etc"
+ $path = preg_replace($regexp,'',$path);
+
+ if(substr($path,0,1) == '#') { return; }
+ // mPDF 5.7.4
+ if (substr($path,0,7) == "mailto:") { return; }
+ if (substr($path,0,3) == "../") { //It is a Relative Link
+ $backtrackamount = substr_count($path,"../");
+ $maxbacktrack = substr_count($basepath,"/") - 3;
+ $filepath = str_replace("../",'',$path);
+ $path = $basepath;
+ //If it is an invalid relative link, then make it go to directory root
+ if ($backtrackamount > $maxbacktrack) $backtrackamount = $maxbacktrack;
+ //Backtrack some directories
+ for( $i = 0 ; $i < $backtrackamount + 1 ; $i++ ) $path = substr( $path, 0 , strrpos($path,"/") );
+ $path = $path . "/" . $filepath; //Make it an absolute path
+ }
+ else if( strpos($path,":/") === false || strpos($path,":/") > 10) { //It is a Local Link
+ if (substr($path,0,1) == "/") {
+ $tr = parse_url($basepath);
+ // mPDF 5.7.2
+ $root = '';
+ if (!empty($tr['scheme'])) { $root .= $tr['scheme'].'://'; }
+ $root .= $tr['host'];
+ $root .= ((isset($tr['port']) && $tr['port']) ? (':'.$tr['port']) : ''); // mPDF 5.7.3
+ $path = $root . $path;
+ }
+ else { $path = $basepath . $path; }
+ }
+ //Do nothing if it is an Absolute Link
+}
+
+
+// Used for external CSS files
+function _get_file($path) {
+ // If local file try using local path (? quicker, but also allowed even if allow_url_fopen false)
+ $contents = '';
+ // mPDF 5.7.3
+ if (strpos($path,"//") === false ) { $path = preg_replace('/\.css\?.*$/', '.css', $path); }
+ $contents = @file_get_contents($path);
+ if ($contents) { return $contents; }
+ if ($this->basepathIsLocal) {
+ $tr = parse_url($path);
+ $lp=getenv("SCRIPT_NAME");
+ $ap=realpath($lp);
+ $ap=str_replace("\\","/",$ap);
+ $docroot=substr($ap,0,strpos($ap,$lp));
+ // WriteHTML parses all paths to full URLs; may be local file name
+ if ($tr['scheme'] && $tr['host'] && $_SERVER["DOCUMENT_ROOT"] ) {
+ $localpath = $_SERVER["DOCUMENT_ROOT"] . $tr['path'];
+ }
+ // DOCUMENT_ROOT is not returned on IIS
+ else if ($docroot) {
+ $localpath = $docroot . $tr['path'];
+ }
+ else { $localpath = $path; }
+ $contents = @file_get_contents($localpath);
+ }
+ // if not use full URL
+ else if (!$contents && !ini_get('allow_url_fopen') && function_exists("curl_init")) {
+ $ch = curl_init($path);
+ curl_setopt($ch, CURLOPT_HEADER, 0);
+ curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , 1 );
+ $contents = curl_exec($ch);
+ curl_close($ch);
+ }
+ return $contents;
+}
+
+
+function docPageNum($num = 0, $extras = false) {
+ if ($num < 1) { $num = $this->page; }
+ $type = $this->defaultPageNumStyle; // set default Page Number Style
+ $ppgno = $num;
+ $suppress = 0;
+ $offset = 0;
+ $lastreset = 0;
+ foreach($this->PageNumSubstitutions AS $psarr) {
+ if ($num >= $psarr['from']) {
+ if ($psarr['reset']) {
+ if ($psarr['reset']>1) { $offset = $psarr['reset']-1; }
+ $ppgno = $num - $psarr['from'] + 1 + $offset;
+ $lastreset = $psarr['from'];
+ }
+ if ($psarr['type']) { $type = $psarr['type']; }
+ if (strtoupper($psarr['suppress'])=='ON' || $psarr['suppress']==1) { $suppress = 1; }
+ else if (strtoupper($psarr['suppress'])=='OFF') { $suppress = 0; }
+ }
+ }
+ if ($suppress) { return ''; }
+
+ $ppgno = $this->_getStyledNumber($ppgno, $type);
+ if ($extras) { $ppgno = $this->pagenumPrefix . $ppgno . $this->pagenumSuffix; }
+ return $ppgno;
+}
+
+function docPageNumTotal($num = 0, $extras = false) {
+ if ($num < 1) { $num = $this->page; }
+ $type = $this->defaultPageNumStyle; // set default Page Number Style
+ $ppgstart = 1;
+ $ppgend = count($this->pages)+1;
+ $suppress = 0;
+ $offset = 0;
+ foreach($this->PageNumSubstitutions AS $psarr) {
+ if ($num >= $psarr['from']) {
+ if ($psarr['reset']) {
+ if ($psarr['reset']>1) { $offset = $psarr['reset']-1; }
+ $ppgstart = $psarr['from'] + $offset;
+ $ppgend = count($this->pages)+1 + $offset;
+ }
+ if ($psarr['type']) { $type = $psarr['type']; }
+ if (strtoupper($psarr['suppress'])=='ON' || $psarr['suppress']==1) { $suppress = 1; }
+ else if (strtoupper($psarr['suppress'])=='OFF') { $suppress = 0; }
+ }
+ if ($num < $psarr['from']) {
+ if ($psarr['reset']) {
+ $ppgend = $psarr['from'] + $offset;
+ break;
+ }
+ }
+ }
+ if ($suppress) { return ''; }
+ $ppgno = $ppgend-$ppgstart+$offset;
+
+ $ppgno = $this->_getStyledNumber($ppgno, $type);
+ if ($extras) { $ppgno = $this->pagenumPrefix . $ppgno . $this->pagenumSuffix; }
+ return $ppgno;
+}
+
+// mPDF 6
+function _getStyledNumber($ppgno, $type, $listmarker=false) {
+ if ($listmarker) {
+ $reverse = true; // Reverse RTL numerals (Hebrew) when using for list
+ $checkfont = true; // Using list - font is set, so check if character is available
+ }
+ else {
+ $reverse = false; // For pagenumbers, RTL numerals (Hebrew) will get reversed later by bidi
+ $checkfont = false; // For pagenumbers - font is not set, so no check
+ }
+ $lowertype = strtolower($type);
+ if ($lowertype == 'upper-latin' || $lowertype == 'upper-alpha' || $type=='A') { $ppgno = $this->dec2alpha($ppgno,true); }
+ else if ($lowertype == 'lower-latin' || $lowertype == 'lower-alpha' || $type=='a') { $ppgno = $this->dec2alpha($ppgno,false);}
+ else if ($lowertype == 'upper-roman' || $type=='I') { $ppgno = $this->dec2roman($ppgno,true); }
+ else if ($lowertype == 'lower-roman' || $type=='i') { $ppgno = $this->dec2roman($ppgno,false); }
+ else if ($lowertype=='hebrew') { $ppgno = $this->dec2hebrew($ppgno, $reverse); }
+ else if (preg_match('/(arabic-indic|bengali|devanagari|gujarati|gurmukhi|kannada|malayalam|oriya|persian|tamil|telugu|thai|urdu|cambodian|khmer|lao)/i',$lowertype,$m)) {
+ switch($m[1]) { //Format type
+ case 'arabic-indic': $cp = 0x0660; break;
+ case 'persian':
+ case 'urdu': $cp = 0x06F0; break;
+ case 'bengali': $cp = 0x09E6; break;
+ case 'devanagari': $cp = 0x0966; break;
+ case 'gujarati': $cp = 0x0AE6; break;
+ case 'gurmukhi': $cp = 0x0A66; break;
+ case 'kannada': $cp = 0x0CE6; break;
+ case 'malayalam': $cp = 0x0D66; break;
+ case 'oriya': $cp = 0x0B66; break;
+ case 'telugu': $cp = 0x0C66; break;
+ case 'tamil': $cp = 0x0BE6; break;
+ case 'thai': $cp = 0x0E50; break;
+ case 'khmer':
+ case 'cambodian': $cp = 0x17E0; break;
+ case 'lao': $cp = 0x0ED0; break;
+ }
+ $ppgno = $this->dec2other($ppgno, $cp, $checkfont);
+ }
+ else if ($lowertype=='cjk-decimal') { $ppgno = $this->dec2cjk($ppgno); }
+ return $ppgno;
+}
+
+function docPageSettings($num = 0) {
+ // Returns current type (numberstyle), suppression state for this page number;
+ // reset is only returned if set for this page number
+ if ($num < 1) { $num = $this->page; }
+ $type = $this->defaultPageNumStyle; // set default Page Number Style
+ $ppgno = $num;
+ $suppress = 0;
+ $offset = 0;
+ $reset = '';
+ foreach($this->PageNumSubstitutions AS $psarr) {
+ if ($num >= $psarr['from']) {
+ if ($psarr['reset']) {
+ if ($psarr['reset']>1) { $offset = $psarr['reset']-1; }
+ $ppgno = $num - $psarr['from'] + 1 + $offset;
+ }
+ if ($psarr['type']) { $type = $psarr['type']; }
+ if (strtoupper($psarr['suppress'])=='ON' || $psarr['suppress']==1) { $suppress = 1; }
+ else if (strtoupper($psarr['suppress'])=='OFF') { $suppress = 0; }
+ }
+ if ($num == $psarr['from']) { $reset = $psarr['reset']; }
+ }
+ if ($suppress) { $suppress = 'on'; }
+ else { $suppress = 'off'; }
+ return array($type, $suppress, $reset);
+}
+
+function RestartDocTemplate() {
+ $this->docTemplateStart = $this->page;
+}
+
+
+
+//Page header
+function Header($content='') {
+
+ $this->cMarginL = 0;
+ $this->cMarginR = 0;
+
+
+ if (($this->mirrorMargins && ($this->page%2==0) && $this->HTMLHeaderE) || ($this->mirrorMargins && ($this->page%2==1) && $this->HTMLHeader) || (!$this->mirrorMargins && $this->HTMLHeader)) {
+ $this->writeHTMLHeaders();
+ return;
+ }
+}
+
+
+
+/*-- TABLES --*/
+function TableHeaderFooter($content='',$tablestartpage='',$tablestartcolumn ='',$horf = 'H',$level, $firstSpread=true, $finalSpread=true) {
+ if(($horf=='H' || $horf=='F') && !empty($content)) { // mPDF 5.7.2
+ $table = &$this->table[1][1];
+
+ // mPDF 5.7.2
+ if ($horf=='F') { // Table Footer
+ $firstrow = count($table['cells']) - $table['footernrows'];
+ $lastrow = count($table['cells']) - 1;
+ }
+ else { // Table Header
+ $firstrow = 0;
+ $lastrow = $table['headernrows'] - 1;
+ }
+ if(empty($content[$firstrow])) {
+ if ($this->debug) { $this->Error("<tfoot> must precede <tbody> in a table"); }
+ else { return; }
+ }
+
+
+ // Advance down page by half width of top border
+ if ($horf=='H') { // Only if header
+ if ($table['borders_separate']) { $adv = $table['border_spacing_V']/2 + $table['border_details']['T']['w'] + $table['padding']['T']; }
+ else { $adv = $table['max_cell_border_width']['T'] /2 ; }
+ if ($adv) {
+ if ($this->table_rotate) {
+ $this->y += ($adv);
+ }
+ else {
+ $this->DivLn($adv,$this->blklvl,true);
+ }
+ }
+ }
+
+ $topy = $content[$firstrow][0]['y']-$this->y;
+
+ for ($i=$firstrow ; $i<=$lastrow; $i++) {
+
+ $y = $this->y;
+
+/*-- COLUMNS --*/
+ // If outside columns, this is done in PaintDivBB
+ if ($this->ColActive) {
+ //OUTER FILL BGCOLOR of DIVS
+ if ($this->blklvl > 0) {
+ $firstblockfill = $this->GetFirstBlockFill();
+ if ($firstblockfill && $this->blklvl >= $firstblockfill) {
+ $divh = $content[$i][0]['h'];
+ $bak_x = $this->x;
+ $this->DivLn($divh,-3,false);
+ // Reset current block fill
+ $bcor = $this->blk[$this->blklvl]['bgcolorarray'];
+ $this->SetFColor($bcor);
+ $this->x = $bak_x;
+ }
+ }
+ }
+/*-- END COLUMNS --*/
+
+ $colctr = 0;
+ foreach($content[$i] as $tablehf) {
+ $colctr++;
+ $y = $tablehf['y'] - $topy;
+ $this->y = $y;
+ //Set some cell values
+ $x = $tablehf['x'];
+ if (($this->mirrorMargins) && ($tablestartpage == 'ODD') && (($this->page)%2==0)) { // EVEN
+ $x = $x +$this->MarginCorrection;
+ }
+ else if (($this->mirrorMargins) && ($tablestartpage == 'EVEN') && (($this->page)%2==1)) { // ODD
+ $x = $x +$this->MarginCorrection;
+ }
+/*-- COLUMNS --*/
+ // Added to correct for Columns
+ if ($this->ColActive) {
+ if ($this->directionality == 'rtl') { // *OTL*
+ $x -= ($this->CurrCol - $tablestartcolumn) * ($this->ColWidth+$this->ColGap); // *OTL*
+ } // *OTL*
+ else { // *OTL*
+ $x += ($this->CurrCol - $tablestartcolumn) * ($this->ColWidth+$this->ColGap);
+ } // *OTL*
+ }
+/*-- END COLUMNS --*/
+
+ if ($colctr==1) { $x0 = $x; }
+
+ // mPDF ITERATION
+ if ($this->iterationCounter) {
+ foreach($tablehf['textbuffer'] AS $k=>$t) {
+ if (!is_array($t[0]) && preg_match('/{iteration ([a-zA-Z0-9_]+)}/',$t[0], $m)) {
+ $vname = '__'.$m[1].'_';
+ if (!isset($this->$vname)) { $this->$vname = 1; }
+ else { $this->$vname++; }
+ $tablehf['textbuffer'][$k][0] = preg_replace('/{iteration '.$m[1].'}/', $this->$vname, $tablehf['textbuffer'][$k][0]);
+ }
+ }
+ }
+
+ $w = $tablehf['w'];
+ $h = $tablehf['h'];
+ $va = $tablehf['va'];
+ $R = $tablehf['R'];
+ $direction = $tablehf['direction'];
+ $mih = $tablehf['mih'];
+ $border = $tablehf['border'];
+ $border_details = $tablehf['border_details'];
+ $padding = $tablehf['padding'];
+ $this->tabletheadjustfinished = true;
+
+ $textbuffer = $tablehf['textbuffer'];
+
+ //Align
+ $align = $tablehf['a'];
+ $this->cellTextAlign=$align;
+
+ $this->cellLineHeight = $tablehf['cellLineHeight'];
+ $this->cellLineStackingStrategy = $tablehf['cellLineStackingStrategy'];
+ $this->cellLineStackingShift = $tablehf['cellLineStackingShift'];
+
+ $this->x = $x;
+
+ if ($this->ColActive) {
+ if ($table['borders_separate']) {
+ $tablefill = isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0;
+ if ($tablefill) {
+ $color = $this->ConvertColor($tablefill);
+ if ($color) {
+ $xadj = ($table['border_spacing_H']/2);
+ $yadj = ($table['border_spacing_V']/2);
+ $wadj = $table['border_spacing_H'];
+ $hadj = $table['border_spacing_V'];
+ if ($i == $firstrow && $horf=='H') { // Top
+ $yadj += $table['padding']['T'] + $table['border_details']['T']['w'] ;
+ $hadj += $table['padding']['T'] + $table['border_details']['T']['w'] ;
+ }
+ if (($i == ($lastrow) || (isset($tablehf['rowspan']) && ($i+$tablehf['rowspan']) == ($lastrow+1)) || (!isset($tablehf['rowspan']) && ($i+1) == ($lastrow+1))) && $horf=='F') { // Bottom
+ $hadj += $table['padding']['B'] + $table['border_details']['B']['w'] ;
+ }
+ if ($colctr == 1) { // Left
+ $xadj += $table['padding']['L'] + $table['border_details']['L']['w'] ;
+ $wadj += $table['padding']['L'] + $table['border_details']['L']['w'] ;
+ }
+ if ($colctr == count($content[$i]) ) { // Right
+ $wadj += $table['padding']['R'] + $table['border_details']['R']['w'] ;
+ }
+ $this->SetFColor($color);
+ $this->Rect($x - $xadj, $y - $yadj, $w + $wadj, $h + $hadj, 'F');
+ }
+ }
+ }
+ }
+
+ if ($table['empty_cells']!='hide' || !empty($textbuffer) || !$table['borders_separate']) { $paintcell = true; }
+ else { $paintcell = false; }
+
+ //Vertical align
+ if ($R && INTVAL($R) > 0 && isset($va) && $va!='B') { $va='B';}
+
+ if (!isset($va) || empty($va) || $va=='M') $this->y += ($h-$mih)/2;
+ elseif (isset($va) && $va=='B') $this->y += $h-$mih;
+
+
+ //TABLE ROW OR CELL FILL BGCOLOR
+ $fill = 0;
+ if (isset($tablehf['bgcolor']) && $tablehf['bgcolor'] && $tablehf['bgcolor']!='transparent') {
+ $fill = $tablehf['bgcolor'];
+ $leveladj = 6;
+ }
+ else if (isset($content[$i][0]['trbgcolor']) && $content[$i][0]['trbgcolor'] && $content[$i][0]['trbgcolor']!='transparent') { // Row color
+ $fill = $content[$i][0]['trbgcolor'];
+ $leveladj = 3;
+ }
+ if ($fill && $paintcell) {
+ $color = $this->ConvertColor($fill);
+ if ($color) {
+ if ($table['borders_separate']) {
+ if ($this->ColActive) {
+ $this->SetFColor($color);
+ $this->Rect($x+ ($table['border_spacing_H']/2), $y+ ($table['border_spacing_V']/2), $w- $table['border_spacing_H'], $h- $table['border_spacing_V'], 'F');
+ }
+ else {
+ $this->tableBackgrounds[$level*9+$leveladj][] = array('gradient'=>false, 'x'=>($x + ($table['border_spacing_H']/2)), 'y'=>($y + ($table['border_spacing_V']/2)), 'w'=>($w - $table['border_spacing_H']), 'h'=>($h - $table['border_spacing_V']), 'col'=>$color);
+ }
+ }
+ else {
+ if ($this->ColActive) {
+ $this->SetFColor($color);
+ $this->Rect($x, $y, $w, $h, 'F');
+ }
+ else {
+ $this->tableBackgrounds[$level*9+$leveladj][] = array('gradient'=>false, 'x'=>$x, 'y'=>$y, 'w'=>$w, 'h'=>$h, 'col'=>$color);
+ }
+ }
+ }
+ }
+
+
+/*-- BACKGROUNDS --*/
+ if (isset($tablehf['gradient']) && $tablehf['gradient'] && $paintcell){
+ $g = $this->grad->parseBackgroundGradient($tablehf['gradient']);
+ if ($g) {
+ if ($table['borders_separate']) {
+ $px = $x+ ($table['border_spacing_H']/2);
+ $py = $y+ ($table['border_spacing_V']/2);
+ $pw = $w- $table['border_spacing_H'];
+ $ph = $h- $table['border_spacing_V'];
+ }
+ else {
+ $px = $x;
+ $py = $y;
+ $pw = $w;
+ $ph = $h;
+ }
+ if ($this->ColActive) {
+ $this->grad->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
+ }
+ else {
+ $this->tableBackgrounds[$level*9+7][] = array('gradient'=>true, 'x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
+ }
+ }
+ }
+
+ if (isset($tablehf['background-image']) && $paintcell){
+ if ($tablehf['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $tablehf['background-image']['gradient'] )) {
+ $g = $this->grad->parseMozGradient( $tablehf['background-image']['gradient'] );
+ if ($g) {
+ if ($table['borders_separate']) {
+ $px = $x+ ($table['border_spacing_H']/2);
+ $py = $y+ ($table['border_spacing_V']/2);
+ $pw = $w- $table['border_spacing_H'];
+ $ph = $h- $table['border_spacing_V'];
+ }
+ else {
+ $px = $x;
+ $py = $y;
+ $pw = $w;
+ $ph = $h;
+ }
+ if ($this->ColActive) {
+ $this->grad->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']);
+ }
+ else {
+ $this->tableBackgrounds[$level*9+7][] = array('gradient'=>true, 'x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
+ }
+ }
+ }
+ else if ($tablehf['background-image']['image_id']) { // Background pattern
+ $n = count($this->patterns)+1;
+ if ($table['borders_separate']) {
+ $px = $x+ ($table['border_spacing_H']/2);
+ $py = $y+ ($table['border_spacing_V']/2);
+ $pw = $w- $table['border_spacing_H'];
+ $ph = $h- $table['border_spacing_V'];
+ }
+ else {
+ $px = $x;
+ $py = $y;
+ $pw = $w;
+ $ph = $h;
+ }
+ if ($this->ColActive) {
+ list($orig_w, $orig_h, $x_repeat, $y_repeat) = $this->_resizeBackgroundImage($tablehf['background-image']['orig_w'], $tablehf['background-image']['orig_h'], $pw, $ph, $tablehf['background-image']['resize'], $tablehf['background-image']['x_repeat'] , $tablehf['background-image']['y_repeat']);
+ $this->patterns[$n] = array('x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'pgh'=>$this->h, 'image_id'=>$tablehf['background-image']['image_id'], 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$tablehf['background-image']['x_pos'] , 'y_pos'=>$tablehf['background-image']['y_pos'] , 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'itype'=>$tablehf['background-image']['itype']);
+ if ($tablehf['background-image']['opacity']>0 && $tablehf['background-image']['opacity']<1) { $opac = $this->SetAlpha($tablehf['background-image']['opacity'],'Normal',true); }
+ else { $opac = ''; }
+ $this->_out(sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $px*_MPDFK, ($this->h-$py)*_MPDFK, $pw*_MPDFK, -$ph*_MPDFK));
+ }
+ else {
+ $this->tableBackgrounds[$level*9+8][] = array('x'=>$px, 'y'=>$py, 'w'=>$pw, 'h'=>$ph, 'image_id'=>$tablehf['background-image']['image_id'], 'orig_w'=>$tablehf['background-image']['orig_w'], 'orig_h'=>$tablehf['background-image']['orig_h'], 'x_pos'=>$tablehf['background-image']['x_pos'], 'y_pos'=>$tablehf['background-image']['y_pos'], 'x_repeat'=>$tablehf['background-image']['x_repeat'], 'y_repeat'=>$tablehf['background-image']['y_repeat'], 'clippath'=>'', 'resize'=>$tablehf['background-image']['resize'], 'opacity'=>$tablehf['background-image']['opacity'], 'itype'=>$tablehf['background-image']['itype']);
+ }
+ }
+ }
+/*-- END BACKGROUNDS --*/
+
+ //Cell Border
+ if ($table['borders_separate'] && $paintcell && $border) {
+ $this->_tableRect($x+ ($table['border_spacing_H']/2)+($border_details['L']['w'] /2), $y+ ($table['border_spacing_V']/2)+($border_details['T']['w'] /2), $w-$table['border_spacing_H']-($border_details['L']['w'] /2)-($border_details['R']['w'] /2), $h- $table['border_spacing_V']-($border_details['T']['w'] /2)-($border_details['B']['w']/2), $border, $border_details, false, $table['borders_separate']);
+ }
+ else if ($paintcell && $border) {
+ $this->_tableRect($x, $y, $w, $h, $border, $border_details, true, $table['borders_separate']); // true causes buffer
+ }
+
+ //Print cell content
+ if (!empty($textbuffer)) {
+ if ($horf=='F' && preg_match('/{colsum([0-9]*)[_]*}/', $textbuffer[0][0], $m)) {
+ $rep = sprintf("%01.".intval($m[1])."f", $this->colsums[$colctr-1]);
+ $textbuffer[0][0] = preg_replace('/{colsum[0-9_]*}/', $rep ,$textbuffer[0][0]);
+ }
+
+ if ($R) {
+ $cellPtSize = $textbuffer[0][11] / $this->shrin_k;
+ if (!$cellPtSize) { $cellPtSize = $this->default_font_size; }
+ $cellFontHeight = ($cellPtSize/_MPDFK);
+ $opx = $this->x;
+ $opy = $this->y;
+ $angle = INTVAL($R);
+ // Only allow 45 - 90 degrees (when bottom-aligned) or -90
+ if ($angle > 90) { $angle = 90; }
+ else if ($angle > 0 && (isset($va) && $va!='B')) { $angle = 90; }
+ else if ($angle > 0 && $angle <45) { $angle = 45; }
+ else if ($angle < 0) { $angle = -90; }
+ $offset = ((sin(deg2rad($angle))) * 0.37 * $cellFontHeight);
+ if (isset($align) && $align =='R') {
+ $this->x += ($w) + ($offset) - ($cellFontHeight/3) - ($padding['R'] + $border_details['R']['w']);
+ }
+ else if (!isset($align ) || $align =='C') {
+ $this->x += ($w/2) + ($offset);
+ }
+ else {
+ $this->x += ($offset) + ($cellFontHeight/3)+($padding['L'] + $border_details['L']['w']);
+ }
+ $str = '';
+ foreach($tablehf['textbuffer'] AS $t) { $str .= $t[0].' '; }
+ $str = rtrim($str);
+
+ if (!isset($va) || $va=='M') {
+ $this->y -= ($h-$mih)/2; //Undo what was added earlier VERTICAL ALIGN
+ if ($angle > 0) { $this->y += (($h-$mih)/2)+($padding['T'] + $border_details['T']['w']) + ($mih-($padding['T'] + $border_details['T']['w']+$border_details['B']['w']+$padding['B'])); }
+ else if ($angle < 0) { $this->y += (($h-$mih)/2)+($padding['T'] + $border_details['T']['w']); }
+ }
+ else if (isset($va) && $va=='B') {
+ $this->y -= $h-$mih; //Undo what was added earlier VERTICAL ALIGN
+ if ($angle > 0) { $this->y += $h-($border_details['B']['w']+$padding['B']); }
+ else if ($angle < 0) { $this->y += $h-$mih+($padding['T'] + $border_details['T']['w']); }
+ }
+ else if (isset($va) && $va=='T') {
+ if ($angle > 0) { $this->y += $mih-($border_details['B']['w']+$padding['B']); }
+ else if ($angle < 0) { $this->y += ($padding['T'] + $border_details['T']['w']); }
+ }
+
+ $this->Rotate($angle,$this->x,$this->y);
+ $s_fs = $this->FontSizePt;
+ $s_f = $this->FontFamily;
+ $s_st = $this->FontStyle;
+ if (!empty($textbuffer[0][3])) { //Font Color
+ $cor = $textbuffer[0][3];
+ $this->SetTColor($cor);
+ }
+ $this->SetFont($textbuffer[0][4],$textbuffer[0][2],$cellPtSize,true,true);
+
+ $this->magic_reverse_dir($str, $this->directionality, $textbuffer[0][18]);
+ $this->Text($this->x,$this->y,$str,$textbuffer[0][18],$textbuffer[0][8]); // textvar
+ $this->Rotate(0);
+ $this->SetFont($s_f,$s_st,$s_fs,true,true);
+ $this->SetTColor(0);
+ $this->x = $opx;
+ $this->y = $opy;
+ }
+ else {
+ if ($table['borders_separate']) { // NB twice border width
+ $xadj = $border_details['L']['w'] + $padding['L'] +($table['border_spacing_H']/2);
+ $wadj = $border_details['L']['w'] + $border_details['R']['w'] + $padding['L'] +$padding['R'] + $table['border_spacing_H'];
+ $yadj = $border_details['T']['w'] + $padding['T'] + ($table['border_spacing_H']/2);
+ }
+ else {
+ $xadj = $border_details['L']['w']/2 + $padding['L'];
+ $wadj = ($border_details['L']['w'] + $border_details['R']['w'])/2 + $padding['L'] + $padding['R'];
+ $yadj = $border_details['T']['w']/2 + $padding['T'];
+ }
+
+ $this->divwidth=$w-($wadj);
+ $this->x += $xadj;
+ $this->y += $yadj;
+ $this->printbuffer($textbuffer,'',true, false, $direction);
+ }
+
+ }
+ $textbuffer = array();
+
+/*-- BACKGROUNDS --*/
+ if (!$this->ColActive) {
+ if (isset($content[$i][0]['trgradients']) && ($colctr==1 || $table['borders_separate'])) {
+ $g = $this->grad->parseBackgroundGradient($content[$i][0]['trgradients']);
+ if ($g) {
+ $gx = $x0;
+ $gy = $y;
+ $gh = $h;
+ $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
+ if ($table['borders_separate']) {
+ $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
+ $clx = $x+ ($table['border_spacing_H']/2);
+ $cly = $y+ ($table['border_spacing_V']/2);
+ $clw = $w- $table['border_spacing_H'];
+ $clh = $h- $table['border_spacing_V'];
+ // Set clipping path
+ $s = $this->_setClippingPath($clx, $cly, $clw, $clh); // mPDF 6
+ $this->tableBackgrounds[$level*9+4][] = array('gradient'=>true, 'x'=>$gx + ($table['border_spacing_H']/2), 'y'=>$gy + ($table['border_spacing_V']/2), 'w'=>$gw - $table['border_spacing_V'], 'h'=>$gh - $table['border_spacing_H'], 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>$s);
+ }
+ else {
+ $this->tableBackgrounds[$level*9+4][] = array('gradient'=>true, 'x'=>$gx, 'y'=>$gy, 'w'=>$gw, 'h'=>$gh, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
+ }
+ }
+ }
+
+ if (isset($content[$i][0]['trbackground-images']) && ($colctr==1 || $table['borders_separate'])) {
+ if ($content[$i][0]['trbackground-images']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $content[$i][0]['trbackground-images']['gradient'] )) {
+ $g = $this->grad->parseMozGradient( $content[$i][0]['trbackground-images']['gradient'] );
+ if ($g) {
+ $gx = $x0;
+ $gy = $y;
+ $gh = $h;
+ $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
+ if ($table['borders_separate']) {
+ $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
+ $clx = $x+ ($table['border_spacing_H']/2);
+ $cly = $y+ ($table['border_spacing_V']/2);
+ $clw = $w- $table['border_spacing_H'];
+ $clh = $h- $table['border_spacing_V'];
+ // Set clipping path
+ $s = $this->_setClippingPath($clx, $cly, $clw, $clh); // mPDF 6
+ $this->tableBackgrounds[$level*9+4][] = array('gradient'=>true, 'x'=>$gx + ($table['border_spacing_H']/2), 'y'=>$gy + ($table['border_spacing_V']/2), 'w'=>$gw - $table['border_spacing_V'], 'h'=>$gh - $table['border_spacing_H'], 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>$s);
+ }
+ else {
+ $this->tableBackgrounds[$level*9+4][] = array('gradient'=>true, 'x'=>$gx, 'y'=>$gy, 'w'=>$gw, 'h'=>$gh, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>'');
+ }
+ }
+ }
+ else {
+ $image_id = $content[$i][0]['trbackground-images']['image_id'];
+ $orig_w = $content[$i][0]['trbackground-images']['orig_w'];
+ $orig_h = $content[$i][0]['trbackground-images']['orig_h'];
+ $x_pos = $content[$i][0]['trbackground-images']['x_pos'];
+ $y_pos = $content[$i][0]['trbackground-images']['y_pos'];
+ $x_repeat = $content[$i][0]['trbackground-images']['x_repeat'];
+ $y_repeat = $content[$i][0]['trbackground-images']['y_repeat'];
+ $resize = $content[$i][0]['trbackground-images']['resize'];
+ $opacity = $content[$i][0]['trbackground-images']['opacity'];
+ $itype = $content[$i][0]['trbackground-images']['itype'];
+
+ $clippath = '';
+ $gx = $x0;
+ $gy = $y;
+ $gh = $h;
+ $gw = $table['w'] - ($table['max_cell_border_width']['L']/2) - ($table['max_cell_border_width']['R']/2) - $table['margin']['L'] - $table['margin']['R'];
+ if ($table['borders_separate']) {
+ $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']);
+ $clx = $x+ ($table['border_spacing_H']/2);
+ $cly = $y+ ($table['border_spacing_V']/2);
+ $clw = $w- $table['border_spacing_H'];
+ $clh = $h- $table['border_spacing_V'];
+ // Set clipping path
+ $s = $this->_setClippingPath($clx, $cly, $clw, $clh); // mPDF 6
+ $this->tableBackgrounds[$level*9+5][] = array('x'=>$gx + ($table['border_spacing_H']/2), 'y'=>$gy + ($table['border_spacing_V']/2), 'w'=>$gw - $table['border_spacing_V'], 'h'=>$gh - $table['border_spacing_H'], 'image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'clippath'=>$s, 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$itype);
+ }
+ else {
+ $this->tableBackgrounds[$level*9+5][] = array('x'=>$gx, 'y'=>$gy, 'w'=>$gw, 'h'=>$gh, 'image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'clippath'=>'', 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$itype);
+ }
+ }
+ }
+ }
+/*-- END BACKGROUNDS --*/
+
+ // TABLE BORDER - if separate OR collapsed and only table border
+ if (($table['borders_separate'] || ($this->simpleTables && !$table['simple']['border'])) && $table['border']) {
+ $halfspaceL = $table['padding']['L'] + ($table['border_spacing_H']/2);
+ $halfspaceR = $table['padding']['R'] + ($table['border_spacing_H']/2);
+ $halfspaceT = $table['padding']['T'] + ($table['border_spacing_V']/2);
+ $halfspaceB = $table['padding']['B'] + ($table['border_spacing_V']/2);
+ $tbx = $x;
+ $tby = $y;
+ $tbw = $w;
+ $tbh = $h;
+ $tab_bord = 0;
+ $corner = '';
+ if ($i == $firstrow && $horf=='H') { // Top
+ $tby -= $halfspaceT + ($table['border_details']['T']['w']/2);
+ $tbh += $halfspaceT + ($table['border_details']['T']['w']/2);
+ $this->setBorder($tab_bord , _BORDER_TOP);
+ $corner .= 'T';
+ }
+ if (($i == ($lastrow) || (isset($tablehf['rowspan']) && ($i+$tablehf['rowspan']) == ($lastrow+1))) && $horf=='F') { // Bottom
+ $tbh += $halfspaceB + ($table['border_details']['B']['w']/2);
+ $this->setBorder($tab_bord , _BORDER_BOTTOM);
+ $corner .= 'B';
+ }
+ if ($colctr == 1 && $firstSpread) { // Left
+ $tbx -= $halfspaceL + ($table['border_details']['L']['w']/2);
+ $tbw += $halfspaceL + ($table['border_details']['L']['w']/2);
+ $this->setBorder($tab_bord , _BORDER_LEFT);
+ $corner .= 'L';
+ }
+ if ($colctr == count($content[$i]) && $finalSpread) { // Right
+ $tbw += $halfspaceR + ($table['border_details']['R']['w']/2);
+ $this->setBorder($tab_bord , _BORDER_RIGHT);
+ $corner .= 'R';
+ }
+ $this->_tableRect($tbx, $tby, $tbw, $tbh, $tab_bord , $table['border_details'], false, $table['borders_separate'], 'table', $corner, $table['border_spacing_V'], $table['border_spacing_H'] );
+ }
+
+
+ }// end column $content
+ $this->y = $y + $h; //Update y coordinate
+ }// end row $i
+ unset($table );
+ $this->colsums = array();
+ }
+}
+/*-- END TABLES --*/
+
+
+function SetHTMLHeader($header='',$OE='',$write=false) {
+
+ $height = 0;
+ if (is_array($header) && isset($header['html']) && $header['html']) {
+ $Hhtml = $header['html'];
+ if ($this->setAutoTopMargin) {
+ if (isset($header['h'])) { $height = $header['h']; }
+ else { $height = $this->_gethtmlheight($Hhtml); }
+ }
+ }
+ else if (!is_array($header) && $header) {
+ $Hhtml = $header;
+ if ($this->setAutoTopMargin) { $height = $this->_gethtmlheight($Hhtml); }
+ }
+ else { $Hhtml = ''; }
+
+ if ($OE != 'E') { $OE = 'O'; }
+ if ($OE == 'E') {
+
+ if ($Hhtml) {
+ $this->HTMLHeaderE['html'] = $Hhtml;
+ $this->HTMLHeaderE['h'] = $height;
+ }
+ else { $this->HTMLHeaderE = ''; }
+ }
+ else {
+
+ if ($Hhtml) {
+ $this->HTMLHeader['html'] = $Hhtml;
+ $this->HTMLHeader['h'] = $height;
+ }
+ else { $this->HTMLHeader = ''; }
+ }
+ if (!$this->mirrorMargins && $OE == 'E') { return; }
+ if ($Hhtml=='') { return; }
+
+ if ($this->setAutoTopMargin=='pad') {
+ $this->tMargin = $this->margin_header + $height + $this->orig_tMargin;
+ if (isset($this->saveHTMLHeader[$this->page][$OE]['mt'])) { $this->saveHTMLHeader[$this->page][$OE]['mt'] = $this->tMargin; }
+ }
+ else if ($this->setAutoTopMargin=='stretch') {
+ $this->tMargin = max($this->orig_tMargin, $this->margin_header + $height + $this->autoMarginPadding);
+ if (isset($this->saveHTMLHeader[$this->page][$OE]['mt'])) { $this->saveHTMLHeader[$this->page][$OE]['mt'] = $this->tMargin; }
+ }
+ if ($write && $this->state!=0 && (($this->mirrorMargins && $OE == 'E' && ($this->page)%2==0) || ($this->mirrorMargins && $OE != 'E' && ($this->page)%2==1) || !$this->mirrorMargins)) { $this->writeHTMLHeaders(); }
+}
+
+function SetHTMLFooter($footer='',$OE='') {
+ $height = 0;
+ if (is_array($footer) && isset($footer['html']) && $footer['html']) {
+ $Fhtml = $footer['html'];
+ if ($this->setAutoBottomMargin) {
+ if (isset($footer['h'])) { $height = $footer['h']; }
+ else { $height = $this->_gethtmlheight($Fhtml); }
+ }
+ }
+ else if (!is_array($footer) && $footer) {
+ $Fhtml = $footer;
+ if ($this->setAutoBottomMargin) { $height = $this->_gethtmlheight($Fhtml); }
+ }
+ else { $Fhtml = ''; }
+
+ if ($OE != 'E') { $OE = 'O'; }
+ if ($OE == 'E') {
+
+ if ($Fhtml) {
+ $this->HTMLFooterE['html'] = $Fhtml;
+ $this->HTMLFooterE['h'] = $height;
+ }
+ else { $this->HTMLFooterE = ''; }
+ }
+ else {
+
+ if ($Fhtml) {
+ $this->HTMLFooter['html'] = $Fhtml;
+ $this->HTMLFooter['h'] = $height;
+ }
+ else { $this->HTMLFooter = ''; }
+ }
+ if (!$this->mirrorMargins && $OE == 'E') { return; }
+ if ($Fhtml=='') { return false; }
+
+ if ($this->setAutoBottomMargin=='pad') {
+ $this->bMargin = $this->margin_footer + $height + $this->orig_bMargin;
+ $this->PageBreakTrigger=$this->h-$this->bMargin ;
+ if (isset($this->saveHTMLHeader[$this->page][$OE]['mb'])) { $this->saveHTMLHeader[$this->page][$OE]['mb'] = $this->bMargin; }
+ }
+ else if ($this->setAutoBottomMargin=='stretch') {
+ $this->bMargin = max($this->orig_bMargin, $this->margin_footer + $height + $this->autoMarginPadding);
+ $this->PageBreakTrigger=$this->h-$this->bMargin ;
+ if (isset($this->saveHTMLHeader[$this->page][$OE]['mb'])) { $this->saveHTMLHeader[$this->page][$OE]['mb'] = $this->bMargin; }
+ }
+}
+
+
+function _getHtmlHeight($html) {
+ $save_state = $this->state;
+ if($this->state==0) {
+ $this->AddPage($this->CurOrientation);
+ }
+ $this->state = 2;
+ $this->Reset();
+ $this->pageoutput[$this->page] = array();
+ $save_x = $this->x;
+ $save_y = $this->y;
+ $this->x = $this->lMargin;
+ $this->y = $this->margin_header;
+ $html = str_replace('{PAGENO}',$this->pagenumPrefix.$this->docPageNum($this->page).$this->pagenumSuffix,$html);
+ $html = str_replace($this->aliasNbPgGp,$this->nbpgPrefix.$this->docPageNumTotal($this->page).$this->nbpgSuffix,$html );
+ $html = str_replace($this->aliasNbPg,$this->page,$html );
+ $html = preg_replace_callback('/\{DATE\s+(.*?)\}/', array($this, 'date_callback'),$html ); // mPDF 5.7
+ $this->HTMLheaderPageLinks = array();
+ $this->HTMLheaderPageAnnots = array();
+ $this->HTMLheaderPageForms = array();
+ $savepb = $this->pageBackgrounds;
+ $this->writingHTMLheader = true;
+ $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
+ $this->writingHTMLheader = false;
+ $h = ($this->y - $this->margin_header);
+ $this->Reset();
+ // mPDF 5.7.2 - Clear in case Float used in Header/Footer
+ $this->blk[0]['blockContext'] = 0;
+ $this->blk[0]['float_endpos'] = 0;
+
+ $this->pageoutput[$this->page] = array();
+ $this->headerbuffer = '';
+ $this->pageBackgrounds = $savepb;
+ $this->x = $save_x;
+ $this->y = $save_y;
+ $this->state = $save_state;
+ if($save_state==0) {
+ unset($this->pages[1]);
+ $this->page = 0;
+ }
+ return $h;
+}
+
+
+// Called internally from Header
+function writeHTMLHeaders() {
+
+ if ($this->mirrorMargins && ($this->page)%2==0) { $OE = 'E'; } // EVEN
+ else { $OE = 'O'; }
+ if ($OE == 'E') {
+ $this->saveHTMLHeader[$this->page][$OE]['html'] = $this->HTMLHeaderE['html'] ;
+ }
+ else {
+ $this->saveHTMLHeader[$this->page][$OE]['html'] = $this->HTMLHeader['html'] ;
+ }
+ if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
+ $this->saveHTMLHeader[$this->page][$OE]['rotate'] = true;
+ $this->saveHTMLHeader[$this->page][$OE]['ml'] = $this->tMargin;
+ $this->saveHTMLHeader[$this->page][$OE]['mr'] = $this->bMargin;
+ $this->saveHTMLHeader[$this->page][$OE]['mh'] = $this->margin_header;
+ $this->saveHTMLHeader[$this->page][$OE]['mf'] = $this->margin_footer;
+ $this->saveHTMLHeader[$this->page][$OE]['pw'] = $this->h;
+ $this->saveHTMLHeader[$this->page][$OE]['ph'] = $this->w;
+ }
+ else {
+ $this->saveHTMLHeader[$this->page][$OE]['ml'] = $this->lMargin;
+ $this->saveHTMLHeader[$this->page][$OE]['mr'] = $this->rMargin;
+ $this->saveHTMLHeader[$this->page][$OE]['mh'] = $this->margin_header;
+ $this->saveHTMLHeader[$this->page][$OE]['mf'] = $this->margin_footer;
+ $this->saveHTMLHeader[$this->page][$OE]['pw'] = $this->w;
+ $this->saveHTMLHeader[$this->page][$OE]['ph'] = $this->h;
+ }
+}
+
+function writeHTMLFooters() {
+
+ if ($this->mirrorMargins && ($this->page)%2==0) { $OE = 'E'; } // EVEN
+ else { $OE = 'O'; }
+ if ($OE == 'E') {
+ $this->saveHTMLFooter[$this->page][$OE]['html'] = $this->HTMLFooterE['html'] ;
+ }
+ else {
+ $this->saveHTMLFooter[$this->page][$OE]['html'] = $this->HTMLFooter['html'] ;
+ }
+ if ($this->forcePortraitHeaders && $this->CurOrientation=='L' && $this->CurOrientation!=$this->DefOrientation) {
+ $this->saveHTMLFooter[$this->page][$OE]['rotate'] = true;
+ $this->saveHTMLFooter[$this->page][$OE]['ml'] = $this->tMargin;
+ $this->saveHTMLFooter[$this->page][$OE]['mr'] = $this->bMargin;
+ $this->saveHTMLFooter[$this->page][$OE]['mt'] = $this->rMargin;
+ $this->saveHTMLFooter[$this->page][$OE]['mb'] = $this->lMargin;
+ $this->saveHTMLFooter[$this->page][$OE]['mh'] = $this->margin_header;
+ $this->saveHTMLFooter[$this->page][$OE]['mf'] = $this->margin_footer;
+ $this->saveHTMLFooter[$this->page][$OE]['pw'] = $this->h;
+ $this->saveHTMLFooter[$this->page][$OE]['ph'] = $this->w;
+ }
+ else {
+ $this->saveHTMLFooter[$this->page][$OE]['ml'] = $this->lMargin;
+ $this->saveHTMLFooter[$this->page][$OE]['mr'] = $this->rMargin;
+ $this->saveHTMLFooter[$this->page][$OE]['mt'] = $this->tMargin;
+ $this->saveHTMLFooter[$this->page][$OE]['mb'] = $this->bMargin;
+ $this->saveHTMLFooter[$this->page][$OE]['mh'] = $this->margin_header;
+ $this->saveHTMLFooter[$this->page][$OE]['mf'] = $this->margin_footer;
+ $this->saveHTMLFooter[$this->page][$OE]['pw'] = $this->w;
+ $this->saveHTMLFooter[$this->page][$OE]['ph'] = $this->h;
+ }
+}
+
+// mPDF 6
+function _shareHeaderFooterWidth($cl,$cc,$cr) { // mPDF 6
+ $l = mb_strlen($cl, 'UTF-8');
+ $c = mb_strlen($cc, 'UTF-8');
+ $r = mb_strlen($cr, 'UTF-8');
+ $s = max($l,$r);
+ $tw = $c + 2*$s;
+ if ($tw > 0) { return array(intval($s*100/$tw), intval($c*100/$tw), intval($s*100/$tw)); }
+ else { return array(33,33,33); }
+}
+
+// mPDF 6
+// Create an HTML header/footer from array (non-HTML header/footer)
+function _createHTMLheaderFooter($arr,$hf) {
+ $lContent = (isset($arr['L']['content']) ? $arr['L']['content'] : '');
+ $cContent = (isset($arr['C']['content']) ? $arr['C']['content'] : '');
+ $rContent = (isset($arr['R']['content']) ? $arr['R']['content'] : '');
+ list($lw, $cw, $rw) = $this->_shareHeaderFooterWidth($lContent, $cContent, $rContent);
+ if ($hf=='H') { $valign = 'bottom'; $vpadding = '0 0 '.$this->header_line_spacing.'em 0'; }
+ else { $valign = 'top'; $vpadding = ''.$this->footer_line_spacing.'em 0 0 0'; }
+ if ($this->directionality == 'rtl') { // table columns get reversed so need different text-alignment
+ $talignL = 'right';
+ $talignR = 'left';
+ }
+ else {
+ $talignL = 'left';
+ $talignR = 'right';
+ }
+ $html = '';
+ $html .= '';
+ $html .= '| '. $lContent .' | ';
+ $html .= ''. $cContent .' | ';
+ $html .= ''. $rContent .' | ';
+ $html .= ' ';
+ return $html;
+}
+
+function DefHeaderByName($name,$arr) {
+ if (!$name) { $name = '_nonhtmldefault'; }
+ $html = $this->_createHTMLheaderFooter($arr,'H');
+
+ $this->pageHTMLheaders[$name]['html'] = $html;
+ $this->pageHTMLheaders[$name]['h'] = $this->_gethtmlheight($html);
+}
+
+function DefFooterByName($name,$arr) {
+ if (!$name) { $name = '_nonhtmldefault'; }
+ $html = $this->_createHTMLheaderFooter($arr,'F');
+
+ $this->pageHTMLfooters[$name]['html'] = $html;
+ $this->pageHTMLfooters[$name]['h'] = $this->_gethtmlheight($html);
+}
+
+function SetHeaderByName($name,$side='O',$write=false) {
+ if (!$name) { $name = '_nonhtmldefault'; }
+ $this->SetHTMLHeader($this->pageHTMLheaders[$name],$side,$write);
+}
+
+function SetFooterByName($name,$side='O') {
+ if (!$name) { $name = '_nonhtmldefault'; }
+ $this->SetHTMLFooter($this->pageHTMLfooters[$name],$side);
+}
+
+
+function DefHTMLHeaderByName($name,$html) {
+ if (!$name) { $name = '_default'; }
+
+ $this->pageHTMLheaders[$name]['html'] = $html;
+ $this->pageHTMLheaders[$name]['h'] = $this->_gethtmlheight($html);
+}
+
+function DefHTMLFooterByName($name,$html) {
+ if (!$name) { $name = '_default'; }
+
+ $this->pageHTMLfooters[$name]['html'] = $html;
+ $this->pageHTMLfooters[$name]['h'] = $this->_gethtmlheight($html);
+}
+
+function SetHTMLHeaderByName($name,$side='O',$write=false) {
+ if (!$name) { $name = '_default'; }
+ $this->SetHTMLHeader($this->pageHTMLheaders[$name],$side,$write);
+}
+
+function SetHTMLFooterByName($name,$side='O') {
+ if (!$name) { $name = '_default'; }
+ $this->SetHTMLFooter($this->pageHTMLfooters[$name],$side);
+}
+
+
+
+function SetHeader($Harray=array(),$side='',$write=false) {
+ $oddhtml = '';
+ $evenhtml = '';
+ if (is_string($Harray)) {
+ if (strlen($Harray)==0) {
+ $oddhtml = '';
+ $evenhtml = '';
+ }
+ else if (strpos($Harray,'|') !== false) {
+ $hdet = explode('|',$Harray);
+ list($lw, $cw, $rw) = $this->_shareHeaderFooterWidth($hdet[0], $hdet[1], $hdet[2]);
+ $oddhtml = '';
+ $oddhtml .= '';
+ $oddhtml .= '| '. $hdet[0] .' | ';
+ $oddhtml .= ''. $hdet[1] .' | ';
+ $oddhtml .= ''. $hdet[2] .' | ';
+ $oddhtml .= ' ';
+
+ $evenhtml = '';
+ $evenhtml .= '';
+ $evenhtml .= '| '. $hdet[2] .' | ';
+ $evenhtml .= ''. $hdet[1] .' | ';
+ $evenhtml .= ''. $hdet[0] .' | ';
+ $evenhtml .= ' ';
+
+ }
+ else {
+ $oddhtml = ''. $Harray .' ';
+
+ $evenhtml = ''. $Harray .' ';
+
+ }
+ }
+ else if (is_array($Harray) && !empty($Harray)) {
+ if ($side=='O') { $odd = $Harray; }
+ else if ($side=='E') { $even = $Harray; }
+ else {
+ $odd = $Harray['odd'];
+ $even = $Harray['even'];
+ }
+ $oddhtml = $this->_createHTMLheaderFooter($odd,'H');
+
+ $evenhtml = $this->_createHTMLheaderFooter($even,'H');
+ }
+
+ if ($side=='E') { $this->SetHTMLHeader($evenhtml ,'E', $write); }
+ else if ($side=='O') { $this->SetHTMLHeader($oddhtml ,'O', $write); }
+ else {
+ $this->SetHTMLHeader($oddhtml ,'O', $write);
+ $this->SetHTMLHeader($evenhtml ,'E', $write);
+ }
+
+}
+
+
+
+function SetFooter($Farray=array(),$side='') {
+ $oddhtml = '';
+ $evenhtml = '';
+ if (is_string($Farray)) {
+ if (strlen($Farray)==0) {
+ $oddhtml = '';
+ $evenhtml = '';
+ }
+ else if (strpos($Farray,'|') !== false) {
+ $hdet = explode('|',$Farray);
+ $oddhtml = '';
+ $oddhtml .= '';
+ $oddhtml .= '| '. $hdet[0] .' | ';
+ $oddhtml .= ''. $hdet[1] .' | ';
+ $oddhtml .= ''. $hdet[2] .' | ';
+ $oddhtml .= ' ';
+
+ $evenhtml = '';
+ $evenhtml .= '';
+ $evenhtml .= '| '. $hdet[2] .' | ';
+ $evenhtml .= ''. $hdet[1] .' | ';
+ $evenhtml .= ''. $hdet[0] .' | ';
+ $evenhtml .= ' ';
+
+ }
+ else {
+ $oddhtml = ''. $Farray .' ';
+
+ $evenhtml = ''. $Farray .' ';
+
+ }
+ }
+ else if (is_array($Farray)) {
+ if ($side=='O') { $odd = $Farray; }
+ else if ($side=='E') { $even = $Farray; }
+ else {
+ if (isset($Farray['odd'])) $odd = $Farray['odd'];
+ if (isset($Farray['even'])) $even = $Farray['even'];
+ }
+
+ if (isset($odd)) $oddhtml = $this->_createHTMLheaderFooter($odd,'F');
+
+ if (isset($even)) $evenhtml = $this->_createHTMLheaderFooter($even,'F');
+
+ }
+/*-- HTMLfooterS-FOOTERS --*/
+ if ($side=='E') { $this->SetHTMLfooter($evenhtml ,'E'); }
+ else if ($side=='O') { $this->SetHTMLfooter($oddhtml ,'O'); }
+ else {
+ $this->SetHTMLfooter($oddhtml ,'O');
+ $this->SetHTMLfooter($evenhtml ,'E');
+ }
+/*-- END HTMLfooterS-FOOTERS --*/
+}
+
+/*-- WATERMARK --*/
+function SetWatermarkText($txt='', $alpha=-1) {
+ if ($alpha>=0) $this->watermarkTextAlpha = $alpha;
+ $this->watermarkText = $txt;
+}
+
+function SetWatermarkImage($src, $alpha=-1, $size='D', $pos='F') {
+ if ($alpha>=0) $this->watermarkImageAlpha = $alpha;
+ $this->watermarkImage = $src;
+ $this->watermark_size = $size;
+ $this->watermark_pos = $pos;
+}
+/*-- END WATERMARK --*/
+
+
+//Page footer
+function Footer() {
+/*-- CSS-PAGE --*/
+ // PAGED MEDIA - CROP / CROSS MARKS from @PAGE
+ if ($this->show_marks == 'CROP' || $this->show_marks == 'CROPCROSS') {
+ // Show TICK MARKS
+ $this->SetLineWidth(0.1); // = 0.1 mm
+ $this->SetDColor($this->ConvertColor(0));
+ $l = $this->cropMarkLength;
+ $m = $this->cropMarkMargin; // Distance of crop mark from margin
+ $b = $this->nonPrintMargin; // Non-printable border at edge of paper sheet
+ $ax1 = $b;
+ $bx = $this->page_box['outer_width_LR'] - $m;
+ $ax = max($ax1, $bx-$l);
+ $cx1 = $this->w - $b;
+ $dx = $this->w - $this->page_box['outer_width_LR'] + $m;
+ $cx = min($cx1, $dx+$l);
+ $ay1 = $b;
+ $by = $this->page_box['outer_width_TB'] - $m;
+ $ay = max($ay1, $by-$l);
+ $cy1 = $this->h - $b;
+ $dy = $this->h - $this->page_box['outer_width_TB'] + $m;
+ $cy = min($cy1, $dy+$l);
+
+ $this->Line($ax, $this->page_box['outer_width_TB'], $bx, $this->page_box['outer_width_TB']);
+ $this->Line($cx, $this->page_box['outer_width_TB'], $dx, $this->page_box['outer_width_TB']);
+ $this->Line($ax, $this->h - $this->page_box['outer_width_TB'], $bx, $this->h - $this->page_box['outer_width_TB']);
+ $this->Line($cx, $this->h - $this->page_box['outer_width_TB'], $dx, $this->h - $this->page_box['outer_width_TB']);
+ $this->Line($this->page_box['outer_width_LR'], $ay, $this->page_box['outer_width_LR'], $by);
+ $this->Line($this->page_box['outer_width_LR'], $cy, $this->page_box['outer_width_LR'], $dy);
+ $this->Line($this->w - $this->page_box['outer_width_LR'], $ay, $this->w - $this->page_box['outer_width_LR'], $by);
+ $this->Line($this->w - $this->page_box['outer_width_LR'], $cy, $this->w - $this->page_box['outer_width_LR'], $dy);
+
+ if ($this->printers_info) {
+ $hd = date('Y-m-d H:i').' Page '.$this->page.' of {nb}';
+ $this->SetTColor($this->ConvertColor(0));
+ $this->SetFont('arial','',7.5,true,true);
+ $this->x = $this->page_box['outer_width_LR'] + 1.5;
+ $this->y = 1;
+ $this->Cell($headerpgwidth ,$this->FontSize,$hd,0,0,'L',0,'',0,0,0,'M');
+ $this->SetFont($this->default_font,'',$this->original_default_font_size);
+ }
+
+ }
+ if ($this->show_marks == 'CROSS' || $this->show_marks == 'CROPCROSS') {
+ $this->SetLineWidth(0.1); // = 0.1 mm
+ $this->SetDColor($this->ConvertColor(0));
+ $l = 14 /2; // longer length of the cross line (half)
+ $w = 6 /2; // shorter width of the cross line (half)
+ $r = 1.2; // radius of circle
+ $m = $this->crossMarkMargin; // Distance of cross mark from margin
+ $x1 = $this->page_box['outer_width_LR'] - $m;
+ $x2 = $this->w - $this->page_box['outer_width_LR'] + $m;
+ $y1 = $this->page_box['outer_width_TB'] - $m;
+ $y2 = $this->h - $this->page_box['outer_width_TB'] + $m;
+ // Left
+ $this->Circle($x1, $this->h/2, $r, 'S') ;
+ $this->Line($x1-$w, $this->h/2, $x1+$w, $this->h/2);
+ $this->Line($x1, $this->h/2-$l, $x1, $this->h/2+$l);
+ // Right
+ $this->Circle($x2, $this->h/2, $r, 'S') ;
+ $this->Line($x2-$w, $this->h/2, $x2+$w, $this->h/2);
+ $this->Line($x2, $this->h/2-$l, $x2, $this->h/2+$l);
+ // Top
+ $this->Circle($this->w/2, $y1, $r, 'S') ;
+ $this->Line($this->w/2, $y1-$w, $this->w/2, $y1+$w);
+ $this->Line($this->w/2-$l, $y1, $this->w/2+$l, $y1);
+ // Bottom
+ $this->Circle($this->w/2, $y2, $r, 'S') ;
+ $this->Line($this->w/2, $y2-$w, $this->w/2, $y2+$w);
+ $this->Line($this->w/2-$l, $y2, $this->w/2+$l, $y2);
+ }
+
+/*-- END CSS-PAGE --*/
+
+ // mPDF 6
+ // If @page set non-HTML headers/footers named, they were not read until later in the HTML code - so now set them
+ if ($this->page==1) {
+ if ($this->firstPageBoxHeader) {
+ if (isset($this->pageHTMLheaders[$this->firstPageBoxHeader])) { $this->HTMLHeader = $this->pageHTMLheaders[$this->firstPageBoxHeader]; }
+ $this->Header();
+ }
+ if ($this->firstPageBoxFooter) {
+ if (isset($this->pageHTMLfooters[$this->firstPageBoxFooter])) { $this->HTMLFooter = $this->pageHTMLfooters[$this->firstPageBoxFooter]; }
+ }
+ $this->firstPageBoxHeader='';
+ $this->firstPageBoxFooter='';
+ }
+
+
+ if (($this->mirrorMargins && ($this->page%2==0) && $this->HTMLFooterE) || ($this->mirrorMargins && ($this->page%2==1) && $this->HTMLFooter) || (!$this->mirrorMargins && $this->HTMLFooter)) {
+ $this->writeHTMLFooters();
+ }
+
+/*-- WATERMARK --*/
+ if (($this->watermarkText) && ($this->showWatermarkText)) {
+ $this->watermark( $this->watermarkText, 45, 120, $this->watermarkTextAlpha); // Watermark text
+ }
+ if (($this->watermarkImage) && ($this->showWatermarkImage)) {
+ $this->watermarkImg( $this->watermarkImage, $this->watermarkImageAlpha); // Watermark image
+ }
+/*-- END WATERMARK --*/
+
+}
+
+
+/*-- HYPHENATION --*/
+///////////////////
+///////////////////
+// HYPHENATION
+///////////////////
+///////////////////
+// Word hyphenation
+// mPDF 6
+function hyphenateWord($word, $currptr) {
+ // Do everything inside this function in utf-8
+ // Don't hyphenate web addresses
+ if (preg_match('/^(http:|www\.)/',$word)) { return -1; }
+
+ $ptr = -1;
+
+ // Get dictionary
+ if (!$this->loadedSHYdictionary) {
+ if (file_exists(_MPDF_PATH.'patterns/dictionary.txt')) {
+ $this->SHYdictionary = file(_MPDF_PATH.'patterns/dictionary.txt',FILE_SKIP_EMPTY_LINES);
+ foreach($this->SHYdictionary as $entry) {
+ $entry = trim($entry);
+ $poss = array();
+ $offset = 0;
+ $p = true;
+ $wl = mb_strlen($entry ,'UTF-8');
+ while($offset < $wl) {
+ $p = mb_strpos($entry, '/', $offset, 'UTF-8');
+ if ($p !== false) { $poss[] = $p - count($poss); }
+ else { break; }
+ $offset = $p+1;
+ }
+ if (count($poss)) { $this->SHYdictionaryWords[str_replace('/', '', mb_strtolower($entry))] = $poss; }
+ }
+ }
+ $this->loadedSHYdictionary = true;
+ }
+
+ if (!in_array($this->SHYlang,$this->SHYlanguages)) { return -1; }
+ // If no pattern loaded or not the best one
+ if (count($this->SHYpatterns) < 1 || ($this->loadedSHYpatterns && $this->loadedSHYpatterns != $this->SHYlang)) {
+ include(_MPDF_PATH."patterns/" . $this->SHYlang . ".php");
+ $patterns = explode(' ', $patterns);
+ $new_patterns = array();
+ for($i = 0; $i < count($patterns); $i++) {
+ $value = $patterns[$i];
+ $new_patterns[preg_replace('/[0-9]/', '', $value)] = $value;
+ }
+ $this->SHYpatterns = $new_patterns;
+ $this->loadedSHYpatterns = $this->SHYlang;
+ }
+
+ if ($this->usingCoreFont) { $word = mb_convert_encoding($word,'UTF-8',$this->mb_enc); }
+
+ $prepre = '';
+ $postpost = '';
+ $startpunctuation = "\xc2\xab\xc2\xbf\xe2\x80\x98\xe2\x80\x9b\xe2\x80\x9c\xe2\x80\x9f";
+ $endpunctuation = "\xe2\x80\x9e\xe2\x80\x9d\xe2\x80\x9a\xe2\x80\x99\xc2\xbb";
+
+
+ if (preg_match('/^(["\''.$startpunctuation .'])+(.{'.$this->SHYcharmin.',})$/u',$word,$m)) {
+ $prepre = $m[1];
+ $word = $m[2];
+ }
+ if (preg_match('/^(.{'.$this->SHYcharmin.',})([\'\.,;:!?"'.$endpunctuation .']+)$/u',$word,$m)) {
+ $word = $m[1];
+ $postpost = $m[2];
+ }
+ if(mb_strlen($word,'UTF-8') < $this->SHYcharmin) {
+ return -1;
+ }
+ $success = false;
+
+ $preprelen = mb_strlen($prepre);
+
+ if(isset($this->SHYdictionaryWords[mb_strtolower($word)])) {
+ foreach($this->SHYdictionaryWords[mb_strtolower($word)] AS $i) {
+ if (($i+$preprelen) >= $currptr) { break ; }
+ $ptr = $i+$preprelen;
+ $success = true;
+ }
+ }
+
+ if (!$success) {
+ $text_word = '_' . $word . '_';
+ $word_length = mb_strlen($text_word,'UTF-8');
+ $text_word = mb_strtolower($text_word,'UTF-8');
+ $hyphenated_word = array();
+ $numb3rs = array('0' => true, '1' => true, '2' => true, '3' => true, '4' => true, '5' => true, '6' => true, '7' => true, '8' => true, '9' => true);
+ for($position = 0; $position <= ($word_length - $this->SHYcharmin); $position++) {
+ $maxwins = min(($word_length - $position), $this->SHYcharmax);
+ for($win = $this->SHYcharmin; $win <= $maxwins; $win++) {
+ if(isset($this->SHYpatterns[mb_substr($text_word, $position, $win,'UTF-8')])) {
+ $pattern = $this->SHYpatterns[mb_substr($text_word, $position, $win,'UTF-8')];
+ $digits = 1;
+ $pattern_length = mb_strlen($pattern,'UTF-8');
+ for($i = 0; $i < $pattern_length; $i++) {
+ $char = $pattern[$i];
+ if(isset($numb3rs[$char])) {
+ $zero = ($i == 0) ? $position - 1 : $position + $i - $digits;
+ if(!isset($hyphenated_word[$zero]) || $hyphenated_word[$zero] != $char) $hyphenated_word[$zero] = $char;
+ $digits++;
+ }
+ }
+ }
+ }
+ }
+ for($i = $this->SHYleftmin; $i <= (mb_strlen($word,'UTF-8') - $this->SHYrightmin); $i++) {
+ if(isset($hyphenated_word[$i]) && $hyphenated_word[$i] % 2 != 0) {
+ if (($i+$preprelen) > $currptr) { break ; }
+ $ptr = $i+$preprelen;
+ }
+ }
+ }
+ return $ptr;
+
+}
+/*-- END HYPHENATION --*/
+
+
+/*-- HTML-CSS --*/
+///////////////////
+/// HTML parser ///
+///////////////////
+function WriteHTML($html,$sub=0,$init=true,$close=true) {
+ // $sub - 0 = default; 1=headerCSS only; 2=HTML body (parts) only; 3 - HTML parses only
+ // 4 - writes HTML headers/Fixed pos DIVs - stores in buffer - for single page only
+ // $close - if false Leaves buffers etc. in current state, so that it can continue a block etc.
+ // $init - Clears and sets buffers to Top level block etc.
+
+ if (empty($html)) { $html = ''; }
+ if ($this->progressBar) { $this->UpdateProgressBar(1,0,'Parsing CSS & Headers'); } // *PROGRESS-BAR*
+
+ if ($init) {
+ $this->headerbuffer='';
+ $this->textbuffer = array();
+ $this->fixedPosBlockSave = array();
+ }
+ if ($sub == 1) { $html = ''; } // stylesheet only
+
+ if ($this->allow_charset_conversion) {
+ if ($sub < 1) {
+ $this->ReadCharset($html);
+ }
+ if ($this->charset_in && $sub!=4) {
+ $success = iconv($this->charset_in,'UTF-8//TRANSLIT',$html);
+ if ($success) { $html = $success; }
+ }
+ }
+ $html = $this->purify_utf8($html,false);
+ if ($init) {
+ $this->blklvl = 0;
+ $this->lastblocklevelchange = 0;
+ $this->blk = array();
+ $this->initialiseBlock($this->blk[0]);
+ $this->blk[0]['width'] =& $this->pgwidth;
+ $this->blk[0]['inner_width'] =& $this->pgwidth;
+ $this->blk[0]['blockContext'] = $this->blockContext;
+ }
+
+ $zproperties = array();
+ if ($sub < 2) {
+ $this->ReadMetaTags($html);
+
+ if (preg_match('/]*href=["\']([^"\'>]*)["\']/i', $html, $m)) {
+ $this->SetBasePath($m[1]);
+ }
+ $html = $this->cssmgr->ReadCSS($html);
+
+ if ($this->autoLangToFont && !$this->usingCoreFont && preg_match('/]*lang=[\'\"](.*?)[\'\"]/ism',$html,$m)) {
+ $html_lang = $m[1];
+ }
+
+ if (preg_match('/]*dir=[\'\"]\s*rtl\s*[\'\"]/ism',$html)) {
+ $zproperties['DIRECTION'] = 'rtl';
+ }
+
+ // allow in-line CSS for body tag to be parsed // Get tag inline CSS
+ if (preg_match('/]*)>(.*?)<\/body>/ism',$html,$m) || preg_match('/]*)>(.*)$/ism',$html,$m)) {
+ $html = $m[2];
+ // Changed to allow style="background: url('bg.jpg')"
+ if (preg_match('/style=[\"](.*?)[\"]/ism',$m[1],$mm) || preg_match('/style=[\'](.*?)[\']/ism',$m[1],$mm)) {
+ $zproperties = $this->cssmgr->readInlineCSS($mm[1]);
+ }
+ if (preg_match('/dir=[\'\"]\s*rtl\s*[\'\"]/ism',$m[1])) {
+ $zproperties['DIRECTION'] = 'rtl';
+ }
+ if (isset($html_lang) && $html_lang) { $zproperties['LANG'] = $html_lang; }
+ if ($this->autoLangToFont && !$this->onlyCoreFonts && preg_match('/lang=[\'\"](.*?)[\'\"]/ism',$m[1],$mm)) {
+ $zproperties['LANG'] = $mm[1];
+ }
+
+ }
+ }
+ $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
+ if ($zproperties) { $properties = $this->cssmgr->array_merge_recursive_unique($properties,$zproperties); }
+
+ if (isset($properties['DIRECTION']) && $properties['DIRECTION']) {
+ $this->cssmgr->CSS['BODY']['DIRECTION'] = $properties['DIRECTION'];
+ }
+ if (!isset($this->cssmgr->CSS['BODY']['DIRECTION'])) {
+ $this->cssmgr->CSS['BODY']['DIRECTION'] = $this->directionality;
+ }
+ else { $this->SetDirectionality($this->cssmgr->CSS['BODY']['DIRECTION']); }
+
+ $this->setCSS($properties,'','BODY');
+
+ $this->blk[0]['InlineProperties'] = $this->saveInlineProperties();
+
+ if ($sub == 1) { return ''; }
+ if (!isset($this->cssmgr->CSS['BODY'])) { $this->cssmgr->CSS['BODY'] = array(); }
+
+/*-- BACKGROUNDS --*/
+ if (isset($properties['BACKGROUND-GRADIENT'])) {
+ $this->bodyBackgroundGradient = $properties['BACKGROUND-GRADIENT'];
+ }
+
+ if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE']) {
+ $ret = $this->SetBackground($properties, $this->pgwidth);
+ if ($ret) { $this->bodyBackgroundImage = $ret; }
+ }
+/*-- END BACKGROUNDS --*/
+
+/*-- CSS-PAGE --*/
+ // If page-box is set
+ if ($this->state==0 && ((isset($this->cssmgr->CSS['@PAGE']) && $this->cssmgr->CSS['@PAGE']) || (isset($this->cssmgr->CSS['@PAGE>>PSEUDO>>FIRST']) && $this->cssmgr->CSS['@PAGE>>PSEUDO>>FIRST'])) ) { // mPDF 5.7.3
+ $this->page_box['current'] = '';
+ $this->page_box['using'] = true;
+ list($pborientation,$pbmgl,$pbmgr,$pbmgt,$pbmgb,$pbmgh,$pbmgf,$hname,$fname,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat) = $this->SetPagedMediaCSS('', false, 'O');
+ $this->DefOrientation = $this->CurOrientation = $pborientation;
+ $this->orig_lMargin = $this->DeflMargin = $pbmgl;
+ $this->orig_rMargin = $this->DefrMargin = $pbmgr;
+ $this->orig_tMargin = $this->tMargin = $pbmgt;
+ $this->orig_bMargin = $this->bMargin = $pbmgb;
+ $this->orig_hMargin = $this->margin_header = $pbmgh;
+ $this->orig_fMargin = $this->margin_footer = $pbmgf;
+ list($pborientation,$pbmgl,$pbmgr,$pbmgt,$pbmgb,$pbmgh,$pbmgf,$hname,$fname,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat) = $this->SetPagedMediaCSS('', true, 'O'); // first page
+ $this->show_marks = $marks;
+ if ($hname) $this->firstPageBoxHeader = $hname;
+ if ($fname) $this->firstPageBoxFooter = $fname;
+ }
+/*-- END CSS-PAGE --*/
+
+ $parseonly = false;
+ $this->bufferoutput = false;
+ if ($sub == 3) {
+ $parseonly = true;
+ // Close any open block tags
+ $arr=array();
+ $ai=0;
+ for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag'],$arr,$ai); }
+ // Output any text left in buffer
+ if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); }
+ $this->textbuffer=array();
+ }
+ else if ($sub == 4) {
+ // Close any open block tags
+ $arr=array();
+ $ai=0;
+ for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag'],$arr,$ai); }
+ // Output any text left in buffer
+ if (count($this->textbuffer)) { $this->printbuffer($this->textbuffer); }
+ $this->bufferoutput = true;
+ $this->textbuffer=array();
+ $this->headerbuffer='';
+ $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
+ $this->setCSS($properties,'','BODY');
+ }
+
+ mb_internal_encoding('UTF-8');
+
+ $html = $this->AdjustHTML($html, $this->tabSpaces); //Try to make HTML look more like XHTML
+
+ if ($this->autoScriptToLang) { $html = $this->markScriptToLang($html); }
+
+ preg_match_all('/]*)>(.*?)<\/htmlpageheader>/si',$html,$h);
+ for($i=0;$ipageHTMLheaders[$n[1]]['html'] = $h[2][$i];
+ $this->pageHTMLheaders[$n[1]]['h'] = $this->_gethtmlheight($h[2][$i]);
+ }
+ }
+ preg_match_all('/]*)>(.*?)<\/htmlpagefooter>/si',$html,$f);
+ for($i=0;$ipageHTMLfooters[$n[1]]['html'] = $f[2][$i];
+ $this->pageHTMLfooters[$n[1]]['h'] = $this->_gethtmlheight($f[2][$i]);
+ }
+ }
+
+ $html = preg_replace('//si','',$html);
+ $html = preg_replace('//si','',$html);
+
+ if($this->state==0 && $sub!=1 && $sub!=3 && $sub!=4) {
+ $this->AddPage($this->CurOrientation);
+ }
+
+
+ if (isset($hname) && preg_match('/^html_(.*)$/i',$hname,$n)) $this->SetHTMLHeader($this->pageHTMLheaders[$n[1]],'O',true);
+ if (isset($fname) && preg_match('/^html_(.*)$/i',$fname,$n)) $this->SetHTMLFooter($this->pageHTMLfooters[$n[1]],'O');
+
+
+
+ $html=str_replace('','< ',$html); //Fix 'checkSIP = false;
+ $this->checkSMP = false;
+ $this->checkCJK = false;
+ if ($this->onlyCoreFonts) { $html = $this->SubstituteChars($html); }
+ else {
+ if (preg_match("/([".$this->pregRTLchars."])/u", $html)) { $this->biDirectional = true; } // *OTL*
+ if (preg_match("/([\x{20000}-\x{2FFFF}])/u", $html)) { $this->checkSIP = true; }
+ if (preg_match("/([\x{10000}-\x{1FFFF}])/u", $html)) { $this->checkSMP = true; }
+/*-- CJK-FONTS --*/
+ if (preg_match("/([".$this->pregCJKchars."])/u", $html)) { $this->checkCJK = true; }
+/*-- END CJK-FONTS --*/
+ }
+
+ // Don't allow non-breaking spaces that are converted to substituted chars or will break anyway and mess up table width calc.
+ $html = str_replace('160',chr(32),$html);
+ $html = str_replace('','|',$html);
+ $html = str_replace('','|',$html);
+ $html = str_replace('','|',$html);
+
+ //Add new supported tags in the DisableTags function
+ $html=strip_tags($html,$this->enabledtags); //remove all unsupported tags, but the ones inside the 'enabledtags' string
+
+ //Explode the string in order to parse the HTML code
+ $a=preg_split('/<(.*?)>/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
+ // ? more accurate regexp that allows e.g.
+ // if changing - also change in fn.SubstituteChars()
+ // $a = preg_split ('/<((?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+)>/ms', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
+
+ if ($this->mb_enc) {
+ mb_internal_encoding($this->mb_enc);
+ }
+ $pbc = 0;
+ if ($this->progressBar) { $this->UpdateProgressBar(1,0); } // *PROGRESS-BAR*
+ $this->subPos = -1;
+ $cnt = count($a);
+ for($i=0;$i<$cnt; $i++) {
+ $e = $a[$i];
+ if($i%2==0) {
+ //TEXT
+ if ($this->blk[$this->blklvl]['hide']) { continue; }
+ if ($this->inlineDisplayOff) { continue; }
+ if ($this->inMeter) { continue; }
+
+ if ($this->inFixedPosBlock) { $this->fixedPosBlock .= $e; continue; } // *CSS-POSITION*
+ if (strlen($e) == 0) { continue; }
+
+ if ($this->ignorefollowingspaces && !$this->ispre) {
+ if (strlen(ltrim($e)) == 0) { continue; }
+ if ($this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats' && substr($e,0,1) == ' ') {
+ $this->ignorefollowingspaces = false;
+ $e = ltrim($e);
+ }
+ }
+
+ $this->OTLdata = NULL; // mPDF 5.7.1
+
+ $e = strcode2utf($e);
+ $e = $this->lesser_entity_decode($e);
+
+ if ($this->usingCoreFont) {
+ // If core font is selected in document which is not onlyCoreFonts - substitute with non-core font
+ if ($this->useSubstitutions && !$this->onlyCoreFonts && $this->subPos<$i && !$this->specialcontent) {
+ $cnt += $this->SubstituteCharsNonCore($a, $i, $e);
+ }
+ // CONVERT ENCODING
+ $e = mb_convert_encoding($e,$this->mb_enc,'UTF-8');
+ if ($this->textvar & FT_UPPERCASE) { $e = mb_strtoupper($e,$this->mb_enc); } // mPDF 5.7.1
+ else if ($this->textvar & FT_LOWERCASE) { $e = mb_strtolower($e,$this->mb_enc); } // mPDF 5.7.1
+ else if ($this->textvar & FT_CAPITALIZE) { $e = mb_convert_case($e, MB_CASE_TITLE, "UTF-8"); } // mPDF 5.7.1
+ }
+ else {
+ if ($this->checkSIP && $this->CurrentFont['sipext'] && $this->subPos<$i && (!$this->specialcontent || !$this->useActiveForms)) {
+ $cnt += $this->SubstituteCharsSIP($a, $i, $e);
+ }
+
+ if ($this->useSubstitutions && !$this->onlyCoreFonts && $this->CurrentFont['type']!='Type0' && $this->subPos<$i && (!$this->specialcontent || !$this->useActiveForms)) {
+ $cnt += $this->SubstituteCharsMB($a, $i, $e);
+ }
+
+ if ($this->textvar & FT_UPPERCASE) { $e = mb_strtoupper($e,$this->mb_enc); }
+ else if ($this->textvar & FT_LOWERCASE) { $e = mb_strtolower($e,$this->mb_enc); }
+ else if ($this->textvar & FT_CAPITALIZE) { $e = mb_convert_case($e, MB_CASE_TITLE, "UTF-8"); }
+
+/*-- OTL --*/
+ // Use OTL OpenType Table Layout - GSUB & GPOS
+ if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL'] && (!$this->specialcontent || !$this->useActiveForms)) {
+ $e = $this->otl->applyOTL($e, $this->CurrentFont['useOTL']);
+ $this->OTLdata = $this->otl->OTLdata;
+ $this->otl->removeChar($e, $this->OTLdata , "\xef\xbb\xbf"); // Remove ZWNBSP (also Byte order mark FEFF)
+ }
+/*-- END OTL --*/
+ else { // *OTL*
+ // removes U+200E/U+200F LTR and RTL mark and U+200C/U+200D Zero-width Joiner and Non-joiner
+ $e = preg_replace("/[\xe2\x80\x8c\xe2\x80\x8d\xe2\x80\x8e\xe2\x80\x8f]/u",'',$e);
+ $e = preg_replace("/[\xef\xbb\xbf]/u",'',$e); // Remove ZWNBSP (also Byte order mark FEFF)
+ } // *OTL*
+ }
+ if (($this->tts) || ($this->ttz) || ($this->tta)) {
+ $es = explode('|',$e);
+ $e = '';
+ foreach($es AS $val) {
+ $e .= chr($val);
+ }
+ }
+
+ // FORM ELEMENTS
+ if ($this->specialcontent) {
+/*-- FORMS --*/
+ //SELECT tag (form element)
+ if ($this->specialcontent == "type=select") {
+ $e = ltrim($e);
+ if (!empty($this->OTLdata)) { $this->otl->trimOTLdata($this->OTLdata, true, false); } // *OTL*
+ $stringwidth = $this->GetStringWidth($e);
+ if (!isset($this->selectoption['MAXWIDTH']) || $stringwidth > $this->selectoption['MAXWIDTH']) { $this->selectoption['MAXWIDTH'] = $stringwidth; }
+ if (!isset($this->selectoption['SELECTED']) || $this->selectoption['SELECTED'] == '') {
+ $this->selectoption['SELECTED'] = $e;
+ if (!empty($this->OTLdata)) { $this->selectoption['SELECTED-OTLDATA'] = $this->OTLdata; } // *OTL*
+ }
+ // Active Forms
+ if (isset($this->selectoption['ACTIVE']) && $this->selectoption['ACTIVE']) {
+ $this->selectoption['ITEMS'][]=array('exportValue'=>$this->selectoption['currentVAL'], 'content'=>$e, 'selected'=>$this->selectoption['currentSEL']);
+ }
+ $this->OTLdata = array();
+ }
+ // TEXTAREA
+ else {
+ $objattr = unserialize($this->specialcontent);
+ $objattr['text'] = $e;
+ $objattr['OTLdata'] = $this->OTLdata;
+ $this->OTLdata = array();
+ $te = "\xbb\xa4\xactype=textarea,objattr=".serialize($objattr)."\xbb\xa4\xac";
+ if ($this->tdbegin) {
+ $this->_saveCellTextBuffer($te, $this->HREF);
+ }
+ else {
+ $this->_saveTextBuffer($te, $this->HREF);
+ }
+ }
+/*-- END FORMS --*/
+ }
+
+ // TABLE
+ else if ($this->tableLevel) {
+/*-- TABLES --*/
+ if ($this->tdbegin) {
+ if (($this->ignorefollowingspaces) && !$this->ispre) {
+ $e = ltrim($e);
+ if (!empty($this->OTLdata)) { $this->otl->trimOTLdata($this->OTLdata, true, false); } // *OTL*
+ }
+ if ($e || $e==='0') {
+ if ($this->blockjustfinished && $this->cell[$this->row][$this->col]['s']>0) {
+ $this->_saveCellTextBuffer("\n");
+ if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
+ $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
+ }
+ elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
+ $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
+ }
+ $this->cell[$this->row][$this->col]['s'] = 0;// reset
+ }
+ $this->blockjustfinished=false;
+
+ if (!isset($this->cell[$this->row][$this->col]['R']) || !$this->cell[$this->row][$this->col]['R']) {
+ if (isset($this->cell[$this->row][$this->col]['s'])) {
+ $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth($e, false, $this->OTLdata, $this->textvar);
+ }
+ else { $this->cell[$this->row][$this->col]['s'] = $this->GetStringWidth($e, false, $this->OTLdata, $this->textvar); }
+ if (!empty($this->spanborddet)) {
+ $this->cell[$this->row][$this->col]['s'] += (isset($this->spanborddet['L']['w']) ? $this->spanborddet['L']['w'] : 0) + (isset($this->spanborddet['R']['w']) ? $this->spanborddet['R']['w'] : 0);
+ }
+ }
+ $this->_saveCellTextBuffer($e, $this->HREF);
+ if (substr($this->cell[$this->row][$this->col]['a'],0,1) == 'D') {
+ $dp = $this->decimal_align[substr($this->cell[$this->row][$this->col]['a'],0,2)];
+ $s = preg_split('/'.preg_quote($dp,'/').'/', $e, 2); // ? needs to be /u if not core
+ $s0 = $this->GetStringWidth($s[0], false);
+ if (isset($s[1]) && $s[1]) { $s1 = $this->GetStringWidth(($s[1].$dp), false); }
+ else $s1 = 0;
+ if (!isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0'])) {
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0'] = $s0;
+ }
+ else {
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0'] = max($s0, $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0']);
+ }
+ if (!isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1'])) {
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1'] = $s1;
+ }
+ else {
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1'] = max($s1, $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1']);
+ }
+ }
+
+ if ($this->tableLevel==1 && $this->useGraphs) {
+ $this->graphs[$this->currentGraphId]['data'][$this->row][$this->col] = $e;
+ }
+ $this->nestedtablejustfinished = false;
+ $this->linebreakjustfinished=false;
+ }
+ }
+/*-- END TABLES --*/
+ }
+ // ALL ELSE
+ else {
+ if ($this->ignorefollowingspaces && !$this->ispre) {
+ $e = ltrim($e);
+ if (!empty($this->OTLdata)) { $this->otl->trimOTLdata($this->OTLdata, true, false); } // *OTL*
+ }
+ if ($e || $e==='0') $this->_saveTextBuffer($e, $this->HREF);
+ }
+ if ($e || $e==='0') $this->ignorefollowingspaces=false; // mPDF 6
+ if (substr($e,-1,1) == ' ' && !$this->ispre && $this->FontFamily!='csymbol' && $this->FontFamily!='czapfdingbats') {
+ $this->ignorefollowingspaces = true;
+ }
+ }
+
+
+ else { // TAG **
+ if(isset($e[0]) && $e[0]=='/') {
+/*-- PROGRESS-BAR --*/
+ if ($this->progressBar) { // 10% increments
+ if (intval($i*10/$cnt) != $pbc) { $pbc = intval($i*10/$cnt); $this->UpdateProgressBar(1,$pbc*10,$tag); }
+ }
+/*-- END PROGRESS-BAR --*/
+
+ $endtag = trim(strtoupper(substr($e,1)));
+
+
+/*-- CSS-POSITION --*/
+ // mPDF 6
+ if ($this->inFixedPosBlock) {
+ if (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags)) { $this->fixedPosBlockDepth--; }
+ if ($this->fixedPosBlockDepth == 0) {
+ $this->fixedPosBlockSave[] = array($this->fixedPosBlock, $this->fixedPosBlockBBox, $this->page);
+ $this->fixedPosBlock = '';
+ $this->inFixedPosBlock = false;
+ continue;
+ }
+ $this->fixedPosBlock .= '<'.$e.'>';
+ continue;
+ }
+/*-- END CSS-POSITION --*/
+
+ // mPDF 6
+ // Correct for tags where HTML5 specifies optional end tags (see also OpenTag() )
+ if ($this->allow_html_optional_endtags && !$parseonly) {
+ if (isset($this->blk[$this->blklvl]['tag'])) {
+ $closed = false;
+ // li end tag may be omitted if there is no more content in the parent element
+ if (!$closed && $this->blk[$this->blklvl]['tag']=='LI' && $endtag!='LI' && (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags))) { $this->CloseTag('LI',$a,$i); $closed = true; }
+ // dd end tag may be omitted if there is no more content in the parent element
+ if (!$closed && $this->blk[$this->blklvl]['tag']=='DD' && $endtag!='DD' && (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags))) { $this->CloseTag('DD',$a,$i); $closed = true; }
+ // p end tag may be omitted if there is no more content in the parent element and the parent element is not an A element [??????]
+ if (!$closed && $this->blk[$this->blklvl]['tag']=='P' && $endtag!='P' && (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags))) { $this->CloseTag('P',$a,$i); $closed = true; }
+ // option end tag may be omitted if there is no more content in the parent element
+ if (!$closed && $this->blk[$this->blklvl]['tag']=='OPTION' && $endtag!='OPTION' && (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags))) { $this->CloseTag('OPTION',$a,$i); $closed = true; }
+ }
+/*-- TABLES --*/
+ // Check for Table tags where HTML specifies optional end tags,
+ if ($endtag == 'TABLE') {
+ if ($this->lastoptionaltag == 'THEAD' || $this->lastoptionaltag == 'TBODY' || $this->lastoptionaltag == 'TFOOT') {
+ $this->CloseTag($this->lastoptionaltag,$a,$i);
+ }
+ if ($this->lastoptionaltag == 'TR') { $this->CloseTag('TR',$a,$i); }
+ if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag,$a,$i); $this->CloseTag('TR',$a,$i); }
+ }
+ if ($endtag == 'THEAD' || $endtag == 'TBODY' || $endtag == 'TFOOT') {
+ if ($this->lastoptionaltag == 'TR') { $this->CloseTag('TR',$a,$i); }
+ if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag,$a,$i); $this->CloseTag('TR',$a,$i); }
+ }
+ if ($endtag == 'TR') {
+ if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag,$a,$i); }
+ }
+/*-- END TABLES --*/
+ }
+
+
+ // mPDF 6
+ if($this->blk[$this->blklvl]['hide']) {
+ if (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags)) {
+ unset($this->blk[$this->blklvl]);
+ $this->blklvl--;
+ }
+ continue;
+ }
+
+ // mPDF 6
+ $this->CloseTag($endtag,$a,$i); // mPDF 6
+ }
+
+ else { // OPENING TAG
+ if($this->blk[$this->blklvl]['hide']) {
+ if (strpos($e,' ')) { $te = strtoupper(substr($e,0,strpos($e,' '))); }
+ else { $te = strtoupper($e); }
+ // mPDF 6
+ if ($te == 'THEAD' || $te == 'TBODY' || $te == 'TFOOT' || $te == 'TR' || $te == 'TD' || $te == 'TH') {
+ $this->lastoptionaltag = $te;
+ }
+ if (in_array($te, $this->outerblocktags) || in_array($te, $this->innerblocktags)) {
+ $this->blklvl++;
+ $this->blk[$this->blklvl]['hide']=true;
+ $this->blk[$this->blklvl]['tag'] = $te; // mPDF 6
+ }
+ continue;
+ }
+
+/*-- CSS-POSITION --*/
+ if ($this->inFixedPosBlock) {
+ if (strpos($e,' ')) { $te = strtoupper(substr($e,0,strpos($e,' '))); }
+ else { $te = strtoupper($e); }
+ $this->fixedPosBlock .= '<'.$e.'>';
+ if (in_array($te, $this->outerblocktags) || in_array($te, $this->innerblocktags)) { $this->fixedPosBlockDepth++; }
+ continue;
+ }
+/*-- END CSS-POSITION --*/
+ $regexp = '|=\'(.*?)\'|s'; // eliminate single quotes, if any
+ $e = preg_replace($regexp,"=\"\$1\"",$e);
+ // changes anykey=anyvalue to anykey="anyvalue" (only do this inside [some] tags)
+ if (substr($e,0,10)!='pageheader' && substr($e,0,10)!='pagefooter' && substr($e,0,12)!='tocpagebreak' && substr($e,0,10)!='indexentry' && substr($e,0,8)!='tocentry') { // mPDF 6 (ZZZ99H)
+ $regexp = '| (\\w+?)=([^\\s>"]+)|si';
+ $e = preg_replace($regexp," \$1=\"\$2\"",$e);
+ }
+
+ $e = preg_replace('/ (\\S+?)\s*=\s*"/i', " \\1=\"", $e);
+
+ //Fix path values, if needed
+ $orig_srcpath = '';
+ if ((stristr($e,"href=") !== false) or (stristr($e,"src=") !== false) ) {
+ $regexp = '/ (href|src)\s*=\s*"(.*?)"/i';
+ preg_match($regexp,$e,$auxiliararray);
+ if (isset($auxiliararray[2])) { $path = $auxiliararray[2]; }
+ else { $path = ''; }
+ if (trim($path) != '' && !(stristr($e,"src=") !== false && substr($path,0,4)=='var:') && substr($path,0,1)!='@') {
+ $path=htmlspecialchars_decode($path); // mPDF 5.7.4 URLs
+ $orig_srcpath = $path;
+ $this->GetFullPath($path);
+ $regexp = '/ (href|src)="(.*?)"/i';
+ $e = preg_replace($regexp,' \\1="'.$path.'"',$e);
+ }
+ }//END of Fix path values
+
+ //Extract attributes
+ $contents=array();
+ $contents1=array();
+ $contents2=array();
+ // Changed to allow style="background: url('bg.jpg')"
+ // Changed to improve performance; maximum length of \S (attribute) = 16
+ // Increase allowed attribute name to 32 - cutting off "toc-even-header-name" etc.
+ preg_match_all('/\\S{1,32}=["][^"]*["]/',$e,$contents1);
+ preg_match_all('/\\S{1,32}=[\'][^\']*[\']/i',$e,$contents2);
+
+ $contents = array_merge($contents1, $contents2);
+ preg_match('/\\S+/',$e,$a2);
+ $tag=(isset($a2[0]) ? strtoupper($a2[0]) : '');
+ $attr=array();
+ if ($orig_srcpath) { $attr['ORIG_SRC'] = $orig_srcpath; }
+ if (!empty($contents)) {
+ foreach($contents[0] as $v) {
+ // Changed to allow style="background: url('bg.jpg')"
+ if(preg_match('/^([^=]*)=["]?([^"]*)["]?$/',$v,$a3) || preg_match('/^([^=]*)=[\']?([^\']*)[\']?$/',$v,$a3)) {
+ if (strtoupper($a3[1])=='ID' || strtoupper($a3[1])=='CLASS') { // 4.2.013 Omits STYLE
+ $attr[strtoupper($a3[1])]=trim(strtoupper($a3[2]));
+ }
+ // includes header-style-right etc. used for
+ else if (preg_match('/^(HEADER|FOOTER)-STYLE/i',$a3[1])) {
+ $attr[strtoupper($a3[1])]=trim(strtoupper($a3[2]));
+ }
+ else {
+ $attr[strtoupper($a3[1])]=trim($a3[2]);
+ }
+ }
+ }
+ }
+ $this->OpenTag($tag,$attr,$a,$i); // mPDF 6
+/*-- CSS-POSITION --*/
+ if ($this->inFixedPosBlock) {
+ $this->fixedPosBlockBBox = array($tag,$attr, $this->x, $this->y);
+ $this->fixedPosBlock = '';
+ $this->fixedPosBlockDepth = 1;
+ }
+/*-- END CSS-POSITION --*/
+ if (preg_match('/\/$/',$e)) { $this->closeTag($tag,$a,$i); }
+ }
+
+ } // end TAG
+ } //end of foreach($a as $i=>$e)
+
+ if ($close) {
+
+ // Close any open block tags
+ for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag'],$a,$i); }
+
+ // Output any text left in buffer
+ if (count($this->textbuffer) && !$parseonly) { $this->printbuffer($this->textbuffer); }
+ if (!$parseonly) $this->textbuffer=array();
+
+/*-- CSS-FLOAT --*/
+ // If ended with a float, need to move to end page
+ $currpos = $this->page*1000 + $this->y;
+ if (isset($this->blk[$this->blklvl]['float_endpos']) && $this->blk[$this->blklvl]['float_endpos'] > $currpos) {
+ $old_page = $this->page;
+ $new_page = intval($this->blk[$this->blklvl]['float_endpos'] /1000);
+ if ($old_page != $new_page) {
+ $s = $this->PrintPageBackgrounds();
+ // Writes after the marker so not overwritten later by page background etc.
+ $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
+ $this->pageBackgrounds = array();
+ $this->page = $new_page;
+ $this->ResetMargins();
+ $this->Reset();
+ $this->pageoutput[$this->page] = array();
+ }
+ $this->y = (($this->blk[$this->blklvl]['float_endpos'] *1000) % 1000000)/1000; // mod changes operands to integers before processing
+ }
+/*-- END CSS-FLOAT --*/
+
+/*-- CSS-IMAGE-FLOAT --*/
+ $this->printfloatbuffer();
+/*-- END CSS-IMAGE-FLOAT --*/
+
+ //Create Internal Links, if needed
+ if (!empty($this->internallink) ) {
+ foreach($this->internallink as $k=>$v) {
+ if (strpos($k,"#") !== false ) { continue; } //ignore
+ $ypos = $v['Y'];
+ $pagenum = $v['PAGE'];
+ $sharp = "#";
+ while (array_key_exists($sharp.$k,$this->internallink)) {
+ $internallink = $this->internallink[$sharp.$k];
+ $this->SetLink($internallink,$ypos,$pagenum);
+ $sharp .= "#";
+ }
+ }
+ }
+
+ $this->bufferoutput = false;
+
+/*-- CSS-POSITION --*/
+ if (count($this->fixedPosBlockSave) && $sub != 4) {
+ foreach($this->fixedPosBlockSave AS $fpbs) {
+ $old_page = $this->page;
+ $this->page = $fpbs[2];
+ $this->WriteFixedPosHTML($fpbs[0], 0, 0, 100, 100,'auto', $fpbs[1]); // 0,0,10,10 are overwritten by bbox
+ $this->page = $old_page;
+ }
+ $this->fixedPosBlockSave = array();
+ }
+/*-- END CSS-POSITION --*/
+
+ }
+}
+
+/*-- CSS-POSITION --*/
+
+function WriteFixedPosHTML($html='',$x, $y, $w, $h, $overflow='visible', $bounding=array()) {
+ // $overflow can be 'hidden', 'visible' or 'auto' - 'auto' causes autofit to size
+ // Annotations disabled - enabled in mPDF 5.0
+ // Links do work
+ // Will always go on current page (or start Page 1 if required)
+ // Probably INCOMPATIBLE WITH keep with table, columns etc.
+ // Called externally or interally via
+ // When used internally, $x $y $w $h and $overflow are all overridden by $bounding
+
+ $overflow = strtolower($overflow);
+ if($this->state==0) {
+ $this->AddPage($this->CurOrientation);
+ }
+ $save_y = $this->y;
+ $save_x = $this->x;
+ $this->fullImageHeight = $this->h;
+ $save_cols = false;
+/*-- COLUMNS --*/
+ if ($this->ColActive) {
+ $save_cols = true;
+ $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
+ $this->SetColumns(0);
+ }
+/*-- END COLUMNS --*/
+ $save_annots = $this->title2annots; // *ANNOTATIONS*
+ $this->writingHTMLheader = true; // a FIX to stop pagebreaks etc.
+ $this->writingHTMLfooter = true;
+ $this->InFooter = true; // suppresses autopagebreaks
+ $save_bgs = $this->pageBackgrounds;
+ $checkinnerhtml = preg_replace('/\s/','',$html);
+
+ if ($w > $this->w) { $x = 0; $w = $this->w; }
+ if ($h > $this->h) { $y = 0; $h = $this->h; }
+ if ($x > $this->w) { $x = $this->w - $w; }
+ if ($y > $this->h) { $y = $this->h - $h; }
+
+ if (!empty($bounding)) {
+ // $cont_ containing block = full physical page (position: absolute) or page inside margins (position: fixed)
+ // $bbox_ Bounding box is the which is positioned absolutely/fixed
+ // top/left/right/bottom/width/height/background*/border*/padding*/margin* are taken from bounding
+ // font*[family/size/style/weight]/line-height/text*[align/decoration/transform/indent]/color are transferred to $inner
+ // as an enclosing (after having checked ID/CLASS)
+ // $x, $y, $w, $h are inside of $bbox_ = containing box for $inner_
+ // $inner_ InnerHTML is the contents of that block to be output
+ $tag = $bounding[0];
+ $attr = $bounding[1];
+ $orig_x0 = $bounding[2];
+ $orig_y0 = $bounding[3];
+
+ // As in WriteHTML() initialising
+ $this->blklvl = 0;
+ $this->lastblocklevelchange = 0;
+ $this->blk = array();
+ $this->initialiseBlock($this->blk[0]);
+
+ $this->blk[0]['width'] =& $this->pgwidth;
+ $this->blk[0]['inner_width'] =& $this->pgwidth;
+
+ $this->blk[0]['blockContext'] = $this->blockContext;
+
+ $properties = $this->cssmgr->MergeCSS('BLOCK','BODY','');
+ $this->setCSS($properties,'','BODY');
+ $this->blklvl = 1;
+ $this->initialiseBlock($this->blk[1]);
+ $this->blk[1]['tag'] = $tag;
+ $this->blk[1]['attr'] = $attr;
+ $this->Reset();
+ $p = $this->cssmgr->MergeCSS('BLOCK',$tag,$attr);
+ if (isset($p['ROTATE']) && ($p['ROTATE']==90 || $p['ROTATE']==-90 || $p['ROTATE']==180)) { $rotate = $p['ROTATE']; } // mPDF 6
+ else { $rotate = 0; }
+ if (isset($p['OVERFLOW'])) { $overflow = strtolower($p['OVERFLOW']); }
+ if (strtolower($p['POSITION']) == 'fixed') {
+ $cont_w = $this->pgwidth; // $this->blk[0]['inner_width'];
+ $cont_h = $this->h - $this->tMargin - $this->bMargin;
+ $cont_x = $this->lMargin;
+ $cont_y = $this->tMargin;
+ }
+ else {
+ $cont_w = $this->w; // ABSOLUTE;
+ $cont_h = $this->h;
+ $cont_x = 0;
+ $cont_y = 0;
+ }
+
+ // Pass on in-line properties to the innerhtml
+ $css = '';
+ if (isset($p['TEXT-ALIGN'])) { $css .= 'text-align: '.strtolower($p['TEXT-ALIGN']).'; '; }
+ if (isset($p['TEXT-TRANSFORM'])) { $css .= 'text-transform: '.strtolower($p['TEXT-TRANSFORM']).'; '; }
+ if (isset($p['TEXT-INDENT'])) { $css .= 'text-indent: '.strtolower($p['TEXT-INDENT']).'; '; }
+ if (isset($p['TEXT-DECORATION'])) { $css .= 'text-decoration: '.strtolower($p['TEXT-DECORATION']).'; '; }
+ if (isset($p['FONT-FAMILY'])) { $css .= 'font-family: '.strtolower($p['FONT-FAMILY']).'; '; }
+ if (isset($p['FONT-STYLE'])) { $css .= 'font-style: '.strtolower($p['FONT-STYLE']).'; '; }
+ if (isset($p['FONT-WEIGHT'])) { $css .= 'font-weight: '.strtolower($p['FONT-WEIGHT']).'; '; }
+ if (isset($p['FONT-SIZE'])) { $css .= 'font-size: '.strtolower($p['FONT-SIZE']).'; '; }
+ if (isset($p['LINE-HEIGHT'])) { $css .= 'line-height: '.strtolower($p['LINE-HEIGHT']).'; '; }
+ if (isset($p['TEXT-SHADOW'])) { $css .= 'text-shadow: '.strtolower($p['TEXT-SHADOW']).'; '; }
+ if (isset($p['LETTER-SPACING'])) { $css .= 'letter-spacing: '.strtolower($p['LETTER-SPACING']).'; '; }
+ // mPDF 6
+ if (isset($p['FONT-VARIANT-POSITION'])) { $css .= 'font-variant-position: '.strtolower($p['FONT-VARIANT-POSITION']).'; '; }
+ if (isset($p['FONT-VARIANT-CAPS'])) { $css .= 'font-variant-caps: '.strtolower($p['FONT-VARIANT-CAPS']).'; '; }
+ if (isset($p['FONT-VARIANT-LIGATURES'])) { $css .= 'font-variant-ligatures: '.strtolower($p['FONT-VARIANT-LIGATURES']).'; '; }
+ if (isset($p['FONT-VARIANT-NUMERIC'])) { $css .= 'font-variant-numeric: '.strtolower($p['FONT-VARIANT-NUMERIC']).'; '; }
+ if (isset($p['FONT-VARIANT-ALTERNATES'])) { $css .= 'font-variant-alternates: '.strtolower($p['FONT-VARIANT-ALTERNATES']).'; '; }
+ if (isset($p['FONT-FEATURE-SETTINGS'])) { $css .= 'font-feature-settings: '.strtolower($p['FONT-FEATURE-SETTINGS']).'; '; }
+ if (isset($p['FONT-LANGUAGE-OVERRIDE'])) { $css .= 'font-language-override: '.strtolower($p['FONT-LANGUAGE-OVERRIDE']).'; '; }
+ if (isset($p['FONT-KERNING'])) { $css .= 'font-kerning: '.strtolower($p['FONT-KERNING']).'; '; }
+
+ if (isset($p['COLOR'])) { $css .= 'color: '.strtolower($p['COLOR']).'; '; }
+ if (isset($p['Z-INDEX'])) { $css .= 'z-index: '.$p['Z-INDEX'].'; '; }
+ if ($css) {
+ $html = ' '.$html.' ';
+ }
+ // Copy over (only) the properties to set for border and background
+ $pb = array();
+ $pb['MARGIN-TOP'] = (isset($p['MARGIN-TOP']) ? $p['MARGIN-TOP'] : '');
+ $pb['MARGIN-RIGHT'] = (isset($p['MARGIN-RIGHT']) ? $p['MARGIN-RIGHT'] : '');
+ $pb['MARGIN-BOTTOM'] = (isset($p['MARGIN-BOTTOM']) ? $p['MARGIN-BOTTOM'] : '');
+ $pb['MARGIN-LEFT'] = (isset($p['MARGIN-LEFT']) ? $p['MARGIN-LEFT'] : '');
+ $pb['PADDING-TOP'] = (isset($p['PADDING-TOP']) ? $p['PADDING-TOP'] : '');
+ $pb['PADDING-RIGHT'] = (isset($p['PADDING-RIGHT']) ? $p['PADDING-RIGHT'] : '');
+ $pb['PADDING-BOTTOM'] = (isset($p['PADDING-BOTTOM']) ? $p['PADDING-BOTTOM'] : '');
+ $pb['PADDING-LEFT'] = (isset($p['PADDING-LEFT']) ? $p['PADDING-LEFT'] : '');
+ $pb['BORDER-TOP'] = (isset($p['BORDER-TOP']) ? $p['BORDER-TOP'] : '');
+ $pb['BORDER-RIGHT'] = (isset($p['BORDER-RIGHT']) ? $p['BORDER-RIGHT'] : '');
+ $pb['BORDER-BOTTOM'] = (isset($p['BORDER-BOTTOM']) ? $p['BORDER-BOTTOM'] : '');
+ $pb['BORDER-LEFT'] = (isset($p['BORDER-LEFT']) ? $p['BORDER-LEFT'] : '');
+ if (isset($p['BORDER-TOP-LEFT-RADIUS-H'])) { $pb['BORDER-TOP-LEFT-RADIUS-H'] = $p['BORDER-TOP-LEFT-RADIUS-H']; }
+ if (isset($p['BORDER-TOP-LEFT-RADIUS-V'])) { $pb['BORDER-TOP-LEFT-RADIUS-V'] = $p['BORDER-TOP-LEFT-RADIUS-V']; }
+ if (isset($p['BORDER-TOP-RIGHT-RADIUS-H'])) { $pb['BORDER-TOP-RIGHT-RADIUS-H'] = $p['BORDER-TOP-RIGHT-RADIUS-H']; }
+ if (isset($p['BORDER-TOP-RIGHT-RADIUS-V'])) { $pb['BORDER-TOP-RIGHT-RADIUS-V'] = $p['BORDER-TOP-RIGHT-RADIUS-V']; }
+ if (isset($p['BORDER-BOTTOM-LEFT-RADIUS-H'])) { $pb['BORDER-BOTTOM-LEFT-RADIUS-H'] = $p['BORDER-BOTTOM-LEFT-RADIUS-H']; }
+ if (isset($p['BORDER-BOTTOM-LEFT-RADIUS-V'])) { $pb['BORDER-BOTTOM-LEFT-RADIUS-V'] = $p['BORDER-BOTTOM-LEFT-RADIUS-V']; }
+ if (isset($p['BORDER-BOTTOM-RIGHT-RADIUS-H'])) { $pb['BORDER-BOTTOM-RIGHT-RADIUS-H'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-H']; }
+ if (isset($p['BORDER-BOTTOM-RIGHT-RADIUS-V'])) { $pb['BORDER-BOTTOM-RIGHT-RADIUS-V'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-V']; }
+ if (isset($p['BACKGROUND-COLOR'])) { $pb['BACKGROUND-COLOR'] = $p['BACKGROUND-COLOR']; }
+ if (isset($p['BOX-SHADOW'])) { $pb['BOX-SHADOW'] = $p['BOX-SHADOW']; }
+/*-- BACKGROUNDS --*/
+ if (isset($p['BACKGROUND-IMAGE'])) { $pb['BACKGROUND-IMAGE'] = $p['BACKGROUND-IMAGE']; }
+ if (isset($p['BACKGROUND-IMAGE-RESIZE'])) { $pb['BACKGROUND-IMAGE-RESIZE'] = $p['BACKGROUND-IMAGE-RESIZE']; }
+ if (isset($p['BACKGROUND-IMAGE-OPACITY'])) { $pb['BACKGROUND-IMAGE-OPACITY'] = $p['BACKGROUND-IMAGE-OPACITY']; }
+ if (isset($p['BACKGROUND-REPEAT'])) { $pb['BACKGROUND-REPEAT'] = $p['BACKGROUND-REPEAT']; }
+ if (isset($p['BACKGROUND-POSITION'])) { $pb['BACKGROUND-POSITION'] = $p['BACKGROUND-POSITION']; }
+ if (isset($p['BACKGROUND-GRADIENT'])) { $pb['BACKGROUND-GRADIENT'] = $p['BACKGROUND-GRADIENT']; }
+ if (isset($p['BACKGROUND-SIZE'])) { $pb['BACKGROUND-SIZE'] = $p['BACKGROUND-SIZE']; }
+ if (isset($p['BACKGROUND-ORIGIN'])) { $pb['BACKGROUND-ORIGIN'] = $p['BACKGROUND-ORIGIN']; }
+ if (isset($p['BACKGROUND-CLIP'])) { $pb['BACKGROUND-CLIP'] = $p['BACKGROUND-CLIP']; }
+
+/*-- END BACKGROUNDS --*/
+
+ $this->setCSS($pb,'BLOCK',$tag);
+
+ //================================================================
+ $bbox_br = $this->blk[1]['border_right']['w'];
+ $bbox_bl = $this->blk[1]['border_left']['w'];
+ $bbox_bt = $this->blk[1]['border_top']['w'];
+ $bbox_bb = $this->blk[1]['border_bottom']['w'];
+ $bbox_pr = $this->blk[1]['padding_right'];
+ $bbox_pl = $this->blk[1]['padding_left'];
+ $bbox_pt = $this->blk[1]['padding_top'];
+ $bbox_pb = $this->blk[1]['padding_bottom'];
+ $bbox_mr = $this->blk[1]['margin_right'];
+ if (isset($p['MARGIN-RIGHT']) && strtolower($p['MARGIN-RIGHT'])=='auto') { $bbox_mr = 'auto'; }
+ $bbox_ml = $this->blk[1]['margin_left'];
+ if (isset($p['MARGIN-LEFT']) && strtolower($p['MARGIN-LEFT'])=='auto') { $bbox_ml = 'auto'; }
+ $bbox_mt = $this->blk[1]['margin_top'];
+ if (isset($p['MARGIN-TOP']) && strtolower($p['MARGIN-TOP'])=='auto') { $bbox_mt = 'auto'; }
+ $bbox_mb = $this->blk[1]['margin_bottom'];
+ if (isset($p['MARGIN-BOTTOM']) && strtolower($p['MARGIN-BOTTOM'])=='auto') { $bbox_mb = 'auto'; }
+ if (isset($p['LEFT']) && strtolower($p['LEFT'])!='auto') { $bbox_left = $this->ConvertSize($p['LEFT'], $cont_w, $this->FontSize,false); }
+ else { $bbox_left = 'auto'; }
+ if (isset($p['TOP']) && strtolower($p['TOP'])!='auto') { $bbox_top = $this->ConvertSize($p['TOP'], $cont_h, $this->FontSize,false); }
+ else { $bbox_top = 'auto'; }
+ if (isset($p['RIGHT']) && strtolower($p['RIGHT'])!='auto') { $bbox_right = $this->ConvertSize($p['RIGHT'], $cont_w, $this->FontSize,false); }
+ else { $bbox_right = 'auto'; }
+ if (isset($p['BOTTOM']) && strtolower($p['BOTTOM'])!='auto') { $bbox_bottom = $this->ConvertSize($p['BOTTOM'], $cont_h, $this->FontSize,false); }
+ else { $bbox_bottom = 'auto'; }
+ if (isset($p['WIDTH']) && strtolower($p['WIDTH'])!='auto') { $inner_w = $this->ConvertSize($p['WIDTH'], $cont_w, $this->FontSize,false); }
+ else { $inner_w = 'auto'; }
+ if (isset($p['HEIGHT']) && strtolower($p['HEIGHT'])!='auto') { $inner_h = $this->ConvertSize($p['HEIGHT'], $cont_h, $this->FontSize,false); }
+ else { $inner_h = 'auto'; }
+
+ // If bottom or right pos are set and not left / top - save this to adjust rotated block later
+ if ($rotate == 90 || $rotate==-90) { // mPDF 6
+ if ($bbox_left === 'auto' && $bbox_right !== 'auto') { $rot_rpos = $bbox_right; }
+ else { $rot_rpos = false; }
+ if ($bbox_top === 'auto' && $bbox_bottom !== 'auto') { $rot_bpos = $bbox_bottom; }
+ else { $rot_bpos = false; }
+ }
+
+ //================================================================
+ if ($checkinnerhtml=='' && $inner_h==='auto') { $inner_h = 0.0001; }
+ if ($checkinnerhtml=='' && $inner_w==='auto') { $inner_w = 2*$this->GetCharWidth('W',false); }
+ //================================================================
+ // Algorithm from CSS2.1 See http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-height
+ // mPD 5.3.14
+ // Special case (not CSS) if all not specified, centre vertically on page
+ $bbox_top_orig = '';
+ if ($bbox_top==='auto' && $inner_h==='auto' && $bbox_bottom==='auto' && $bbox_mt==='auto' && $bbox_mb==='auto') {
+ $bbox_top_orig = $bbox_top;
+ if ($bbox_mt==='auto') { $bbox_mt = 0; }
+ if ($bbox_mb==='auto') { $bbox_mb = 0; }
+ $bbox_top = $orig_y0 - $bbox_mt - $cont_y;
+ // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
+ }
+ // mPD 5.3.14
+ else if ($bbox_top==='auto' && $inner_h==='auto' && $bbox_bottom==='auto') {
+ $bbox_top_orig = $bbox_top = $orig_y0 - $cont_y;
+ if ($bbox_mt==='auto') { $bbox_mt = 0; }
+ if ($bbox_mb==='auto') { $bbox_mb = 0; }
+ // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
+ }
+ else if ($bbox_top!=='auto' && $inner_h!=='auto' && $bbox_bottom!=='auto') {
+ if ($bbox_mt==='auto' && $bbox_mb==='auto') {
+ $x = $cont_h - $bbox_top - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_bottom;
+ $bbox_mt = $bbox_mb = ($x/2);
+ }
+ else if ($bbox_mt==='auto') {
+ $bbox_mt = $cont_h - $bbox_top - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
+ }
+ else if ($bbox_mb==='auto') {
+ $bbox_mb = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_bottom;
+ }
+ else {
+ $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
+ }
+ }
+ else {
+ if ($bbox_mt==='auto') { $bbox_mt = 0; }
+ if ($bbox_mb==='auto') { $bbox_mb = 0; }
+ if ($bbox_top==='auto' && $inner_h==='auto' && $bbox_bottom!=='auto') {
+ // solve for $bbox_top when content_h known - $inner_h=='auto' && $bbox_top =='auto'
+ }
+ else if ($bbox_top==='auto' && $bbox_bottom==='auto' && $inner_h!=='auto') {
+ $bbox_top = $orig_y0 - $bbox_mt - $cont_y;
+ $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
+ }
+ else if ($inner_h==='auto' && $bbox_bottom==='auto' && $bbox_top!=='auto') {
+ // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
+ }
+ else if ($bbox_top==='auto' && $inner_h!=='auto' && $bbox_bottom!=='auto') {
+ $bbox_top = $cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt - $bbox_bottom;
+ }
+ else if ($inner_h==='auto' && $bbox_top!=='auto' && $bbox_bottom!=='auto') {
+ $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mt - $bbox_bottom;
+ }
+ else if ($bbox_bottom==='auto' && $bbox_top!=='auto' && $inner_h!=='auto') {
+ $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
+ }
+ }
+
+ // THEN DO SAME FOR WIDTH
+ // http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width
+ if ($bbox_left==='auto' && $inner_w==='auto' && $bbox_right==='auto') {
+ if ($bbox_ml==='auto') { $bbox_ml = 0; }
+ if ($bbox_mr==='auto') { $bbox_mr = 0; }
+ // IF containing element RTL, should set $bbox_right
+ $bbox_left = $orig_x0 - $bbox_ml - $cont_x;
+ // solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto'
+ }
+ else if ($bbox_left!=='auto' && $inner_w!=='auto' && $bbox_right!=='auto') {
+ if ($bbox_ml==='auto' && $bbox_mr==='auto') {
+ $x = $cont_w - $bbox_left - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_right;
+ $bbox_ml = $bbox_mr = ($x/2);
+ }
+ else if ($bbox_ml==='auto') {
+ $bbox_ml = $cont_w - $bbox_left - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_mr - $bbox_right;
+ }
+ else if ($bbox_mr==='auto') {
+ $bbox_mr = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_right;
+ }
+ else {
+ $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
+ }
+ }
+ else {
+ if ($bbox_ml==='auto') { $bbox_ml = 0; }
+ if ($bbox_mr==='auto') { $bbox_mr = 0; }
+ if ($bbox_left==='auto' && $inner_w==='auto' && $bbox_right!=='auto') {
+ // solve for $bbox_left when content_w known - $inner_w=='auto' && $bbox_left =='auto'
+ }
+ else if ($bbox_left==='auto' && $bbox_right==='auto' && $inner_w!=='auto') {
+ // IF containing element RTL, should set $bbox_right
+ $bbox_left = $orig_x0 - $bbox_ml - $cont_x;
+ $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
+ }
+ else if ($inner_w==='auto' && $bbox_right==='auto' && $bbox_left!=='auto') {
+ // solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto'
+ }
+ else if ($bbox_left==='auto' && $inner_w!=='auto' && $bbox_right!=='auto') {
+ $bbox_left = $cont_w - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
+ }
+ else if ($inner_w==='auto' && $bbox_left!=='auto' && $bbox_right!=='auto') {
+ $inner_w = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
+ }
+ else if ($bbox_right==='auto' && $bbox_left!=='auto' && $inner_w!=='auto') {
+ $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
+ }
+ }
+
+ //================================================================
+ //================================================================
+/*-- BACKGROUNDS --*/
+ if (isset($pb['BACKGROUND-IMAGE']) && $pb['BACKGROUND-IMAGE']) {
+ $ret = $this->SetBackground($pb, $this->blk[1]['inner_width']);
+ if ($ret) { $this->blk[1]['background-image'] = $ret; }
+ }
+/*-- END BACKGROUNDS --*/
+
+ //================================================================
+ $y = $cont_y + $bbox_top + $bbox_mt + $bbox_bt + $bbox_pt;
+ $h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
+ $x = $cont_x + $bbox_left + $bbox_ml + $bbox_bl + $bbox_pl;
+ $w = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $bbox_pr - $bbox_br - $bbox_mr - $bbox_right;
+ // Set (temporary) values for x y w h to do first paint, if values are auto
+ if ($inner_h==='auto' && $bbox_top==='auto') {
+ $y = $cont_y + $bbox_mt + $bbox_bt + $bbox_pt;
+ $h = $cont_h - ($bbox_bottom + $bbox_mt + $bbox_mb + $bbox_bt + $bbox_bb + $bbox_pt + $bbox_pb);
+ }
+ else if ($inner_h==='auto' && $bbox_bottom==='auto') {
+ $y = $cont_y + $bbox_top + $bbox_mt + $bbox_bt + $bbox_pt;
+ $h = $cont_h - ($bbox_top + $bbox_mt + $bbox_mb + $bbox_bt + $bbox_bb + $bbox_pt + $bbox_pb);
+ }
+ if ($inner_w==='auto' && $bbox_left==='auto') {
+ $x = $cont_x + $bbox_ml + $bbox_bl + $bbox_pl;
+ $w = $cont_w - ($bbox_right + $bbox_ml + $bbox_mr + $bbox_bl + $bbox_br + $bbox_pl + $bbox_pr);
+ }
+ else if ($inner_w==='auto' && $bbox_right==='auto') {
+ $x = $cont_x + $bbox_left + $bbox_ml + $bbox_bl + $bbox_pl;
+ $w = $cont_w - ($bbox_left + $bbox_ml + $bbox_mr + $bbox_bl + $bbox_br + $bbox_pl + $bbox_pr);
+ }
+ $bbox_y = $cont_y + $bbox_top + $bbox_mt;
+ $bbox_x = $cont_x + $bbox_left + $bbox_ml;
+ $saved_block1 = $this->blk[1];
+ unset($p);
+ unset($pb);
+ //================================================================
+ if ($inner_w==='auto') { // do a first write
+ $this->lMargin=$x;
+ $this->rMargin=$this->w - $w - $x;
+ // SET POSITION & FONT VALUES
+ $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
+ $this->pageoutput[$this->page]=array();
+ $this->x = $x;
+ $this->y = $y;
+ $this->HTMLheaderPageLinks = array();
+ $this->HTMLheaderPageAnnots = array();
+ $this->HTMLheaderPageForms = array();
+ $this->pageBackgrounds = array();
+ $this->maxPosR = 0;
+ $this->maxPosL = $this->w; // For RTL
+ $this->WriteHTML($html , 4);
+ $inner_w = $this->maxPosR - $this->lMargin;
+ if ($bbox_right==='auto') {
+ $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
+ }
+ else if ($bbox_left==='auto') {
+ $bbox_left = $cont_w - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
+ $bbox_x = $cont_x + $bbox_left + $bbox_ml ;
+ $inner_x = $bbox_x + $bbox_bl + $bbox_pl;
+ $x = $inner_x;
+ }
+ $w = $inner_w;
+ $bbox_y = $cont_y + $bbox_top + $bbox_mt;
+ $bbox_x = $cont_x + $bbox_left + $bbox_ml;
+ }
+
+ if ($inner_h==='auto') { // do a first write
+ $this->lMargin=$x;
+ $this->rMargin=$this->w - $w - $x;
+ // SET POSITION & FONT VALUES
+ $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
+ $this->pageoutput[$this->page]=array();
+ $this->x = $x;
+ $this->y = $y;
+ $this->HTMLheaderPageLinks = array();
+ $this->HTMLheaderPageAnnots = array();
+ $this->HTMLheaderPageForms = array();
+ $this->pageBackgrounds = array();
+ $this->WriteHTML($html , 4);
+ $inner_h = $this->y - $y;
+ if ($overflow!='hidden' && $overflow!='visible') { // constrained
+ if (($this->y + $bbox_pb + $bbox_bb) > ($cont_y + $cont_h)) {
+ $adj = ($this->y + $bbox_pb + $bbox_bb) - ($cont_y + $cont_h);
+ $inner_h -= $adj;
+ }
+ }
+ if ($bbox_bottom==='auto' && $bbox_top_orig==='auto') {
+ $bbox_bottom = $bbox_top = ($cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb)/2;
+ if ($overflow!='hidden' && $overflow!='visible') { // constrained
+ if ($bbox_top < 0) {
+ $bbox_top = 0;
+ $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
+ }
+ }
+ $bbox_y = $cont_y + $bbox_top + $bbox_mt;
+ $inner_y = $bbox_y + $bbox_bt + $bbox_pt;
+ $y = $inner_y;
+
+ }
+ else if ($bbox_bottom==='auto') {
+ $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb;
+ }
+ else if ($bbox_top==='auto') {
+ $bbox_top = $cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
+ if ($overflow!='hidden' && $overflow!='visible') { // constrained
+ if ($bbox_top < 0) {
+ $bbox_top = 0;
+ $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
+ }
+ }
+ $bbox_y = $cont_y + $bbox_top + $bbox_mt;
+ $inner_y = $bbox_y + $bbox_bt + $bbox_pt;
+ $y = $inner_y;
+ }
+ $h = $inner_h;
+ $bbox_y = $cont_y + $bbox_top + $bbox_mt;
+ $bbox_x = $cont_x + $bbox_left + $bbox_ml;
+ }
+ $inner_w = $w;
+ $inner_h = $h;
+
+ }
+ $this->lMargin=$x;
+ $this->rMargin=$this->w - $w - $x;
+ // SET POSITION & FONT VALUES
+ $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
+ $this->pageoutput[$this->page]=array();
+ $this->x = $x;
+ $this->y = $y;
+ $this->HTMLheaderPageLinks = array();
+ $this->HTMLheaderPageAnnots = array();
+ $this->HTMLheaderPageForms = array();
+ $this->pageBackgrounds = array();
+ $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
+ $actual_h = $this->y - $y;
+ $use_w = $w;
+ $use_h = $h;
+ $ratio = $actual_h / $use_w;
+
+ if ($overflow!='hidden' && $overflow!='visible') {
+ $target = $h/$w;
+ if (($ratio / $target ) > 1) {
+ $nl = CEIL($actual_h / $this->lineheight);
+ $l = $use_w * $nl;
+ $est_w = sqrt(($l * $this->lineheight) / $target) * 0.8;
+ $use_w += ($est_w - $use_w) - ($w/100);
+ }
+ $bpcstart = ($ratio / $target);
+ $bpcctr = 1;
+ while(($ratio / $target ) > 1) {
+
+ if ($this->progressBar) { $this->UpdateProgressBar(4,intval(100/($ratio/$target)),('Auto-sizing fixed-position block: '.$bpcctr++)); } // *PROGRESS-BAR*
+
+ $this->x = $x;
+ $this->y = $y;
+
+ if (($ratio / $target) > 1.5 || ($ratio / $target) < 0.6) {
+ $use_w += ($w/$this->incrementFPR1);
+ }
+ else if (($ratio / $target) > 1.2 || ($ratio / $target) < 0.85) {
+ $use_w += ($w/$this->incrementFPR2);
+ }
+ else if (($ratio / $target) > 1.1 || ($ratio / $target) < 0.91) {
+ $use_w += ($w/$this->incrementFPR3);
+ }
+ else {
+ $use_w += ($w/$this->incrementFPR4);
+ }
+
+ $use_h = $use_w * $target ;
+ $this->rMargin=$this->w - $use_w - $x;
+ $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
+ $this->HTMLheaderPageLinks = array();
+ $this->HTMLheaderPageAnnots = array();
+ $this->HTMLheaderPageForms = array();
+ $this->pageBackgrounds = array();
+ $this->WriteHTML($html , 4); // parameter 4 saves output to $this->headerbuffer
+ $actual_h = $this->y - $y;
+ $ratio = $actual_h / $use_w;
+ }
+ if ($this->progressBar) { $this->UpdateProgressBar(4,'100',' '); } // *PROGRESS-BAR*
+ }
+ $shrink_f = $w/$use_w;
+
+ //================================================================
+
+ $this->pages[$this->page] .= '___BEFORE_BORDERS___';
+ $block_s = $this->PrintPageBackgrounds(); // Save to print later inside clipping path
+ $this->pageBackgrounds = array();
+
+ //================================================================
+
+ if ($rotate == 90 || $rotate==-90) { // mPDF 6
+ $prerotw = $bbox_bl + $bbox_pl + $inner_w + $bbox_pr + $bbox_br;
+ $preroth = $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb;
+ $rot_start = " q\n";
+ if ($rotate == 90) {
+ if ($rot_rpos !== false) { $adjw = $prerotw; } // width before rotation
+ else { $adjw = $preroth; } // height before rotation
+ if ($rot_bpos !== false) { $adjh = -$prerotw + $preroth; }
+ else { $adjh = 0; }
+ }
+ else {
+ if ($rot_rpos !== false) { $adjw = $prerotw - $preroth; }
+ else { $adjw = 0; }
+ if ($rot_bpos !== false) { $adjh = $preroth; } // height before rotation
+ else { $adjh = $prerotw; } // width before rotation
+ }
+ $rot_start .= $this->transformTranslate($adjw, $adjh, true)."\n";
+ $rot_start .= $this->transformRotate($rotate, $bbox_x, $bbox_y, true)."\n";
+ $rot_end = " Q\n";
+ }
+ else if ($rotate == 180) { // mPDF 6
+ $rot_start = " q\n";
+ $rot_start .= $this->transformTranslate($bbox_bl + $bbox_pl + $inner_w + $bbox_pr + $bbox_br, $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb, true)."\n";
+ $rot_start .= $this->transformRotate(180, $bbox_x, $bbox_y, true)."\n";
+ $rot_end = " Q\n";
+ }
+ else {
+ $rot_start = '';
+ $rot_end = '';
+ }
+
+ //================================================================
+ if (!empty($bounding)) {
+ // WHEN HEIGHT // BOTTOM EDGE IS KNOWN and $this->y is set to the bottom
+ // Re-instate saved $this->blk[1]
+ $this->blk[1] = $saved_block1;
+
+ // These are only needed when painting border/background
+ $this->blk[1]['width'] = $bbox_w = $cont_w - $bbox_left - $bbox_ml - $bbox_mr - $bbox_right;
+ $this->blk[1]['x0'] = $bbox_x;
+ $this->blk[1]['y0'] = $bbox_y;
+ $this->blk[1]['startpage'] = $this->page;
+ $this->blk[1]['y1'] = $bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb ;
+ $this->_out($rot_start);
+ $this->PaintDivBB('',0,1); // Prints borders and sets backgrounds in $this->pageBackgrounds
+ $this->_out($rot_end);
+ }
+
+ $s = $this->PrintPageBackgrounds();
+ $s = $rot_start.$s.$rot_end;
+ $this->pages[$this->page] = preg_replace('/___BEFORE_BORDERS___/', "\n".$s."\n", $this->pages[$this->page]);
+ $this->pageBackgrounds = array();
+
+ $this->_out($rot_start);
+
+ // Clipping Output
+ if ($overflow=='hidden') {
+ //Bounding rectangle to clip
+ $clip_y1 = $this->y;
+ if (!empty($bounding) && ($this->y + $bbox_pb + $bbox_bb) > ($bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb )) {
+ $clip_y1 = ($bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb ) - ($bbox_pb + $bbox_bb);
+ }
+ //$op = 'W* n'; // Clipping
+ $op = 'W n'; // Clipping alternative mode
+ $this->_out("q");
+ $ch = $clip_y1 - $y;
+ $this->_out(sprintf('%.3F %.3F %.3F %.3F re %s',$x*_MPDFK,($this->h-$y)*_MPDFK,$w*_MPDFK,-$ch*_MPDFK,$op));
+ if (!empty($block_s)) {
+ $tmp = "q\n".sprintf('%.3F %.3F %.3F %.3F re %s',$x*_MPDFK,($this->h-$y)*_MPDFK,$w*_MPDFK,-$ch*_MPDFK,$op);
+ $tmp .= "\n".$block_s."\nQ";
+ $block_s = $tmp ;
+ }
+ }
+
+
+ if (!empty($block_s)) {
+ if ($shrink_f != 1) { // i.e. autofit has resized the box
+ $tmp = "q\n".$this->transformScale(($shrink_f*100),($shrink_f*100), $x, $y, true);
+ $tmp .= "\n".$block_s."\nQ";
+ $block_s = $tmp ;
+ }
+ $this->_out($block_s);
+ }
+
+
+
+ if ($shrink_f != 1) { // i.e. autofit has resized the box
+ $this->StartTransform();
+ $this->transformScale(($shrink_f*100),($shrink_f*100), $x, $y);
+ }
+
+ $this->_out($this->headerbuffer);
+
+ if ($shrink_f != 1) { // i.e. autofit has resized the box
+ $this->StopTransform();
+ }
+
+ if ($overflow=='hidden') {
+ //End clipping
+ $this->_out("Q");
+ }
+
+ $this->_out($rot_end);
+
+
+ // Page Links
+ foreach($this->HTMLheaderPageLinks AS $lk) {
+ if ($rotate) {
+ $tmp = $lk[2]; // Switch h - w
+ $lk[2] = $lk[3];
+ $lk[3] = $tmp;
+
+ $lx1 = (($lk[0]/_MPDFK));
+ $ly1 = (($this->h-($lk[1]/_MPDFK)));
+ if ($rotate == 90) {
+ $adjx = -($lx1-$bbox_x) + ($preroth - ($ly1-$bbox_y));
+ $adjy = -($ly1-$bbox_y) + ($lx1-$bbox_x);
+ $lk[2] = -$lk[2];
+ }
+ else if ($rotate == -90) {
+ $adjx = -($lx1-$bbox_x) + ($ly1-$bbox_y);
+ $adjy = -($ly1-$bbox_y) - ($lx1-$bbox_x) + $prerotw;
+ $lk[3] = -$lk[3];
+ }
+ if ($rot_rpos !== false) { $adjx += $prerotw - $preroth; }
+ if ($rot_bpos !== false) { $adjy += $preroth - $prerotw; }
+ $lx1 += $adjx;
+ $ly1 += $adjy;
+
+ $lk[0] = $lx1*_MPDFK;
+ $lk[1] = ($this->h-$ly1)*_MPDFK;
+ }
+ if ($shrink_f != 1) { // i.e. autofit has resized the box
+ $lx1 = (($lk[0]/_MPDFK)-$x);
+ $lx2 = $x + ($lx1 * $shrink_f);
+ $lk[0] = $lx2*_MPDFK;
+ $ly1 = (($this->h-($lk[1]/_MPDFK))-$y);
+ $ly2 = $y + ($ly1 * $shrink_f);
+ $lk[1] = ($this->h-$ly2)*_MPDFK;
+ $lk[2] *= $shrink_f; // width
+ $lk[3] *= $shrink_f; // height
+ }
+ $this->PageLinks[$this->page][]=$lk;
+ }
+
+ foreach($this->HTMLheaderPageForms AS $n=>$f) {
+ if ($shrink_f != 1) { // i.e. autofit has resized the box
+ $f['x'] = $x + (($f['x'] -$x) * $shrink_f);
+ $f['y'] = $y + (($f['y'] -$y) * $shrink_f);
+ $f['w'] *= $shrink_f;
+ $f['h'] *= $shrink_f;
+ $f['style']['fontsize'] *= $shrink_f;
+ }
+ $this->mpdfform->forms[$f['n']] = $f;
+ }
+ // Page Annotations
+ foreach($this->HTMLheaderPageAnnots AS $lk) {
+ if ($rotate) {
+ if ($rotate == 90) {
+ $adjx = -($lk['x']-$bbox_x) + ($preroth - ($lk['y']-$bbox_y));
+ $adjy = -($lk['y']-$bbox_y) + ($lk['x']-$bbox_x);
+ }
+ else if ($rotate == -90) {
+ $adjx = -($lk['x']-$bbox_x) + ($lk['y']-$bbox_y);
+ $adjy = -($lk['y']-$bbox_y) - ($lk['x']-$bbox_x) + $prerotw;
+ }
+ if ($rot_rpos !== false) { $adjx += $prerotw - $preroth; }
+ if ($rot_bpos !== false) { $adjy += $preroth - $prerotw; }
+ $lk['x'] += $adjx;
+ $lk['y'] += $adjy;
+ }
+ if ($shrink_f != 1) { // i.e. autofit has resized the box
+ $lk['x'] = $x + (($lk['x']-$x) * $shrink_f);
+ $lk['y'] = $y + (($lk['y']-$y) * $shrink_f);
+ }
+ $this->PageAnnots[$this->page][]=$lk;
+ }
+
+ // Restore
+ $this->headerbuffer = '';
+ $this->HTMLheaderPageLinks = array();
+ $this->HTMLheaderPageAnnots = array();
+ $this->HTMLheaderPageForms = array();
+ $this->pageBackgrounds = $save_bgs;
+ $this->writingHTMLheader = false;
+
+ $this->writingHTMLfooter = false;
+ $this->fullImageHeight = false;
+ $this->ResetMargins();
+ $this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
+ $this->SetXY($save_x,$save_y) ;
+ $this->title2annots = $save_annots; // *ANNOTATIONS*
+ $this->InFooter = false; // turns back on autopagebreaks
+ $this->pageoutput[$this->page]=array();
+ $this->pageoutput[$this->page]['Font']='';
+/*-- COLUMNS --*/
+ if ($save_cols) {
+ $this->SetColumns($save_nbcol,$this->colvAlign,$this->ColGap);
+ }
+/*-- END COLUMNS --*/
+}
+/*-- END CSS-POSITION --*/
+
+
+
+function initialiseBlock(&$blk) {
+ $blk['margin_top'] = 0;
+ $blk['margin_left'] = 0;
+ $blk['margin_bottom'] = 0;
+ $blk['margin_right'] = 0;
+ $blk['padding_top'] = 0;
+ $blk['padding_left'] = 0;
+ $blk['padding_bottom'] = 0;
+ $blk['padding_right'] = 0;
+ $blk['border_top']['w'] = 0;
+ $blk['border_left']['w'] = 0;
+ $blk['border_bottom']['w'] = 0;
+ $blk['border_right']['w'] = 0;
+ $blk['direction'] = 'ltr';
+ $blk['hide'] = false;
+ $blk['outer_left_margin'] = 0;
+ $blk['outer_right_margin'] = 0;
+ $blk['cascadeCSS'] = array();
+ $blk['block-align'] = false;
+ $blk['bgcolor'] = false;
+ $blk['page_break_after_avoid'] = false;
+ $blk['keep_block_together'] = false;
+ $blk['float'] = false;
+ $blk['line_height'] = '';
+ $blk['margin_collapse'] = false;
+}
+
+
+function border_details($bd) {
+ $prop = preg_split('/\s+/',trim($bd));
+
+ if (isset($this->blk[$this->blklvl]['inner_width'])) { $refw = $this->blk[$this->blklvl]['inner_width']; }
+ else if (isset($this->blk[$this->blklvl-1]['inner_width'])) { $refw = $this->blk[$this->blklvl-1]['inner_width']; }
+ else { $refw = $this->w; }
+ if ( count($prop) == 1 ) {
+ $bsize = $this->ConvertSize($prop[0],$refw,$this->FontSize,false);
+ if ($bsize > 0) {
+ return array('s' => 1, 'w' => $bsize, 'c' => $this->ConvertColor(0), 'style'=>'solid');
+ }
+ else { return array('w' => 0, 's' => 0); }
+ }
+
+ else if (count($prop) == 2 ) {
+ // 1px solid
+ if (in_array($prop[1],$this->borderstyles) || $prop[1] == 'none' || $prop[1] == 'hidden' ) { $prop[2] = ''; }
+ // solid #000000
+ else if (in_array($prop[0],$this->borderstyles) || $prop[0] == 'none' || $prop[0] == 'hidden' ) { $prop[0] = ''; $prop[1] = $prop[0]; $prop[2] = $prop[1]; }
+ // 1px #000000
+ else { $prop[1] = ''; $prop[2] = $prop[1]; }
+ }
+ else if ( count($prop) == 3 ) {
+ // Change #000000 1px solid to 1px solid #000000 (proper)
+ if (substr($prop[0],0,1) == '#') { $tmp = $prop[0]; $prop[0] = $prop[1]; $prop[1] = $prop[2]; $prop[2] = $tmp; }
+ // Change solid #000000 1px to 1px solid #000000 (proper)
+ else if (substr($prop[0],1,1) == '#') { $tmp = $prop[1]; $prop[0] = $prop[2]; $prop[1] = $prop[0]; $prop[2] = $tmp; }
+ // Change solid 1px #000000 to 1px solid #000000 (proper)
+ else if (in_array($prop[0],$this->borderstyles) || $prop[0] == 'none' || $prop[0] == 'hidden' ) {
+ $tmp = $prop[0]; $prop[0] = $prop[1]; $prop[1] = $tmp;
+ }
+ }
+ else { return array(); }
+ // Size
+ $bsize = $this->ConvertSize($prop[0],$refw,$this->FontSize,false);
+ //color
+ $coul = $this->ConvertColor($prop[2]); // returns array
+ // Style
+ $prop[1] = strtolower($prop[1]);
+ if (in_array($prop[1],$this->borderstyles) && $bsize > 0) { $on = 1; }
+ else if ($prop[1] == 'hidden') { $on = 1; $bsize = 0; $coul = ''; }
+ else if ($prop[1] == 'none') { $on = 0; $bsize = 0; $coul = ''; }
+ else { $on = 0; $bsize = 0; $coul = ''; $prop[1] = ''; }
+ return array('s' => $on, 'w' => $bsize, 'c' => $coul, 'style'=> $prop[1] );
+}
+
+
+
+/*-- END HTML-CSS --*/
+
+
+/*-- BORDER-RADIUS --*/
+function _borderPadding($a, $b, &$px, &$py) {
+ // $px and py are padding long axis (x) and short axis (y)
+ $added = 0; // extra padding
+
+ $x = $a-$px;
+ $y = $b-$py;
+ // Check if Falls within ellipse of border radius
+ if ( ( (($x+$added)*($x+$added))/($a*$a) + (($y+$added)*($y+$added))/($b*$b) ) <=1 ) { return false; }
+
+ $t = atan2($y,$x);
+
+ $newx = $b / sqrt((($b*$b)/($a*$a)) + ( tan($t) * tan($t) ) );
+ $newy = $a / sqrt((($a*$a)/($b*$b)) + ( (1/tan($t)) * (1/tan($t)) ) );
+ $px = max($px, $a - $newx + $added);
+ $py = max($py, $b - $newy + $added);
+}
+/*-- END BORDER-RADIUS --*/
+
+
+
+/*-- HTML-CSS --*/
+
+
+/*-- CSS-PAGE --*/
+function SetPagedMediaCSS($name='', $first, $oddEven) {
+ if ($oddEven == 'E') {
+ if ($this->directionality=='rtl') { $side = 'R'; }
+ else { $side = 'L'; }
+ }
+ else {
+ if ($this->directionality=='rtl') { $side = 'L'; }
+ else { $side = 'R'; }
+ }
+ $name = strtoupper($name);
+ $p = array();
+ $p['SIZE'] = 'AUTO';
+
+ // Uses mPDF original margins as default
+ $p['MARGIN-RIGHT'] = strval($this->orig_rMargin).'mm';
+ $p['MARGIN-LEFT'] = strval($this->orig_lMargin).'mm';
+ $p['MARGIN-TOP'] = strval($this->orig_tMargin).'mm';
+ $p['MARGIN-BOTTOM'] = strval($this->orig_bMargin).'mm';
+ $p['MARGIN-HEADER'] = strval($this->orig_hMargin).'mm';
+ $p['MARGIN-FOOTER'] = strval($this->orig_fMargin).'mm';
+
+ // Basic page + selector
+ if (isset($this->cssmgr->CSS['@PAGE'])) { $zp = $this->cssmgr->CSS['@PAGE']; }
+ else { $zp = array(); }
+ if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
+
+ if (isset($p['EVEN-HEADER-NAME']) && $oddEven=='E') {
+ $p['HEADER'] = $p['EVEN-HEADER-NAME']; unset($p['EVEN-HEADER-NAME']);
+ }
+ if (isset($p['ODD-HEADER-NAME']) && $oddEven!='E') {
+ $p['HEADER'] = $p['ODD-HEADER-NAME']; unset($p['ODD-HEADER-NAME']);
+ }
+ if (isset($p['EVEN-FOOTER-NAME']) && $oddEven=='E') {
+ $p['FOOTER'] = $p['EVEN-FOOTER-NAME']; unset($p['EVEN-FOOTER-NAME']);
+ }
+ if (isset($p['ODD-FOOTER-NAME']) && $oddEven!='E') {
+ $p['FOOTER'] = $p['ODD-FOOTER-NAME']; unset($p['ODD-FOOTER-NAME']);
+ }
+
+ // If right/Odd page
+ if (isset($this->cssmgr->CSS['@PAGE>>PSEUDO>>RIGHT']) && $side=='R') {
+ $zp = $this->cssmgr->CSS['@PAGE>>PSEUDO>>RIGHT'];
+ }
+ else { $zp = array(); }
+ if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
+ if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
+ // Disallow margin-left or -right on :LEFT or :RIGHT
+ if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
+ if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
+ if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
+
+ // If left/Even page
+ if (isset($this->cssmgr->CSS['@PAGE>>PSEUDO>>LEFT']) && $side=='L') {
+ $zp = $this->cssmgr->CSS['@PAGE>>PSEUDO>>LEFT'];
+ }
+ else { $zp = array(); }
+ if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
+ if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
+ // Disallow margin-left or -right on :LEFT or :RIGHT
+ if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
+ if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
+ if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
+
+ // If first page
+ if (isset($this->cssmgr->CSS['@PAGE>>PSEUDO>>FIRST']) && $first) { $zp = $this->cssmgr->CSS['@PAGE>>PSEUDO>>FIRST']; }
+ else { $zp = array(); }
+ if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
+ if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
+ // Disallow margin-left or -right on :FIRST // mPDF 5.7.3
+ if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
+ if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
+ if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
+
+ // If named page
+ if ($name) {
+ if (isset($this->cssmgr->CSS['@PAGE>>NAMED>>'.$name])) { $zp = $this->cssmgr->CSS['@PAGE>>NAMED>>'.$name]; }
+ else { $zp = array(); }
+ if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
+
+ if (isset($p['EVEN-HEADER-NAME']) && $oddEven=='E') {
+ $p['HEADER'] = $p['EVEN-HEADER-NAME']; unset($p['EVEN-HEADER-NAME']);
+ }
+ if (isset($p['ODD-HEADER-NAME']) && $oddEven!='E') {
+ $p['HEADER'] = $p['ODD-HEADER-NAME']; unset($p['ODD-HEADER-NAME']);
+ }
+ if (isset($p['EVEN-FOOTER-NAME']) && $oddEven=='E') {
+ $p['FOOTER'] = $p['EVEN-FOOTER-NAME']; unset($p['EVEN-FOOTER-NAME']);
+ }
+ if (isset($p['ODD-FOOTER-NAME']) && $oddEven!='E') {
+ $p['FOOTER'] = $p['ODD-FOOTER-NAME']; unset($p['ODD-FOOTER-NAME']);
+ }
+
+ // If named right/Odd page
+ if (isset($this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>RIGHT']) && $side=='R') { $zp = $this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>RIGHT']; }
+ else { $zp = array(); }
+ if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
+ if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
+ // Disallow margin-left or -right on :LEFT or :RIGHT
+ if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
+ if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
+ if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
+
+ // If named left/Even page
+ if (isset($this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>LEFT']) && $side=='L') { $zp = $this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>LEFT']; }
+ else { $zp = array(); }
+ if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
+ if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
+ // Disallow margin-left or -right on :LEFT or :RIGHT
+ if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
+ if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
+ if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
+
+ // If named first page
+ if (isset($this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>FIRST']) && $first) { $zp = $this->cssmgr->CSS['@PAGE>>NAMED>>'.$name.'>>PSEUDO>>FIRST']; }
+ else { $zp = array(); }
+ if (isset($zp['SIZE'])) { unset($zp['SIZE']); }
+ if (isset($zp['SHEET-SIZE'])) { unset($zp['SHEET-SIZE']); }
+ // Disallow margin-left or -right on :FIRST // mPDF 5.7.3
+ if (isset($zp['MARGIN-LEFT'])) { unset($zp['MARGIN-LEFT']); }
+ if (isset($zp['MARGIN-RIGHT'])) { unset($zp['MARGIN-RIGHT']); }
+ if (is_array($zp) && !empty($zp)) { $p = array_merge($p,$zp); }
+ }
+
+ $orientation = $mgl = $mgr = $mgt = $mgb = $mgh = $mgf = '';
+ $header = $footer = '';
+ $resetpagenum = $pagenumstyle = $suppress = '';
+ $marks = '';
+ $bg = array();
+
+ $newformat = '';
+
+
+ if (isset($p['SHEET-SIZE']) && is_array($p['SHEET-SIZE'])) {
+ $newformat = $p['SHEET-SIZE'];
+ if ($newformat[0] > $newformat[1]) { // landscape
+ $newformat = array_reverse($newformat);
+ $p['ORIENTATION'] = 'L';
+ }
+ else { $p['ORIENTATION'] = 'P'; }
+ $this->_setPageSize($newformat, $p['ORIENTATION']);
+ }
+
+ if (isset($p['SIZE']) && is_array($p['SIZE']) && !$newformat) {
+ if ($p['SIZE']['W'] > $p['SIZE']['H']) { $p['ORIENTATION'] = 'L'; }
+ else { $p['ORIENTATION'] = 'P'; }
+ }
+ if (is_array($p['SIZE'])) {
+ if ($p['SIZE']['W'] > $this->fw) { $p['SIZE']['W'] = $this->fw; } // mPD 4.2 use fw not fPt
+ if ($p['SIZE']['H'] > $this->fh) { $p['SIZE']['H'] = $this->fh; }
+ if (($p['ORIENTATION']==$this->DefOrientation && !$newformat) || ($newformat && $p['ORIENTATION']=='P')) {
+ $outer_width_LR = ($this->fw - $p['SIZE']['W'])/2;
+ $outer_width_TB = ($this->fh - $p['SIZE']['H'])/2;
+ }
+ else {
+ $outer_width_LR = ($this->fh - $p['SIZE']['W'])/2;
+ $outer_width_TB = ($this->fw - $p['SIZE']['H'])/2;
+ }
+ $pgw = $p['SIZE']['W'];
+ $pgh = $p['SIZE']['H'];
+ }
+ else { // AUTO LANDSCAPE PORTRAIT
+ $outer_width_LR = 0;
+ $outer_width_TB = 0;
+ if (!$newformat) {
+ if (strtoupper($p['SIZE']) == 'AUTO') { $p['ORIENTATION']=$this->DefOrientation; }
+ else if (strtoupper($p['SIZE']) == 'LANDSCAPE') { $p['ORIENTATION']='L'; }
+ else { $p['ORIENTATION']='P'; }
+ }
+ if (($p['ORIENTATION']==$this->DefOrientation && !$newformat) || ($newformat && $p['ORIENTATION']=='P')) {
+ $pgw = $this->fw;
+ $pgh = $this->fh;
+ }
+ else {
+ $pgw = $this->fh;
+ $pgh = $this->fw;
+ }
+ }
+
+ if (isset($p['HEADER']) && $p['HEADER']) { $header = $p['HEADER']; }
+ if (isset($p['FOOTER']) && $p['FOOTER']) { $footer = $p['FOOTER']; }
+ if (isset($p['RESETPAGENUM']) && $p['RESETPAGENUM']) { $resetpagenum = $p['RESETPAGENUM']; }
+ if (isset($p['PAGENUMSTYLE']) && $p['PAGENUMSTYLE']) { $pagenumstyle = $p['PAGENUMSTYLE']; }
+ if (isset($p['SUPPRESS']) && $p['SUPPRESS']) { $suppress = $p['SUPPRESS']; }
+
+ if (isset($p['MARKS'])) {
+ if (preg_match('/cross/i', $p['MARKS']) && preg_match('/crop/i', $p['MARKS'])) { $marks = 'CROPCROSS'; }
+ else if (strtoupper($p['MARKS']) == 'CROP') { $marks = 'CROP'; }
+ else if (strtoupper($p['MARKS']) == 'CROSS') { $marks = 'CROSS'; }
+ }
+
+ if (isset($p['BACKGROUND-COLOR']) && $p['BACKGROUND-COLOR']) { $bg['BACKGROUND-COLOR'] = $p['BACKGROUND-COLOR']; }
+/*-- BACKGROUNDS --*/
+ if (isset($p['BACKGROUND-GRADIENT']) && $p['BACKGROUND-GRADIENT']) { $bg['BACKGROUND-GRADIENT'] = $p['BACKGROUND-GRADIENT']; }
+ if (isset($p['BACKGROUND-IMAGE']) && $p['BACKGROUND-IMAGE']) { $bg['BACKGROUND-IMAGE'] = $p['BACKGROUND-IMAGE']; }
+ if (isset($p['BACKGROUND-REPEAT']) && $p['BACKGROUND-REPEAT']) { $bg['BACKGROUND-REPEAT'] = $p['BACKGROUND-REPEAT']; }
+ if (isset($p['BACKGROUND-POSITION']) && $p['BACKGROUND-POSITION']) { $bg['BACKGROUND-POSITION'] = $p['BACKGROUND-POSITION']; }
+ if (isset($p['BACKGROUND-IMAGE-RESIZE']) && $p['BACKGROUND-IMAGE-RESIZE']) { $bg['BACKGROUND-IMAGE-RESIZE'] = $p['BACKGROUND-IMAGE-RESIZE']; }
+ if (isset($p['BACKGROUND-IMAGE-OPACITY'])) { $bg['BACKGROUND-IMAGE-OPACITY'] = $p['BACKGROUND-IMAGE-OPACITY']; }
+/*-- END BACKGROUNDS --*/
+
+ if (isset($p['MARGIN-LEFT'])) { $mgl = $this->ConvertSize($p['MARGIN-LEFT'],$pgw) + $outer_width_LR; }
+ if (isset($p['MARGIN-RIGHT'])) { $mgr = $this->ConvertSize($p['MARGIN-RIGHT'],$pgw) + $outer_width_LR; }
+ if (isset($p['MARGIN-BOTTOM'])) { $mgb = $this->ConvertSize($p['MARGIN-BOTTOM'],$pgh) + $outer_width_TB; }
+ if (isset($p['MARGIN-TOP'])) { $mgt = $this->ConvertSize($p['MARGIN-TOP'],$pgh) + $outer_width_TB; }
+ if (isset($p['MARGIN-HEADER'])) { $mgh = $this->ConvertSize($p['MARGIN-HEADER'],$pgh) + $outer_width_TB; }
+ if (isset($p['MARGIN-FOOTER'])) { $mgf = $this->ConvertSize($p['MARGIN-FOOTER'],$pgh) + $outer_width_TB; }
+
+ if (isset($p['ORIENTATION']) && $p['ORIENTATION']) { $orientation = $p['ORIENTATION']; }
+ $this->page_box['outer_width_LR'] = $outer_width_LR; // Used in MARKS:crop etc.
+ $this->page_box['outer_width_TB'] = $outer_width_TB;
+
+ return array($orientation,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$header,$footer,$bg,$resetpagenum,$pagenumstyle,$suppress,$marks,$newformat);
+}
+/*-- END CSS-PAGE --*/
+
+
+
+/*-- CSS-FLOAT --*/
+// Added mPDF 3.0 Float DIV - CLEAR
+function ClearFloats($clear, $blklvl=0) {
+ list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($blklvl,true);
+ $end = $currpos = ($this->page*1000 + $this->y);
+ if ($clear == 'BOTH' && ($l_exists || $r_exists)) {
+ $this->pageoutput[$this->page] = array();
+ $end = max($l_max, $r_max, $currpos);
+ }
+ else if ($clear == 'RIGHT' && $r_exists) {
+ $this->pageoutput[$this->page] = array();
+ $end = max($r_max, $currpos);
+ }
+ else if ($clear == 'LEFT' && $l_exists ) {
+ $this->pageoutput[$this->page] = array();
+ $end = max($l_max, $currpos);
+ }
+ else { return; }
+ $old_page = $this->page;
+ $new_page = intval($end/1000);
+ if ($old_page != $new_page) {
+ $s = $this->PrintPageBackgrounds();
+ // Writes after the marker so not overwritten later by page background etc.
+ $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
+ $this->pageBackgrounds = array();
+ $this->page = $new_page;
+ }
+ $this->ResetMargins();
+ $this->pageoutput[$this->page] = array();
+ $this->y = (($end*1000) % 1000000)/1000; // mod changes operands to integers before processing
+}
+
+
+// Added mPDF 3.0 Float DIV
+function GetFloatDivInfo($blklvl=0,$clear=false) {
+ // If blklvl specified, only returns floats at that level - for ClearFloats
+ $l_exists = false;
+ $r_exists = false;
+ $l_max = 0;
+ $r_max = 0;
+ $l_width = 0;
+ $r_width = 0;
+ if (count($this->floatDivs)) {
+ $currpos = ($this->page*1000 + $this->y);
+ foreach($this->floatDivs AS $f) {
+ if (($clear && $f['blockContext'] == $this->blk[$blklvl]['blockContext']) || (!$clear && $currpos >= $f['startpos'] && $currpos < ($f['endpos']-0.001) && $f['blklvl'] > $blklvl && $f['blockContext'] == $this->blk[$blklvl]['blockContext'])) {
+ if ($f['side']=='L') {
+ $l_exists= true;
+ $l_max = max($l_max, $f['endpos']);
+ $l_width = max($l_width , $f['w']);
+ }
+ if ($f['side']=='R') {
+ $r_exists= true;
+ $r_max = max($r_max, $f['endpos']);
+ $r_width = max($r_width , $f['w']);
+ }
+ }
+ }
+ }
+ return array($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width);
+}
+/*-- END CSS-FLOAT --*/
+
+
+
+
+function OpenTag($tag,$attr,&$ahtml,&$ihtml) { // mPDF 6
+ //Opening tag
+
+ // mPDF 6
+ // Correct for tags where HTML5 specifies optional end tags excluding table elements (cf WriteHTML() )
+ if ($this->allow_html_optional_endtags) {
+ if (isset($this->blk[$this->blklvl]['tag'])) {
+ $closed = false;
+ // li end tag may be omitted if immediately followed by another li element
+ if (!$closed && $this->blk[$this->blklvl]['tag']=='LI' && $tag=='LI') { $this->CloseTag('LI',$ahtml,$ihtml); $closed = true; }
+ // dt end tag may be omitted if immediately followed by another dt element or a dd element
+ if (!$closed && $this->blk[$this->blklvl]['tag']=='DT' && ($tag=='DT' || $tag=='DD')) { $this->CloseTag('DT',$ahtml,$ihtml); $closed = true; }
+ // dd end tag may be omitted if immediately followed by another dd element or a dt element
+ if (!$closed && $this->blk[$this->blklvl]['tag']=='DD' && ($tag=='DT' || $tag=='DD')) { $this->CloseTag('DD',$ahtml,$ihtml); $closed = true; }
+ // p end tag may be omitted if immediately followed by an address, article, aside, blockquote, div, dl, fieldset, form,
+ // h1, h2, h3, h4, h5, h6, hgroup, hr, main, nav, ol, p, pre, section, table, ul
+ if (!$closed && $this->blk[$this->blklvl]['tag']=='P' && ($tag == 'P' || $tag == 'DIV' || $tag == 'H1' || $tag == 'H2' || $tag == 'H3' || $tag == 'H4' || $tag == 'H5' || $tag == 'H6' || $tag == 'UL' || $tag == 'OL' || $tag == 'TABLE' || $tag=='PRE' || $tag=='FORM' || $tag=='ADDRESS' || $tag=='BLOCKQUOTE' || $tag=='CENTER' || $tag=='DL' || $tag == 'HR' || $tag=='ARTICLE' || $tag=='ASIDE' || $tag=='FIELDSET' || $tag=='HGROUP' || $tag=='MAIN' || $tag=='NAV' || $tag=='SECTION')) { $this->CloseTag('P',$ahtml,$ihtml); $closed = true; }
+ // option end tag may be omitted if immediately followed by another option element (or if it is immediately followed by an optgroup element)
+ if (!$closed && $this->blk[$this->blklvl]['tag']=='OPTION' && $tag=='OPTION') { $this->CloseTag('OPTION',$ahtml,$ihtml); $closed = true; }
+ // Table elements - see also WriteHTML()
+ if (!$closed && ($tag == 'TD' || $tag == 'TH') && $this->lastoptionaltag == 'TD') { $this->CloseTag($this->lastoptionaltag,$ahtml,$ihtml); $closed = true; } // *TABLES*
+ if (!$closed && ($tag == 'TD' || $tag == 'TH') && $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag,$ahtml,$ihtml); $closed = true; } // *TABLES*
+ if (!$closed && $tag == 'TR' && $this->lastoptionaltag == 'TR') { $this->CloseTag($this->lastoptionaltag,$ahtml,$ihtml); $closed = true; } // *TABLES*
+ if (!$closed && $tag == 'TR' && $this->lastoptionaltag == 'TD') { $this->CloseTag($this->lastoptionaltag,$ahtml,$ihtml); $this->CloseTag('TR',$ahtml,$ihtml); $this->CloseTag('THEAD',$ahtml,$ihtml); $closed = true; } // *TABLES*
+ if (!$closed && $tag == 'TR' && $this->lastoptionaltag == 'TH') { $this->CloseTag($this->lastoptionaltag,$ahtml,$ihtml); $this->CloseTag('TR',$ahtml,$ihtml); $this->CloseTag('THEAD',$ahtml,$ihtml); $closed = true; } // *TABLES*
+ }
+ }
+
+ $align = array('left'=>'L','center'=>'C','right'=>'R','top'=>'T','text-top'=>'TT','middle'=>'M','baseline'=>'BS','bottom'=>'B','text-bottom'=>'TB','justify'=>'J');
+
+
+
+ switch($tag){
+
+ case 'DOTTAB':
+ $objattr = array();
+ $objattr['type'] = 'dottab';
+ $dots=str_repeat('.', 3)." "; // minimum number of dots
+ $objattr['width'] = $this->GetStringWidth($dots);
+ $objattr['margin_top'] = 0;
+ $objattr['margin_bottom'] = 0;
+ $objattr['margin_left'] = 0;
+ $objattr['margin_right'] = 0;
+ $objattr['height'] = 0;
+ $objattr['colorarray'] = $this->colorarray;
+ $objattr['border_top']['w'] = 0;
+ $objattr['border_bottom']['w'] = 0;
+ $objattr['border_left']['w'] = 0;
+ $objattr['border_right']['w'] = 0;
+ $objattr['vertical_align'] = 'BS'; // mPDF 6 DOTTAB
+
+ $properties = $this->cssmgr->MergeCSS('INLINE',$tag,$attr);
+ if (isset($properties['OUTDENT'])) {
+ $objattr['outdent'] = $this->ConvertSize($properties['OUTDENT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ }
+ else if (isset($attr['OUTDENT'])) {
+ $objattr['outdent'] = $this->ConvertSize($attr['OUTDENT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ }
+ else { $objattr['outdent'] = 0; }
+
+ $objattr['fontfamily'] = $this->FontFamily;
+ $objattr['fontsize'] = $this->FontSizePt;
+
+ $e = "\xbb\xa4\xactype=dottab,objattr=".serialize($objattr)."\xbb\xa4\xac";
+/*-- TABLES --*/
+ // Output it to buffers
+ if ($this->tableLevel) {
+ if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
+ $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
+ }
+ elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
+ $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
+ }
+ $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
+ $this->_saveCellTextBuffer($e);
+ }
+ else {
+/*-- END TABLES --*/
+ $this->_saveTextBuffer($e);
+ } // *TABLES*
+ break;
+
+ case 'PAGEHEADER':
+ case 'PAGEFOOTER':
+ $this->ignorefollowingspaces = true;
+ if ($attr['NAME']) { $pname = $attr['NAME']; }
+ else { $pname = '_nonhtmldefault'; } // mPDF 6
+
+ $p=array(); // mPDF 6
+ $p['L']=array();
+ $p['C']=array();
+ $p['R']=array();
+ $p['L']['font-style'] = '';
+ $p['C']['font-style'] = '';
+ $p['R']['font-style'] = '';
+
+ if (isset($attr['CONTENT-LEFT'])) {
+ $p['L']['content'] = $attr['CONTENT-LEFT'];
+ }
+ if (isset($attr['CONTENT-CENTER'])) {
+ $p['C']['content'] = $attr['CONTENT-CENTER'];
+ }
+ if (isset($attr['CONTENT-RIGHT'])) {
+ $p['R']['content'] = $attr['CONTENT-RIGHT'];
+ }
+
+ if (isset($attr['HEADER-STYLE']) || isset($attr['FOOTER-STYLE'])) { // font-family,size,weight,style,color
+ if ($tag=='PAGEHEADER') { $properties = $this->cssmgr->readInlineCSS($attr['HEADER-STYLE']); }
+ else { $properties = $this->cssmgr->readInlineCSS($attr['FOOTER-STYLE']); }
+ if (isset($properties['FONT-FAMILY'])) {
+ $p['L']['font-family'] = $properties['FONT-FAMILY'];
+ $p['C']['font-family'] = $properties['FONT-FAMILY'];
+ $p['R']['font-family'] = $properties['FONT-FAMILY'];
+ }
+ if (isset($properties['FONT-SIZE'])) {
+ $p['L']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK;
+ $p['C']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK;
+ $p['R']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK;
+ }
+ if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') {
+ $p['L']['font-style'] = 'B';
+ $p['C']['font-style'] = 'B';
+ $p['R']['font-style'] = 'B';
+ }
+ if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') {
+ $p['L']['font-style'] .= 'I';
+ $p['C']['font-style'] .= 'I';
+ $p['R']['font-style'] .= 'I';
+ }
+ if (isset($properties['COLOR'])) {
+ $p['L']['color'] = $properties['COLOR'];
+ $p['C']['color'] = $properties['COLOR'];
+ $p['R']['color'] = $properties['COLOR'];
+ }
+ }
+ if (isset($attr['HEADER-STYLE-LEFT']) || isset($attr['FOOTER-STYLE-LEFT'])) {
+ if ($tag=='PAGEHEADER') { $properties = $this->cssmgr->readInlineCSS($attr['HEADER-STYLE-LEFT']); }
+ else { $properties = $this->cssmgr->readInlineCSS($attr['FOOTER-STYLE-LEFT']); }
+ if (isset($properties['FONT-FAMILY'])) { $p['L']['font-family'] = $properties['FONT-FAMILY']; }
+ if (isset($properties['FONT-SIZE'])) { $p['L']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK; }
+ if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') { $p['L']['font-style'] ='B'; }
+ if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') { $p['L']['font-style'] .='I'; }
+ if (isset($properties['COLOR'])) { $p['L']['color'] = $properties['COLOR']; }
+ }
+ if (isset($attr['HEADER-STYLE-CENTER']) || isset($attr['FOOTER-STYLE-CENTER'])) {
+ if ($tag=='PAGEHEADER') { $properties = $this->cssmgr->readInlineCSS($attr['HEADER-STYLE-CENTER']); }
+ else { $properties = $this->cssmgr->readInlineCSS($attr['FOOTER-STYLE-CENTER']); }
+ if (isset($properties['FONT-FAMILY'])) { $p['C']['font-family'] = $properties['FONT-FAMILY']; }
+ if (isset($properties['FONT-SIZE'])) { $p['C']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK; }
+ if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') { $p['C']['font-style'] = 'B'; }
+ if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') { $p['C']['font-style'] .= 'I'; }
+ if (isset($properties['COLOR'])) { $p['C']['color'] = $properties['COLOR']; }
+ }
+ if (isset($attr['HEADER-STYLE-RIGHT']) || isset($attr['FOOTER-STYLE-RIGHT'])) {
+ if ($tag=='PAGEHEADER') { $properties = $this->cssmgr->readInlineCSS($attr['HEADER-STYLE-RIGHT']); }
+ else { $properties = $this->cssmgr->readInlineCSS($attr['FOOTER-STYLE-RIGHT']); }
+ if (isset($properties['FONT-FAMILY'])) { $p['R']['font-family'] = $properties['FONT-FAMILY']; }
+ if (isset($properties['FONT-SIZE'])) { $p['R']['font-size'] = $this->ConvertSize($properties['FONT-SIZE']) * _MPDFK; }
+ if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT']=='bold') { $p['R']['font-style'] = 'B'; }
+ if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE']=='italic') { $p['R']['font-style'] .= 'I'; }
+ if (isset($properties['COLOR'])) { $p['R']['color'] = $properties['COLOR']; }
+ }
+ if (isset($attr['LINE']) && $attr['LINE']) { // 0|1|on|off
+ if ($attr['LINE']=='1' || strtoupper($attr['LINE'])=='ON') { $lineset=1; }
+ else { $lineset=0; }
+ $p['line'] = $lineset;
+ }
+ // mPDF 6
+ if ($tag=='PAGEHEADER') { $this->DefHeaderByName($pname,$p); }
+ else { $this->DefFooterByName($pname,$p); }
+ break;
+
+
+ case 'SETPAGEHEADER': // mPDF 6
+ case 'SETPAGEFOOTER':
+ case 'SETHTMLPAGEHEADER':
+ case 'SETHTMLPAGEFOOTER':
+ $this->ignorefollowingspaces = true;
+ if (isset($attr['NAME']) && $attr['NAME']) { $pname = $attr['NAME']; }
+ else if ($tag=='SETPAGEHEADER' || $tag=='SETPAGEFOOTER') { $pname = '_nonhtmldefault'; } // mPDF 6
+ else { $pname = '_default'; }
+ if (isset($attr['PAGE']) && $attr['PAGE']) { // O|odd|even|E|ALL|[blank]
+ if (strtoupper($attr['PAGE'])=='O' || strtoupper($attr['PAGE'])=='ODD') { $side='odd'; }
+ else if (strtoupper($attr['PAGE'])=='E' || strtoupper($attr['PAGE'])=='EVEN') { $side='even'; }
+ else if (strtoupper($attr['PAGE'])=='ALL') { $side='both'; }
+ else { $side='odd'; }
+ }
+ else { $side='odd'; }
+ if (isset($attr['VALUE']) && $attr['VALUE']) { // -1|1|on|off
+ if ($attr['VALUE']=='1' || strtoupper($attr['VALUE'])=='ON') { $set=1; }
+ else if ($attr['VALUE']=='-1' || strtoupper($attr['VALUE'])=='OFF') { $set=0; }
+ else { $set=1; }
+ }
+ else { $set=1; }
+ if (isset($attr['SHOW-THIS-PAGE']) && $attr['SHOW-THIS-PAGE'] && ($tag=='SETHTMLPAGEHEADER' || $tag=='SETPAGEHEADER')) { $write = 1; }
+ else { $write = 0; }
+ if ($side=='odd' || $side=='both') {
+ if ($set && ($tag=='SETHTMLPAGEHEADER' || $tag=='SETPAGEHEADER')) { $this->SetHTMLHeader($this->pageHTMLheaders[$pname],'O',$write); }
+ else if ($set && ($tag=='SETHTMLPAGEFOOTER' || $tag=='SETPAGEFOOTER')) { $this->SetHTMLFooter($this->pageHTMLfooters[$pname],'O'); }
+ else if ($tag=='SETHTMLPAGEHEADER' || $tag=='SETPAGEHEADER') { $this->SetHTMLHeader('','O'); }
+ else { $this->SetHTMLFooter('','O'); }
+ }
+ if ($side=='even' || $side=='both') {
+ if ($set && ($tag=='SETHTMLPAGEHEADER' || $tag=='SETPAGEHEADER')) { $this->SetHTMLHeader($this->pageHTMLheaders[$pname],'E',$write); }
+ else if ($set && ($tag=='SETHTMLPAGEFOOTER' || $tag=='SETPAGEFOOTER')) { $this->SetHTMLFooter($this->pageHTMLfooters[$pname],'E'); }
+ else if ($tag=='SETHTMLPAGEHEADER' || $tag=='SETPAGEHEADER') { $this->SetHTMLHeader('','E'); }
+ else { $this->SetHTMLFooter('','E'); }
+ }
+ break;
+
+
+
+/*-- TOC --*/
+ case 'TOC': //added custom-tag - set Marker for insertion later of ToC
+ if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
+ if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
+ $this->tocontents->openTagTOC($attr);
+ break;
+
+
+
+ case 'TOCPAGEBREAK': // custom-tag - set Marker for insertion later of ToC AND adds PAGEBREAK
+ if (!class_exists('tocontents', false)) { include(_MPDF_PATH.'classes/tocontents.php'); }
+ if (empty($this->tocontents)) { $this->tocontents = new tocontents($this); }
+ list($isbreak,$toc_id) = $this->tocontents->openTagTOCPAGEBREAK($attr);
+ if ($isbreak) break;
+ if (!isset($attr['RESETPAGENUM']) || $attr['RESETPAGENUM']<1) { $attr['RESETPAGENUM']=1; } // mPDF 6
+ // No break - continues as PAGEBREAK...
+/*-- END TOC --*/
+
+
+ case 'PAGE_BREAK': //custom-tag
+ case 'PAGEBREAK': //custom-tag
+ case 'NEWPAGE': //custom-tag
+ case 'FORMFEED': //custom-tag
+
+ if (isset($attr['SHEET-SIZE'])) {
+ // Convert to same types as accepted in initial mPDF() A4, A4-L, or array(w,h)
+ $prop = preg_split('/\s+/',trim($attr['SHEET-SIZE']));
+ if (count($prop) == 2 ) {
+ $newformat = array($this->ConvertSize($prop[0]), $this->ConvertSize($prop[1]));
+ }
+ else { $newformat = $attr['SHEET-SIZE']; }
+ }
+ else { $newformat = ''; }
+
+ $save_blklvl = $this->blklvl;
+ $save_blk = $this->blk;
+ $save_silp = $this->saveInlineProperties();
+ $save_ilp = $this->InlineProperties;
+ $save_bflp = $this->InlineBDF;
+ $save_bflpc = $this->InlineBDFctr; // mPDF 6
+
+ $mgr = $mgl = $mgt = $mgb = $mgh = $mgf = '';
+ if (isset($attr['MARGIN-RIGHT'])) { $mgr = $this->ConvertSize($attr['MARGIN-RIGHT'],$this->w,$this->FontSize,false); }
+ if (isset($attr['MARGIN-LEFT'])) { $mgl = $this->ConvertSize($attr['MARGIN-LEFT'],$this->w,$this->FontSize,false); }
+ if (isset($attr['MARGIN-TOP'])) { $mgt = $this->ConvertSize($attr['MARGIN-TOP'],$this->w,$this->FontSize,false); }
+ if (isset($attr['MARGIN-BOTTOM'])) { $mgb = $this->ConvertSize($attr['MARGIN-BOTTOM'],$this->w,$this->FontSize,false); }
+ if (isset($attr['MARGIN-HEADER'])) { $mgh = $this->ConvertSize($attr['MARGIN-HEADER'],$this->w,$this->FontSize,false); }
+ if (isset($attr['MARGIN-FOOTER'])) { $mgf = $this->ConvertSize($attr['MARGIN-FOOTER'],$this->w,$this->FontSize,false); }
+ $ohname = $ehname = $ofname = $efname = '';
+ if (isset($attr['ODD-HEADER-NAME'])) { $ohname = $attr['ODD-HEADER-NAME']; }
+ if (isset($attr['EVEN-HEADER-NAME'])) { $ehname = $attr['EVEN-HEADER-NAME']; }
+ if (isset($attr['ODD-FOOTER-NAME'])) { $ofname = $attr['ODD-FOOTER-NAME']; }
+ if (isset($attr['EVEN-FOOTER-NAME'])) { $efname = $attr['EVEN-FOOTER-NAME']; }
+ $ohvalue = $ehvalue = $ofvalue = $efvalue = 0;
+ if (isset($attr['ODD-HEADER-VALUE']) && ($attr['ODD-HEADER-VALUE']=='1' || strtoupper($attr['ODD-HEADER-VALUE'])=='ON')) { $ohvalue = 1; }
+ else if (isset($attr['ODD-HEADER-VALUE']) && ($attr['ODD-HEADER-VALUE']=='-1' || strtoupper($attr['ODD-HEADER-VALUE'])=='OFF')) { $ohvalue = -1; }
+ if (isset($attr['EVEN-HEADER-VALUE']) && ($attr['EVEN-HEADER-VALUE']=='1' || strtoupper($attr['EVEN-HEADER-VALUE'])=='ON')) { $ehvalue = 1; }
+ else if (isset($attr['EVEN-HEADER-VALUE']) && ($attr['EVEN-HEADER-VALUE']=='-1' || strtoupper($attr['EVEN-HEADER-VALUE'])=='OFF')) { $ehvalue = -1; }
+ if (isset($attr['ODD-FOOTER-VALUE']) && ($attr['ODD-FOOTER-VALUE']=='1' || strtoupper($attr['ODD-FOOTER-VALUE'])=='ON')) { $ofvalue = 1; }
+ else if (isset($attr['ODD-FOOTER-VALUE']) && ($attr['ODD-FOOTER-VALUE']=='-1' || strtoupper($attr['ODD-FOOTER-VALUE'])=='OFF')) { $ofvalue = -1; }
+ if (isset($attr['EVEN-FOOTER-VALUE']) && ($attr['EVEN-FOOTER-VALUE']=='1' || strtoupper($attr['EVEN-FOOTER-VALUE'])=='ON')) { $efvalue = 1; }
+ else if (isset($attr['EVEN-FOOTER-VALUE']) && ($attr['EVEN-FOOTER-VALUE']=='-1' || strtoupper($attr['EVEN-FOOTER-VALUE'])=='OFF')) { $efvalue = -1; }
+
+ if (isset($attr['ORIENTATION']) && (strtoupper($attr['ORIENTATION'])=='L' || strtoupper($attr['ORIENTATION'])=='LANDSCAPE')) { $orient = 'L'; }
+ else if (isset($attr['ORIENTATION']) && (strtoupper($attr['ORIENTATION'])=='P' || strtoupper($attr['ORIENTATION'])=='PORTRAIT')) { $orient = 'P'; }
+ else { $orient = $this->CurOrientation; }
+
+ if (isset($attr['PAGE-SELECTOR']) && $attr['PAGE-SELECTOR']) { $pagesel = $attr['PAGE-SELECTOR']; }
+ else { $pagesel = ''; }
+
+ // mPDF 6 pagebreaktype
+ $pagebreaktype = $this->defaultPagebreakType;
+ if ($tag == 'FORMFEED') { $pagebreaktype = 'slice'; } // can be overridden by PAGE-BREAK-TYPE
+ $startpage = $this->page;
+ if (isset($attr['PAGE-BREAK-TYPE'])) {
+ if (strtolower($attr['PAGE-BREAK-TYPE'])=='cloneall' || strtolower($attr['PAGE-BREAK-TYPE'])=='clonebycss' || strtolower($attr['PAGE-BREAK-TYPE'])=='slice') {
+ $pagebreaktype = strtolower($attr['PAGE-BREAK-TYPE']);
+ }
+ }
+ if ($tag == 'TOCPAGEBREAK') { $pagebreaktype = 'cloneall'; }
+ else if ($this->ColActive) { $pagebreaktype = 'cloneall'; }
+ // Any change in headers/footers (may need to _getHtmlHeight), or page size/orientation, @page selector, or margins - force cloneall
+ else if ($mgr!=='' || $mgl!=='' || $mgt!=='' || $mgb!=='' || $mgh!=='' || $mgf!=='' ||
+ $ohname!=='' || $ehname!=='' || $ofname!=='' || $efname!=='' ||
+ $ohvalue || $ehvalue || $ofvalue || $efvalue ||
+ $orient != $this->CurOrientation || $newformat || $pagesel) {
+ $pagebreaktype = 'cloneall';
+ }
+
+ // mPDF 6 pagebreaktype
+ $this->_preForcedPagebreak($pagebreaktype);
+
+ $this->ignorefollowingspaces = true;
+
+
+ $resetpagenum = '';
+ $pagenumstyle = '';
+ $suppress = '';
+ if (isset($attr['RESETPAGENUM'])) { $resetpagenum = $attr['RESETPAGENUM']; }
+ if (isset($attr['PAGENUMSTYLE'])) { $pagenumstyle = $attr['PAGENUMSTYLE']; }
+ if (isset($attr['SUPPRESS'])) { $suppress = $attr['SUPPRESS']; }
+
+ if ($tag == 'TOCPAGEBREAK') { $type = 'NEXT-ODD'; }
+ else if(isset($attr['TYPE'])) { $type = strtoupper($attr['TYPE']); }
+ else { $type = ''; }
+
+ if ($type == 'E' || $type == 'EVEN') { $this->AddPage($orient,'E', $resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat); }
+ else if ($type == 'O' || $type == 'ODD') { $this->AddPage($orient,'O', $resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat); }
+ else if ($type == 'NEXT-ODD') { $this->AddPage($orient,'NEXT-ODD', $resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat); }
+ else if ($type == 'NEXT-EVEN') { $this->AddPage($orient,'NEXT-EVEN', $resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat); }
+ else { $this->AddPage($orient,'', $resetpagenum, $pagenumstyle, $suppress,$mgl,$mgr,$mgt,$mgb,$mgh,$mgf,$ohname,$ehname,$ofname,$efname,$ohvalue,$ehvalue,$ofvalue,$efvalue,$pagesel,$newformat); }
+
+/*-- TOC --*/
+ if ($tag == 'TOCPAGEBREAK') {
+ if ($toc_id) { $this->tocontents->m_TOC[$toc_id]['TOCmark'] = $this->page; }
+ else { $this->tocontents->TOCmark = $this->page; }
+ }
+/*-- END TOC --*/
+
+ // mPDF 6 pagebreaktype
+ $this->_postForcedPagebreak($pagebreaktype, $startpage, $save_blk, $save_blklvl);
+
+ $this->InlineProperties = $save_ilp;
+ $this->InlineBDF = $save_bflp;
+ $this->InlineBDFctr = $save_bflpc; // mPDF 6
+ $this->restoreInlineProperties($save_silp);
+
+ break;
+
+
+/*-- TOC --*/
+ case 'TOCENTRY':
+ if (isset($attr['CONTENT']) && $attr['CONTENT']) {
+ $objattr = array();
+ $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
+ $objattr['type'] = 'toc';
+ $objattr['vertical-align'] = 'T';
+ if (isset($attr['LEVEL']) && $attr['LEVEL']) { $objattr['toclevel'] = $attr['LEVEL']; } else { $objattr['toclevel'] = 0; }
+ if (isset($attr['NAME']) && $attr['NAME']) { $objattr['toc_id'] = $attr['NAME']; } else { $objattr['toc_id'] = 0; }
+ $e = "\xbb\xa4\xactype=toc,objattr=".serialize($objattr)."\xbb\xa4\xac";
+ if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
+ else { // *TABLES*
+ $this->textbuffer[] = array($e);
+ } // *TABLES*
+ }
+ break;
+/*-- END TOC --*/
+
+/*-- INDEX --*/
+ case 'INDEXENTRY':
+ if (isset($attr['CONTENT']) && $attr['CONTENT']) {
+ if (isset($attr['XREF']) && $attr['XREF']) {
+ $this->IndexEntry(htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES),$attr['XREF']);
+ break;
+ }
+ $objattr = array();
+ $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
+ $objattr['type'] = 'indexentry';
+ $objattr['vertical-align'] = 'T';
+ $e = "\xbb\xa4\xactype=indexentry,objattr=".serialize($objattr)."\xbb\xa4\xac";
+ if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
+ else { // *TABLES*
+ $this->textbuffer[] = array($e);
+ } // *TABLES*
+ }
+ break;
+
+
+ case 'INDEXINSERT':
+ if (isset($attr['COLLATION'])) { $indexCollationLocale = $attr['COLLATION']; } else { $indexCollationLocale = ''; }
+ if (isset($attr['COLLATION-GROUP'])) { $indexCollationGroup = $attr['COLLATION-GROUP']; } else { $indexCollationGroup = ''; }
+ if (isset($attr['USEDIVLETTERS']) && (strtoupper($attr['USEDIVLETTERS'])=='OFF' || $attr['USEDIVLETTERS']==-1 || $attr['USEDIVLETTERS']==='0')) { $usedivletters = 0; }
+ else { $usedivletters = 1; }
+ if (isset($attr['LINKS']) && (strtoupper($attr['LINKS'])=='ON' || $attr['LINKS']==1)) { $links = true; }
+ else { $links = false; }
+ $this->InsertIndex($usedivletters, $links, $indexCollationLocale, $indexCollationGroup);
+
+ break;
+/*-- END INDEX --*/
+
+/*-- WATERMARK --*/
+
+ case 'WATERMARKTEXT':
+ if (isset($attr['CONTENT']) && $attr['CONTENT']) { $txt = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES); } else { $txt = ''; }
+ if (isset($attr['ALPHA']) && $attr['ALPHA']>0) { $alpha = $attr['ALPHA']; } else { $alpha = -1; }
+ $this->SetWatermarkText($txt, $alpha);
+ break;
+
+
+ case 'WATERMARKIMAGE':
+ if (isset($attr['SRC'])) { $src = $attr['SRC']; } else { $src = ''; }
+ if (isset($attr['ALPHA']) && $attr['ALPHA']>0) { $alpha = $attr['ALPHA']; } else { $alpha = -1; }
+ if (isset($attr['SIZE']) && $attr['SIZE']) {
+ $size = $attr['SIZE'];
+ if (strpos($size,',')) { $size = explode(',',$size); }
+ }
+ else { $size = 'D'; }
+ if (isset($attr['POSITION']) && $attr['POSITION']) { // mPDF 5.7.2
+ $pos = $attr['POSITION'];
+ if (strpos($pos,',')) { $pos = explode(',',$pos); }
+ }
+ else { $pos = 'P'; }
+ $this->SetWatermarkImage($src, $alpha, $size, $pos);
+ break;
+/*-- END WATERMARK --*/
+
+/*-- BOOKMARKS --*/
+ case 'BOOKMARK':
+ if (isset($attr['CONTENT'])) {
+ $objattr = array();
+ $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
+ $objattr['type'] = 'bookmark';
+ if (isset($attr['LEVEL']) && $attr['LEVEL']) { $objattr['bklevel'] = $attr['LEVEL']; } else { $objattr['bklevel'] = 0; }
+ $e = "\xbb\xa4\xactype=bookmark,objattr=".serialize($objattr)."\xbb\xa4\xac";
+ if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
+ else { // *TABLES*
+ $this->textbuffer[] = array($e);
+ } // *TABLES*
+ }
+ break;
+/*-- END BOOKMARKS --*/
+
+/*-- ANNOTATIONS --*/
+ case 'ANNOTATION':
+
+ //if (isset($attr['CONTENT']) && !$this->writingHTMLheader && !$this->writingHTMLfooter) { // Stops annotations in FixedPos
+ if (isset($attr['CONTENT'])) {
+ $objattr = array();
+ $objattr['margin_top'] = 0;
+ $objattr['margin_bottom'] = 0;
+ $objattr['margin_left'] = 0;
+ $objattr['margin_right'] = 0;
+ $objattr['width'] = 0;
+ $objattr['height'] = 0;
+ $objattr['border_top']['w'] = 0;
+ $objattr['border_bottom']['w'] = 0;
+ $objattr['border_left']['w'] = 0;
+ $objattr['border_right']['w'] = 0;
+ $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'],ENT_QUOTES);
+ $objattr['type'] = 'annot';
+ $objattr['POPUP'] = '';
+ }
+ else { break; }
+ if (isset($attr['POS-X'])) { $objattr['POS-X'] = $attr['POS-X']; } else { $objattr['POS-X'] = 0; }
+ if (isset($attr['POS-Y'])) { $objattr['POS-Y'] = $attr['POS-Y']; } else { $objattr['POS-Y'] = 0; }
+ if (isset($attr['ICON'])) { $objattr['ICON'] = $attr['ICON']; } else { $objattr['ICON'] = 'Note'; }
+ if (isset($attr['AUTHOR'])) { $objattr['AUTHOR'] = $attr['AUTHOR']; }
+ else if (isset($attr['TITLE'])) { $objattr['AUTHOR'] = $attr['TITLE']; } else { $objattr['AUTHOR'] = ''; }
+ if (isset($attr['FILE'])) { $objattr['FILE'] = $attr['FILE']; } else { $objattr['FILE'] = ''; }
+ if (isset($attr['SUBJECT'])) { $objattr['SUBJECT'] = $attr['SUBJECT']; } else { $objattr['SUBJECT'] = ''; }
+ if (isset($attr['OPACITY']) && $attr['OPACITY']>0 && $attr['OPACITY']<=1) { $objattr['OPACITY'] = $attr['OPACITY']; }
+ else if ($this->annotMargin) { $objattr['OPACITY'] = 1; }
+ else { $objattr['OPACITY'] = $this->annotOpacity; }
+ if (isset($attr['COLOR'])) {
+ $cor = $this->ConvertColor($attr['COLOR']);
+ if ($cor) { $objattr['COLOR'] = $cor; }
+ else { $objattr['COLOR'] = $this->ConvertColor('yellow'); }
+ }
+ else { $objattr['COLOR'] = $this->ConvertColor('yellow'); }
+
+ if (isset($attr['POPUP']) && !empty($attr['POPUP'])) {
+ $pop = preg_split('/\s+/',trim($attr['POPUP']));
+ if (count($pop)>1) { $objattr['POPUP'] = $pop; }
+ else { $objattr['POPUP'] = true; }
+ }
+ $e = "\xbb\xa4\xactype=annot,objattr=".serialize($objattr)."\xbb\xa4\xac";
+ if($this->tableLevel) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); } // *TABLES*
+ else { // *TABLES*
+ $this->textbuffer[] = array($e);
+ } // *TABLES*
+ break;
+/*-- END ANNOTATIONS --*/
+
+
+/*-- COLUMNS --*/
+ case 'COLUMNS': //added custom-tag
+ if (isset($attr['COLUMN-COUNT']) && ($attr['COLUMN-COUNT'] || $attr['COLUMN-COUNT']==='0')) {
+ // Close any open block tags
+ for ($b= $this->blklvl;$b>0;$b--) { $this->CloseTag($this->blk[$b]['tag'],$ahtml,$ihtml); }
+ if(!empty($this->textbuffer)) { //Output previously buffered content
+ $this->printbuffer($this->textbuffer);
+ $this->textbuffer=array();
+ }
+
+ if (isset($attr['VALIGN']) && $attr['VALIGN']) {
+ if ($attr['VALIGN'] == 'J') { $valign = 'J'; }
+ else { $valign = $align[$attr['VALIGN']]; }
+ }
+ else { $valign = ''; }
+ if (isset($attr['COLUMN-GAP']) && $attr['COLUMN-GAP']) { $this->SetColumns($attr['COLUMN-COUNT'],$valign,$attr['COLUMN-GAP']); }
+ else { $this->SetColumns($attr['COLUMN-COUNT'],$valign); }
+ }
+ $this->ignorefollowingspaces = true;
+ break;
+
+ case 'COLUMN_BREAK': //custom-tag
+ case 'COLUMNBREAK': //custom-tag
+ case 'NEWCOLUMN': //custom-tag
+ $this->ignorefollowingspaces = true;
+ $this->NewColumn();
+ $this->ColumnAdjust = false; // disables all column height adjustment for the page.
+ break;
+
+/*-- END COLUMNS --*/
+
+
+ case 'TTZ':
+ $this->ttz = true;
+ $this->InlineProperties[$tag] = $this->saveInlineProperties();
+ $this->setCSS(array('FONT-FAMILY'=>'czapfdingbats','FONT-WEIGHT'=>'normal','FONT-STYLE'=>'normal'),'INLINE');
+ break;
+
+ case 'TTS':
+ $this->tts = true;
+ $this->InlineProperties[$tag] = $this->saveInlineProperties();
+ $this->setCSS(array('FONT-FAMILY'=>'csymbol','FONT-WEIGHT'=>'normal','FONT-STYLE'=>'normal'),'INLINE');
+ break;
+
+ case 'TTA':
+ $this->tta = true;
+ $this->InlineProperties[$tag] = $this->saveInlineProperties();
+
+ if (in_array($this->FontFamily,$this->mono_fonts)) {
+ $this->setCSS(array('FONT-FAMILY'=>'ccourier'),'INLINE');
+ }
+ else if (in_array($this->FontFamily,$this->serif_fonts)) {
+ $this->setCSS(array('FONT-FAMILY'=>'ctimes'),'INLINE');
+ }
+ else {
+ $this->setCSS(array('FONT-FAMILY'=>'chelvetica'),'INLINE');
+ }
+ break;
+
+
+
+ // INLINE PHRASES OR STYLES
+ case 'SUB':
+ case 'SUP':
+ case 'ACRONYM':
+ case 'BIG':
+ case 'SMALL':
+ case 'INS':
+ case 'S':
+ case 'STRIKE':
+ case 'DEL':
+ case 'STRONG':
+ case 'CITE':
+ case 'Q':
+ case 'EM':
+ case 'B':
+ case 'I':
+ case 'U':
+ case 'SAMP':
+ case 'CODE':
+ case 'KBD':
+ case 'TT':
+ case 'VAR':
+ case 'FONT':
+ case 'MARK':
+ case 'TIME':
+ case 'BDO': // mPDF 6
+ case 'BDI': // mPDF 6
+
+ case 'SPAN':
+/*-- ANNOTATIONS --*/
+ if ($this->title2annots && isset($attr['TITLE'])) {
+ $objattr = array();
+ $objattr['margin_top'] = 0;
+ $objattr['margin_bottom'] = 0;
+ $objattr['margin_left'] = 0;
+ $objattr['margin_right'] = 0;
+ $objattr['width'] = 0;
+ $objattr['height'] = 0;
+ $objattr['border_top']['w'] = 0;
+ $objattr['border_bottom']['w'] = 0;
+ $objattr['border_left']['w'] = 0;
+ $objattr['border_right']['w'] = 0;
+
+ $objattr['CONTENT'] = $attr['TITLE'];
+ $objattr['type'] = 'annot';
+ $objattr['POS-X'] = 0;
+ $objattr['POS-Y'] = 0;
+ $objattr['ICON'] = 'Comment';
+ $objattr['AUTHOR'] = '';
+ $objattr['SUBJECT'] = '';
+ $objattr['OPACITY'] = $this->annotOpacity;
+ $objattr['COLOR'] = $this->ConvertColor('yellow');
+ $annot = "\xbb\xa4\xactype=annot,objattr=".serialize($objattr)."\xbb\xa4\xac";
+ }
+/*-- END ANNOTATIONS --*/
+
+ // mPDF 5.7.3 Inline tags
+ if (!isset($this->InlineProperties[$tag])) { $this->InlineProperties[$tag] = array($this->saveInlineProperties()); }
+ else { $this->InlineProperties[$tag][] = $this->saveInlineProperties(); }
+ if (isset($annot)) { // *ANNOTATIONS*
+ if (!isset($this->InlineAnnots[$tag])) { $this->InlineAnnots[$tag] = array($annot); } // *ANNOTATIONS*
+ else { $this->InlineAnnots[$tag][] = $annot; } // *ANNOTATIONS*
+ } // *ANNOTATIONS*
+
+ $properties = $this->cssmgr->MergeCSS('INLINE',$tag,$attr);
+ if (!empty($properties)) $this->setCSS($properties,'INLINE');
+
+ // mPDF 6 Bidirectional formatting for inline elements
+ $bdf = false;
+ $bdf2 = '';
+ $popd = '';
+
+ // Get current direction
+ if (isset($this->blk[$this->blklvl]['direction'])) { $currdir = $this->blk[$this->blklvl]['direction']; }
+ else { $currdir = 'ltr'; }
+ if($this->tableLevel && isset($this->cell[$this->row][$this->col]['direction']) && $this->cell[$this->row][$this->col]['direction'] == 'rtl') {
+ $currdir = 'rtl';
+ }
+ if (isset($attr['DIR']) and $attr['DIR'] != '') { $currdir = strtolower($attr['DIR']); }
+ if(isset($properties['DIRECTION'])) { $currdir = strtolower($properties['DIRECTION']); }
+
+ // mPDF 6 bidi
+ // cf. http://www.w3.org/TR/css3-writing-modes/#unicode-bidi
+ if ($tag == 'BDO') {
+ if (isset($attr['DIR']) and strtolower($attr['DIR']) == 'rtl') { $bdf = 0x202E; $popd = 'RLOPDF'; } // U+202E RLO
+ else if (isset($attr['DIR']) and strtolower($attr['DIR']) == 'ltr') { $bdf = 0x202D; $popd = 'LROPDF'; } // U+202D LRO
+ }
+ else if ($tag == 'BDI') {
+ if (isset($attr['DIR']) and strtolower($attr['DIR']) == 'rtl') { $bdf = 0x2067; $popd = 'RLIPDI'; } // U+2067 RLI
+ else if (isset($attr['DIR']) and strtolower($attr['DIR']) == 'ltr') { $bdf = 0x2066; $popd = 'LRIPDI'; } // U+2066 LRI
+ else { $bdf = 0x2068; $popd = 'FSIPDI'; } // U+2068 FSI
+ }
+ else if(isset($properties ['UNICODE-BIDI']) && strtolower($properties ['UNICODE-BIDI'])=='bidi-override') {
+ if ($currdir == 'rtl') { $bdf = 0x202E; $popd = 'RLOPDF';} // U+202E RLO
+ else { $bdf = 0x202D; $popd = 'LROPDF'; } // U+202D LRO
+ }
+ else if(isset($properties ['UNICODE-BIDI']) && strtolower($properties ['UNICODE-BIDI'])=='embed') {
+ if ($currdir == 'rtl') { $bdf = 0x202B; $popd = 'RLEPDF';} // U+202B RLE
+ else { $bdf = 0x202A; $popd = 'LREPDF'; } // U+202A LRE
+ }
+ else if(isset($properties ['UNICODE-BIDI']) && strtolower($properties ['UNICODE-BIDI'])=='isolate') {
+ if ($currdir == 'rtl') { $bdf = 0x2067; $popd = 'RLIPDI'; } // U+2067 RLI
+ else { $bdf = 0x2066; $popd = 'LRIPDI'; } // U+2066 LRI
+ }
+ else if(isset($properties ['UNICODE-BIDI']) && strtolower($properties ['UNICODE-BIDI'])=='isolate-override') {
+ if ($currdir == 'rtl') { $bdf = 0x2067; $bdf2 = 0x202E; $popd = 'RLIRLOPDFPDI'; } // U+2067 RLI // U+202E RLO
+ else { $bdf = 0x2066; $bdf2 = 0x202D; $popd = 'LRILROPDFPDI'; } // U+2066 LRI // U+202D LRO
+ }
+ else if(isset($properties ['UNICODE-BIDI']) && strtolower($properties ['UNICODE-BIDI'])=='plaintext') {
+ $bdf = 0x2068; $popd = 'FSIPDI'; // U+2068 FSI
+ }
+ else {
+ if (isset($attr['DIR']) and strtolower($attr['DIR']) == 'rtl') { $bdf = 0x202B; $popd = 'RLEPDF'; } // U+202B RLE
+ else if (isset($attr['DIR']) and strtolower($attr['DIR']) == 'ltr') { $bdf = 0x202A; $popd = 'LREPDF'; } // U+202A LRE
+ }
+
+ if ($bdf) {
+ // mPDF 5.7.3 Inline tags
+ if (!isset($this->InlineBDF[$tag])) { $this->InlineBDF[$tag] = array(array($popd, $this->InlineBDFctr)); }
+ else { $this->InlineBDF[$tag][] = array($popd, $this->InlineBDFctr); }
+ $this->InlineBDFctr++;
+ if ($bdf2) { $bdf2 = code2utf($bdf); }
+ $this->OTLdata = array();
+ if($this->tableLevel) { $this->_saveCellTextBuffer(code2utf($bdf).$bdf2); }
+ else { $this->_saveTextBuffer(code2utf($bdf).$bdf2); }
+ $this->biDirectional = true;
+ }
+
+ break;
+
+
+ case 'A':
+ if (isset($attr['NAME']) and $attr['NAME'] != '') {
+ $e = '';
+/*-- BOOKMARKS --*/
+ if ($this->anchor2Bookmark) {
+ $objattr = array();
+ $objattr['CONTENT'] = htmlspecialchars_decode($attr['NAME'],ENT_QUOTES);
+ $objattr['type'] = 'bookmark';
+ if (isset($attr['LEVEL']) && $attr['LEVEL']) { $objattr['bklevel'] = $attr['LEVEL']; } else { $objattr['bklevel'] = 0; }
+ $e = "\xbb\xa4\xactype=bookmark,objattr=".serialize($objattr)."\xbb\xa4\xac";
+ }
+/*-- END BOOKMARKS --*/
+ if($this->tableLevel) { // *TABLES*
+ $this->_saveCellTextBuffer($e, '', $attr['NAME']); // *TABLES*
+ } // *TABLES*
+ else { // *TABLES*
+ $this->_saveTextBuffer($e, '', $attr['NAME']); //an internal link (adds a space for recognition)
+ } // *TABLES*
+ }
+ if (isset($attr['HREF'])) {
+ $this->InlineProperties['A'] = $this->saveInlineProperties();
+ $properties = $this->cssmgr->MergeCSS('INLINE',$tag,$attr);
+ if (!empty($properties)) $this->setCSS($properties,'INLINE');
+ $this->HREF=$attr['HREF']; // mPDF 5.7.4 URLs
+ }
+ break;
+
+ case 'LEGEND':
+ $this->InlineProperties['LEGEND'] = $this->saveInlineProperties();
+ $properties = $this->cssmgr->MergeCSS('INLINE',$tag,$attr);
+ if (!empty($properties)) $this->setCSS($properties,'INLINE');
+ break;
+
+
+
+ case 'PROGRESS':
+ case 'METER':
+ $this->inMeter = true;
+
+ if (isset($attr['MAX']) && $attr['MAX']) { $max = $attr['MAX']; }
+ else { $max = 1; }
+ if (isset($attr['MIN']) && $attr['MIN'] && $tag=='METER') { $min = $attr['MIN']; }
+ else { $min = 0; }
+ if ($max < $min) { $max = $min; }
+
+ if (isset($attr['VALUE']) && ($attr['VALUE'] || $attr['VALUE']==='0')) {
+ $value = $attr['VALUE'];
+ if ($value < $min) { $value = $min; }
+ else if ($value > $max) { $value = $max; }
+ }
+ else { $value = ''; }
+
+ if (isset($attr['LOW']) && $attr['LOW']) { $low = $attr['LOW']; }
+ else { $low = $min; }
+ if ($low < $min) { $low = $min; }
+ else if ($low > $max) { $low = $max; }
+ if (isset($attr['HIGH']) && $attr['HIGH']) { $high = $attr['HIGH']; }
+ else { $high = $max; }
+ if ($high < $low) { $high = $low; }
+ else if ($high > $max) { $high = $max; }
+ if (isset($attr['OPTIMUM']) && $attr['OPTIMUM']) { $optimum = $attr['OPTIMUM']; }
+ else { $optimum = $min + (($max-$min)/2); }
+ if ($optimum < $min) { $optimum = $min; }
+ else if ($optimum > $max) { $optimum = $max; }
+ if (isset($attr['TYPE']) && $attr['TYPE']) { $type = $attr['TYPE']; }
+ else { $type = ''; }
+ $objattr = array();
+ $objattr['margin_top'] = 0;
+ $objattr['margin_bottom'] = 0;
+ $objattr['margin_left'] = 0;
+ $objattr['margin_right'] = 0;
+ $objattr['padding_top'] = 0;
+ $objattr['padding_bottom'] = 0;
+ $objattr['padding_left'] = 0;
+ $objattr['padding_right'] = 0;
+ $objattr['width'] = 0;
+ $objattr['height'] = 0;
+ $objattr['border_top']['w'] = 0;
+ $objattr['border_bottom']['w'] = 0;
+ $objattr['border_left']['w'] = 0;
+ $objattr['border_right']['w'] = 0;
+
+ $properties = $this->cssmgr->MergeCSS('INLINE',$tag,$attr);
+ if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
+ return;
+ }
+ $objattr['visibility'] = 'visible';
+ if (isset($properties['VISIBILITY'])) {
+ $v = strtolower($properties['VISIBILITY']);
+ if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility=='visible') {
+ $objattr['visibility'] = $v;
+ }
+ }
+
+ if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+
+ if (isset($properties['PADDING-TOP'])) { $objattr['padding_top']=$this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['PADDING-BOTTOM'])) { $objattr['padding_bottom'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['PADDING-LEFT'])) { $objattr['padding_left'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['PADDING-RIGHT'])) { $objattr['padding_right'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+
+ if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
+ if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
+ if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
+ if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
+
+ if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
+ $w = 0;
+ $h = 0;
+ if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ else if(isset($attr['WIDTH'])) $w = $this->ConvertSize($attr['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+
+ if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ else if(isset($attr['HEIGHT'])) $h = $this->ConvertSize($attr['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+
+ if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { $objattr['opacity'] = $properties['OPACITY']; }
+ if ($this->HREF) {
+ if (strpos($this->HREF,".") === false && strpos($this->HREF,"@") !== 0) {
+ $href = $this->HREF;
+ while(array_key_exists($href,$this->internallink)) $href="#".$href;
+ $this->internallink[$href] = $this->AddLink();
+ $objattr['link'] = $this->internallink[$href];
+ }
+ else { $objattr['link'] = $this->HREF; }
+ }
+ $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
+ $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
+
+ // Image file
+ if (!class_exists('meter', false)) {
+ include(_MPDF_PATH.'classes/meter.php');
+ }
+ $this->meter = new meter();
+ $svg = $this->meter->makeSVG(strtolower($tag), $type, $value, $max, $min, $optimum, $low, $high);
+ //Save to local file
+ $srcpath= _MPDF_TEMP_PATH.'_tempSVG'.uniqid(rand(1,100000),true).'_'.strtolower($tag).'.svg';
+ file_put_contents($srcpath, $svg);
+ $orig_srcpath = $srcpath;
+ $this->GetFullPath($srcpath);
+
+ $info=$this->_getImage($srcpath, true, true, $orig_srcpath);
+ if(!$info) {
+ $info = $this->_getImage($this->noImageFile);
+ if ($info) {
+ $srcpath = $this->noImageFile;
+ $w = ($info['w'] * (25.4/$this->dpi));
+ $h = ($info['h'] * (25.4/$this->dpi));
+ }
+ }
+ if(!$info) break;
+
+ $objattr['file'] = $srcpath;
+ //Default width and height calculation if needed
+ if($w==0 and $h==0) {
+ // SVG units are pixels
+ $w = $this->FontSize/(10/_MPDFK) * abs($info['w'])/_MPDFK;
+ $h = $this->FontSize/(10/_MPDFK) * abs($info['h'])/_MPDFK;
+ }
+ // IF WIDTH OR HEIGHT SPECIFIED
+ if($w==0) $w=abs($h*$info['w']/$info['h']);
+ if($h==0) $h=abs($w*$info['h']/$info['w']);
+
+ // Resize to maximum dimensions of page
+ $maxWidth = $this->blk[$this->blklvl]['inner_width'];
+ $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 1) ;
+ if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
+ if (($w + $extrawidth) > ($maxWidth + 0.0001) ) { // mPDF 5.7.4 0.0001 to allow for rounding errors when w==maxWidth
+ $w = $maxWidth - $extrawidth;
+ $h=abs($w*$info['h']/$info['w']);
+ }
+
+ if ($h + $extraheight > $maxHeight ) {
+ $h = $maxHeight - $extraheight;
+ $w=abs($h*$info['w']/$info['h']);
+ }
+ $objattr['type'] = 'image';
+ $objattr['itype'] = $info['type'];
+
+ $objattr['orig_h'] = $info['h'];
+ $objattr['orig_w'] = $info['w'];
+ $objattr['wmf_x'] = $info['x'];
+ $objattr['wmf_y'] = $info['y'];
+ $objattr['height'] = $h + $extraheight;
+ $objattr['width'] = $w + $extrawidth;
+ $objattr['image_height'] = $h;
+ $objattr['image_width'] = $w;
+ $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
+ $properties = array();
+ if ($this->tableLevel) {
+ $this->_saveCellTextBuffer($e, $this->HREF);
+ $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
+ }
+ else {
+ $this->_saveTextBuffer($e, $this->HREF);
+ }
+
+ break;
+
+
+ case 'BR':
+ // Added mPDF 3.0 Float DIV - CLEAR
+ if (isset($attr['STYLE'])) {
+ $properties = $this->cssmgr->readInlineCSS($attr['STYLE']);
+ if (isset($properties['CLEAR'])) { $this->ClearFloats(strtoupper($properties['CLEAR']),$this->blklvl); } // *CSS-FLOAT*
+ }
+
+ // mPDF 6 bidi
+ // Inline
+ // If unicode-bidi set, any embedding levels, isolates, or overrides started by the inline box are closed at the br and reopened on the other side
+ $blockpre = '';
+ $blockpost = '';
+ if (isset($this->blk[$this->blklvl]['bidicode'])) {
+ $blockpre = $this->_setBidiCodes('end', $this->blk[$this->blklvl]['bidicode']);
+ $blockpost = $this->_setBidiCodes('start', $this->blk[$this->blklvl]['bidicode']);
+ }
+
+ // Inline
+ // If unicode-bidi set, any embedding levels, isolates, or overrides started by the inline box are closed at the br and reopened on the other side
+ $inlinepre = '';
+ $inlinepost = '';
+ $iBDF = array();
+ if (count($this->InlineBDF)) {
+ foreach($this->InlineBDF AS $k => $ib) {
+ foreach($ib AS $ib2) { $iBDF[$ib2[1]] = $ib2[0]; }
+ }
+ if (count($iBDF)) {
+ ksort($iBDF);
+ for($i=count($iBDF)-1;$i>=0;$i--) {
+ $inlinepre .= $this->_setBidiCodes('end', $iBDF[$i]);
+ }
+ for($i=0;$i _setBidiCodes('start', $iBDF[$i]);
+ }
+ }
+ }
+
+/*-- TABLES --*/
+ if($this->tableLevel) {
+
+ if ($this->blockjustfinished) {
+ $this->_saveCellTextBuffer($blockpre.$inlinepre."\n".$inlinepost.$blockpost);
+ }
+
+ $this->_saveCellTextBuffer($blockpre.$inlinepre."\n".$inlinepost.$blockpost);
+ if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
+ $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
+ }
+ elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
+ $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
+ }
+ $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
+ }
+ else {
+/*-- END TABLES --*/
+ if (count($this->textbuffer)) {
+ $this->textbuffer[count($this->textbuffer)-1][0] = preg_replace('/ $/','',$this->textbuffer[count($this->textbuffer)-1][0]);
+ if (!empty($this->textbuffer[count($this->textbuffer)-1][18])) { $this->otl->trimOTLdata($this->textbuffer[count($this->textbuffer)-1][18], false, true); } // *OTL*
+ }
+ $this->_saveTextBuffer($blockpre.$inlinepre."\n".$inlinepost.$blockpost);
+ } // *TABLES*
+ $this->ignorefollowingspaces = true;
+ $this->blockjustfinished=false;
+
+ $this->linebreakjustfinished=true;
+ break;
+
+
+ // *********** BLOCKS ********************
+
+
+ case 'PRE':
+ $this->ispre=true; // ADDED - Prevents left trim of textbuffer in printbuffer()
+
+ case 'DIV':
+ case 'FORM':
+ case 'CENTER':
+
+ case 'BLOCKQUOTE':
+ case 'ADDRESS':
+
+ case 'CAPTION':
+ case 'P':
+ case 'H1':
+ case 'H2':
+ case 'H3':
+ case 'H4':
+ case 'H5':
+ case 'H6':
+ case 'DL':
+ case 'DT':
+ case 'DD':
+ case 'UL': // mPDF 6 Lists
+ case 'OL': // mPDF 6
+ case 'LI': // mPDF 6
+ case 'FIELDSET':
+ case 'DETAILS':
+ case 'SUMMARY':
+ case 'ARTICLE':
+ case 'ASIDE':
+ case 'FIGURE':
+ case 'FIGCAPTION':
+ case 'FOOTER':
+ case 'HEADER':
+ case 'HGROUP':
+ case 'NAV':
+ case 'SECTION':
+ case 'MAIN':
+ // mPDF 6 Lists
+ $this->lastoptionaltag = '';
+
+ // mPDF 6 bidi
+ // Block
+ // If unicode-bidi set on current clock, any embedding levels, isolates, or overrides are closed (not inherited)
+ if (isset($this->blk[$this->blklvl]['bidicode'])) {
+ $blockpost = $this->_setBidiCodes('end', $this->blk[$this->blklvl]['bidicode']);
+ if ($blockpost) {
+ $this->OTLdata = array();
+ if($this->tableLevel) { $this->_saveCellTextBuffer($blockpost); }
+ else { $this->_saveTextBuffer($blockpost); }
+ }
+ }
+
+
+ $p = $this->cssmgr->PreviewBlockCSS($tag,$attr);
+ if(isset($p['DISPLAY']) && strtolower($p['DISPLAY'])=='none') {
+ $this->blklvl++;
+ $this->blk[$this->blklvl]['hide'] = true;
+ $this->blk[$this->blklvl]['tag'] = $tag; // mPDF 6
+ return;
+ }
+ if($tag == 'CAPTION') {
+ // position is written in AdjstHTML
+ if (isset($attr['POSITION']) && strtolower($attr['POSITION'])=='bottom') { $divpos = 'B'; }
+ else { $divpos = 'T'; }
+ if (isset($attr['ALIGN']) && strtolower($attr['ALIGN'])=='bottom') { $cappos = 'B'; }
+ else if (isset($p['CAPTION-SIDE']) && strtolower($p['CAPTION-SIDE'])=='bottom') { $cappos = 'B'; }
+ else { $cappos = 'T'; }
+ if (isset($attr['ALIGN'])) { unset($attr['ALIGN']); }
+ if ($cappos != $divpos) {
+ $this->blklvl++;
+ $this->blk[$this->blklvl]['hide'] = true;
+ $this->blk[$this->blklvl]['tag'] = $tag; // mPDF 6
+ return;
+ }
+ }
+
+/*-- FORMS --*/
+ if($tag == 'FORM') {
+ if (isset($attr['METHOD']) && strtolower($attr['METHOD'])=='get') { $this->mpdfform->formMethod = 'GET'; }
+ else { $this->mpdfform->formMethod = 'POST'; }
+ if (isset($attr['ACTION'])) { $this->mpdfform->formAction = $attr['ACTION']; }
+ else { $this->mpdfform->formAction = ''; }
+ }
+/*-- END FORMS --*/
+
+
+/*-- CSS-POSITION --*/
+ if ((isset($p['POSITION']) && (strtolower($p['POSITION'])=='fixed' || strtolower($p['POSITION'])=='absolute')) && $this->blklvl==0) {
+ if ($this->inFixedPosBlock) {
+ $this->Error("Cannot nest block with position:fixed or position:absolute");
+ }
+ $this->inFixedPosBlock = true;
+ return;
+ }
+/*-- END CSS-POSITION --*/
+ // Start Block
+ $this->ignorefollowingspaces = true;
+
+ if ($this->blockjustfinished && !count($this->textbuffer) && $this->y != $this->tMargin && $this->collapseBlockMargins) { $lastbottommargin = $this->lastblockbottommargin; }
+ else { $lastbottommargin = 0; }
+ $this->lastblockbottommargin = 0;
+ $this->blockjustfinished=false;
+
+
+ $this->InlineBDF=array(); // mPDF 6
+ $this->InlineBDFctr= 0; // mPDF 6
+ $this->InlineProperties = array();
+ $this->divbegin=true;
+
+ $this->linebreakjustfinished=false;
+
+/*-- TABLES --*/
+ if ($this->tableLevel) {
+ // If already something on the line
+ if ($this->cell[$this->row][$this->col]['s'] > 0 && !$this->nestedtablejustfinished ) {
+ $this->_saveCellTextBuffer("\n");
+ if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
+ $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
+ }
+ elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
+ $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
+ }
+ $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
+ }
+ // Cannot set block properties inside table - use Bold to indicate h1-h6
+ if ($tag == 'CENTER' && $this->tdbegin) { $this->cell[$this->row][$this->col]['a'] = $align['center']; }
+
+ $this->InlineProperties['BLOCKINTABLE'] = $this->saveInlineProperties();
+ $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
+ if (!empty($properties)) $this->setCSS($properties,'INLINE');
+
+ // mPDF 6 Lists
+ if ($tag == 'UL' || $tag == 'OL') {
+ $this->listlvl++;
+ if (isset($attr['START'])) { $this->listcounter[$this->listlvl] = intval($attr['START'])-1; }
+ else { $this->listcounter[$this->listlvl] = 0; }
+ $this->listitem = array();
+ if ($tag == 'OL') $this->listtype[$this->listlvl] = 'decimal';
+ else if ($tag == 'UL') {
+ if ($this->listlvl % 3 == 1) $this->listtype[$this->listlvl] = 'disc';
+ elseif ($this->listlvl % 3 == 2) $this->listtype[$this->listlvl] = 'circle';
+ else $this->listtype[$this->listlvl] = 'square';
+ }
+ }
+
+ // mPDF 6 Lists - in Tables
+ if ($tag == 'LI') {
+ if ($this->listlvl == 0) { //in case of malformed HTML code. Example:(...)ContentParagraph1 (...)
+ $this->listlvl++; // first depth level
+ $this->listcounter[$this->listlvl] = 0;
+ }
+ $this->listcounter[$this->listlvl]++;
+ $this->listitem = array();
+ //if in table - output here as a tabletextbuffer
+ //position:inside OR position:outside (always output in table as position:inside)
+ switch($this->listtype[$this->listlvl]) {
+ case 'upper-alpha':
+ case 'upper-latin':
+ case 'A':
+ $blt = $this->dec2alpha($this->listcounter[$this->listlvl],true).$this->list_number_suffix;
+ break;
+ case 'lower-alpha':
+ case 'lower-latin':
+ case 'a':
+ $blt = $this->dec2alpha($this->listcounter[$this->listlvl],false).$this->list_number_suffix;
+ break;
+ case 'upper-roman':
+ case 'I':
+ $blt = $this->dec2roman($this->listcounter[$this->listlvl],true).$this->list_number_suffix;
+ break;
+ case 'lower-roman':
+ case 'i':
+ $blt = $this->dec2roman($this->listcounter[$this->listlvl],false).$this->list_number_suffix;
+ break;
+ case 'decimal':
+ case '1':
+ $blt = $this->listcounter[$this->listlvl].$this->list_number_suffix;
+ break;
+ default:
+ if ($this->listlvl % 3 == 1 && $this->_charDefined($this->CurrentFont['cw'],8226)) { $blt = "\xe2\x80\xa2"; } // •
+ else if ($this->listlvl % 3 == 2 && $this->_charDefined($this->CurrentFont['cw'],9900)) { $blt = "\xe2\x9a\xac"; } // ⚬
+ else if ($this->listlvl % 3 == 0 && $this->_charDefined($this->CurrentFont['cw'],9642)) { $blt = "\xe2\x96\xaa"; } // ▪
+ else { $blt = '-'; }
+ break;
+ }
+
+ // change to spaces
+ if ($this->usingCoreFont) {
+ $ls = str_repeat(chr(160).chr(160),($this->listlvl-1)*2) . $blt . ' ';
+ }
+ else {
+ $ls = str_repeat("\xc2\xa0\xc2\xa0",($this->listlvl-1)*2) . $blt . ' ';
+ }
+ $this->_saveCellTextBuffer($ls);
+ $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth($ls);
+ }
+
+ break;
+ }
+/*-- END TABLES --*/
+
+ if ($this->lastblocklevelchange == 1) { $blockstate = 1; } // Top margins/padding only
+ else if ($this->lastblocklevelchange < 1) { $blockstate = 0; } // NO margins/padding
+ $this->printbuffer($this->textbuffer,$blockstate);
+ $this->textbuffer=array();
+
+ $save_blklvl = $this->blklvl;
+ $save_blk = $this->blk;
+
+ $this->Reset();
+
+ $pagesel = '';
+/*-- CSS-PAGE --*/
+ if (isset($p['PAGE'])) { $pagesel = $p['PAGE']; } // mPDF 6 (uses $p - preview of properties so blklvl can be incremented after page-break)
+/*-- END CSS-PAGE --*/
+
+ // If page-box has changed AND/OR PAGE-BREAK-BEFORE
+ // mPDF 6 (uses $p - preview of properties so blklvl can be imcremented after page-break)
+ if (!$this->tableLevel && (($pagesel && (!isset($this->page_box['current']) || $pagesel != $this->page_box['current'])) || (isset($p['PAGE-BREAK-BEFORE']) && $p['PAGE-BREAK-BEFORE']))) {
+ // mPDF 6 pagebreaktype
+ $startpage = $this->page;
+ $pagebreaktype = $this->defaultPagebreakType;
+ $this->lastblocklevelchange=-1;
+ if ($this->ColActive) { $pagebreaktype = 'cloneall'; }
+ if ($pagesel && (!isset($this->page_box['current']) || $pagesel != $this->page_box['current'])) { $pagebreaktype = 'cloneall'; }
+ $this->_preForcedPagebreak($pagebreaktype);
+
+ if (isset($p['PAGE-BREAK-BEFORE'])) {
+ if (strtoupper($p['PAGE-BREAK-BEFORE']) == 'RIGHT') { $this->AddPage($this->CurOrientation,'NEXT-ODD','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
+ else if (strtoupper($p['PAGE-BREAK-BEFORE']) == 'LEFT') { $this->AddPage($this->CurOrientation,'NEXT-EVEN','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
+ else if (strtoupper($p['PAGE-BREAK-BEFORE']) == 'ALWAYS') { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); }
+ else if ($this->page_box['current'] != $pagesel) { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel); } // *CSS-PAGE*
+ }
+/*-- CSS-PAGE --*/
+ // Must Add new page if changed page properties
+ else if (!isset($this->page_box['current']) || $pagesel != $this->page_box['current']) {
+ $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0,$pagesel);
+ }
+/*-- END CSS-PAGE --*/
+
+ // mPDF 6 pagebreaktype
+ $this->_postForcedPagebreak($pagebreaktype, $startpage, $save_blk, $save_blklvl);
+
+ }
+
+ // mPDF 6 pagebreaktype - moved after pagebreak
+ $this->blklvl++;
+ $currblk =& $this->blk[$this->blklvl];
+ $this->initialiseBlock($currblk);
+ $prevblk =& $this->blk[$this->blklvl-1];
+ $currblk['tag'] = $tag;
+ $currblk['attr'] = $attr;
+
+ $properties = $this->cssmgr->MergeCSS('BLOCK',$tag,$attr); // mPDF 6 - moved to after page-break-before
+
+ // mPDF 6 page-break-inside:avoid
+ if (isset($properties['PAGE-BREAK-INSIDE']) && strtoupper($properties['PAGE-BREAK-INSIDE']) == 'AVOID' && !$this->ColActive && !$this->keep_block_together && !isset($attr['PAGEBREAKAVOIDCHECKED'])) { // avoid re-iterating using PAGEBREAKAVOIDCHECKED; set in CloseTag
+ $currblk['keep_block_together'] = 1;
+ $currblk['array_i'] = $ihtml; // mPDF 6
+ $this->kt_y00 = $this->y;
+ $this->kt_p00 = $this->page;
+ $this->keep_block_together = 1;
+ }
+ if ($lastbottommargin && isset($properties['MARGIN-TOP']) && $properties['MARGIN-TOP'] && empty($properties['FLOAT'])) { $currblk['lastbottommargin'] = $lastbottommargin; }
+
+ if (isset($properties['Z-INDEX']) && $this->current_layer==0) {
+ $v = intval($properties['Z-INDEX']);
+ if ($v > 0) {
+ $currblk['z-index'] = $v;
+ $this->BeginLayer($v);
+ }
+ }
+
+
+ // mPDF 6 Lists
+ // List-type set by attribute
+ if ($tag == 'OL' || $tag == 'UL' || $tag == 'LI') {
+ if (isset($attr['TYPE']) && $attr['TYPE']) {
+ $listtype = $attr['TYPE'];
+ switch($listtype) {
+ case 'A':
+ $listtype = 'upper-latin';
+ break;
+ case 'a':
+ $listtype = 'lower-latin';
+ break;
+ case 'I':
+ $listtype = 'upper-roman';
+ break;
+ case 'i':
+ $listtype = 'lower-roman';
+ break;
+ case '1':
+ $listtype = 'decimal';
+ break;
+ }
+ $currblk['list_style_type'] = $listtype;
+ }
+ }
+
+ $this->setCSS($properties,'BLOCK',$tag); //name(id/class/style) found in the CSS array!
+ $currblk['InlineProperties'] = $this->saveInlineProperties();
+
+ if (isset($properties['VISIBILITY'])) {
+ $v = strtolower($properties['VISIBILITY']);
+ if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility=='visible' && !$this->tableLevel) {
+ $currblk['visibility'] = $v;
+ $this->SetVisibility($v);
+ }
+ }
+
+ // mPDF 6
+ if(isset($attr['ALIGN']) && $attr['ALIGN']) { $currblk['block-align'] = $align[strtolower($attr['ALIGN'])]; }
+
+
+ if (isset($properties['HEIGHT'])) {
+ $currblk['css_set_height'] = $this->ConvertSize($properties['HEIGHT'],($this->h - $this->tMargin - $this->bMargin),$this->FontSize,false);
+ if (($currblk['css_set_height'] + $this->y) > $this->PageBreakTrigger && $this->y > $this->tMargin+5 && $currblk['css_set_height'] < ($this->h - ($this->tMargin + $this->bMargin))) { $this->AddPage($this->CurOrientation); }
+ }
+ else { $currblk['css_set_height'] = false; }
+
+
+ // Added mPDF 3.0 Float DIV
+ if (isset($prevblk['blockContext'])) { $currblk['blockContext'] = $prevblk['blockContext'] ; } // *CSS-FLOAT*
+
+ if (isset($properties['CLEAR'])) { $this->ClearFloats(strtoupper($properties['CLEAR']), $this->blklvl-1); } // *CSS-FLOAT*
+
+ $container_w = $prevblk['inner_width'];
+ $bdr = $currblk['border_right']['w'];
+ $bdl = $currblk['border_left']['w'];
+ $pdr = $currblk['padding_right'];
+ $pdl = $currblk['padding_left'];
+
+ if (isset($currblk['css_set_width'])) { $setwidth = $currblk['css_set_width']; }
+ else { $setwidth = 0; }
+
+/*-- CSS-FLOAT --*/
+ if (isset($properties['FLOAT']) && strtoupper($properties['FLOAT']) == 'RIGHT' && !$this->ColActive) {
+ // Cancel Keep-Block-together
+ $currblk['keep_block_together'] = false;
+ $this->kt_y00 = '';
+ $this->keep_block_together = 0;
+
+ $this->blockContext++;
+ $currblk['blockContext'] = $this->blockContext;
+
+ list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
+
+ // DIV is too narrow for text to fit!
+ $maxw = $container_w - $l_width - $r_width;
+ if (($setwidth + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) > $maxw || ($maxw - ($currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr)) < (2*$this->GetCharWidth('W',false))) {
+ // Too narrow to fit - try to move down past L or R float
+ if ($l_max < $r_max && ($setwidth + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) <= ($container_w - $r_width) && (($container_w - $r_width) - ($currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr)) > (2*$this->GetCharWidth('W',false))) {
+ $this->ClearFloats('LEFT', $this->blklvl-1);
+ }
+ else if ($r_max < $l_max && ($setwidth + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) <= ($container_w - $l_width) && (($container_w - $l_width) - ($currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr)) > (2*$this->GetCharWidth('W',false))) {
+ $this->ClearFloats('RIGHT', $this->blklvl-1);
+ }
+ else { $this->ClearFloats('BOTH', $this->blklvl-1); }
+ list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
+ }
+
+ if ($r_exists) { $currblk['margin_right'] += $r_width; }
+
+ $currblk['float'] = 'R';
+ $currblk['float_start_y'] = $this->y;
+ if ($currblk['css_set_width']) {
+ $currblk['margin_left'] = $container_w - ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_right']);
+ $currblk['float_width'] = ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_right']);
+ }
+ else {
+ // *** If no width set - would need to buffer and keep track of max width, then Right-align if not full width
+ // and do borders and backgrounds - For now - just set to maximum width left
+
+ if ($l_exists) { $currblk['margin_left'] += $l_width; }
+ $currblk['css_set_width'] = $container_w - ($currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr);
+
+ $currblk['float_width'] = ($currblk['css_set_width'] + $bdl + $pdl + $bdr + $pdr + $currblk['margin_right']);
+ }
+ }
+ else if (isset($properties['FLOAT']) && strtoupper($properties['FLOAT']) == 'LEFT' && !$this->ColActive) {
+ // Cancel Keep-Block-together
+ $currblk['keep_block_together'] = false;
+ $this->kt_y00 = '';
+ $this->keep_block_together = 0;
+
+ $this->blockContext++;
+ $currblk['blockContext'] = $this->blockContext;
+
+ list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
+
+ // DIV is too narrow for text to fit!
+ $maxw = $container_w - $l_width - $r_width;
+ if (($setwidth + $currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr) > $maxw || ($maxw - ($currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr)) < (2*$this->GetCharWidth('W',false))) {
+ // Too narrow to fit - try to move down past L or R float
+ if ($l_max < $r_max && ($setwidth + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) <= ($container_w - $r_width) && (($container_w - $r_width) - ($currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr)) > (2*$this->GetCharWidth('W',false))) {
+ $this->ClearFloats('LEFT', $this->blklvl-1);
+ }
+ else if ($r_max < $l_max && ($setwidth + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) <= ($container_w - $l_width) && (($container_w - $l_width) - ($currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr)) > (2*$this->GetCharWidth('W',false))) {
+ $this->ClearFloats('RIGHT', $this->blklvl-1);
+ }
+ else { $this->ClearFloats('BOTH', $this->blklvl-1); }
+ list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
+ }
+
+ if ($l_exists) { $currblk['margin_left'] += $l_width; }
+
+ $currblk['float'] = 'L';
+ $currblk['float_start_y'] = $this->y;
+ if ($setwidth) {
+ $currblk['margin_right'] = $container_w - ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_left']);
+ $currblk['float_width'] = ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_left']);
+ }
+ else {
+ // *** If no width set - would need to buffer and keep track of max width, then Right-align if not full width
+ // and do borders and backgrounds - For now - just set to maximum width left
+
+ if ($r_exists) { $currblk['margin_right'] += $r_width; }
+ $currblk['css_set_width'] = $container_w - ($currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr);
+
+ $currblk['float_width'] = ($currblk['css_set_width'] + $bdl + $pdl + $bdr + $pdr + $currblk['margin_left']);
+ }
+ }
+
+ else {
+ // Don't allow overlap - if floats present - adjust padding to avoid overlap with Floats
+ list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
+ $maxw = $container_w - $l_width - $r_width;
+ if (($setwidth + $currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) > $maxw || ($maxw - ($currblk['margin_right'] + $currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr)) < (2*$this->GetCharWidth('W',false))) {
+ // Too narrow to fit - try to move down past L or R float
+ if ($l_max < $r_max && ($setwidth + $currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) <= ($container_w - $r_width) && (($container_w - $r_width) - ($currblk['margin_right'] + $currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr)) > (2*$this->GetCharWidth('W',false))) {
+ $this->ClearFloats('LEFT', $this->blklvl-1);
+ }
+ else if ($r_max < $l_max && ($setwidth + $currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) <= ($container_w - $l_width) && (($container_w - $l_width) - ($currblk['margin_right'] + $currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr)) > (2*$this->GetCharWidth('W',false))) {
+ $this->ClearFloats('RIGHT', $this->blklvl-1);
+ }
+ else { $this->ClearFloats('BOTH', $this->blklvl-1); }
+ list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl-1);
+ }
+ if ($r_exists) { $currblk['padding_right'] = max(($r_width-$currblk['margin_right']-$bdr), $pdr); }
+ if ($l_exists) { $currblk['padding_left'] = max(($l_width-$currblk['margin_left']-$bdl), $pdl); }
+ }
+/*-- END CSS-FLOAT --*/
+
+
+/*-- BORDER-RADIUS --*/
+ // Automatically increase padding if required for border-radius
+ if ($this->autoPadding && !$this->ColActive) {
+ if ($currblk['border_radius_TL_H']>$currblk['padding_left'] && $currblk['border_radius_TL_V']>$currblk['padding_top']) {
+ if ($currblk['border_radius_TL_H']>$currblk['border_radius_TL_V']) {
+ $this->_borderPadding($currblk['border_radius_TL_H'],$currblk['border_radius_TL_V'], $currblk['padding_left'], $currblk['padding_top']);
+ }
+ else {
+ $this->_borderPadding($currblk['border_radius_TL_V'],$currblk['border_radius_TL_H'], $currblk['padding_top'], $currblk['padding_left']);
+ }
+ }
+ if ($currblk['border_radius_TR_H']>$currblk['padding_right'] && $currblk['border_radius_TR_V']>$currblk['padding_top']) {
+ if ($currblk['border_radius_TR_H']>$currblk['border_radius_TR_V']) {
+ $this->_borderPadding($currblk['border_radius_TR_H'],$currblk['border_radius_TR_V'], $currblk['padding_right'], $currblk['padding_top']);
+ }
+ else {
+ $this->_borderPadding($currblk['border_radius_TR_V'],$currblk['border_radius_TR_H'], $currblk['padding_top'], $currblk['padding_right']);
+ }
+ }
+ if ($currblk['border_radius_BL_H']>$currblk['padding_left'] && $currblk['border_radius_BL_V']>$currblk['padding_bottom']) {
+ if ($currblk['border_radius_BL_H']>$currblk['border_radius_BL_V']) {
+ $this->_borderPadding($currblk['border_radius_BL_H'],$currblk['border_radius_BL_V'], $currblk['padding_left'], $currblk['padding_bottom']);
+ }
+ else {
+ $this->_borderPadding($currblk['border_radius_BL_V'],$currblk['border_radius_BL_H'], $currblk['padding_bottom'], $currblk['padding_left']);
+ }
+ }
+ if ($currblk['border_radius_BR_H']>$currblk['padding_right'] && $currblk['border_radius_BR_V']>$currblk['padding_bottom']) {
+ if ($currblk['border_radius_BR_H']>$currblk['border_radius_BR_V']) {
+ $this->_borderPadding($currblk['border_radius_BR_H'],$currblk['border_radius_BR_V'], $currblk['padding_right'], $currblk['padding_bottom']);
+ }
+ else {
+ $this->_borderPadding($currblk['border_radius_BR_V'],$currblk['border_radius_BR_H'], $currblk['padding_bottom'], $currblk['padding_right']);
+ }
+ }
+ }
+/*-- END BORDER-RADIUS --*/
+
+
+ // Hanging indent - if negative indent: ensure padding is >= indent
+ if(!isset($currblk['text_indent'])) { $currblk['text_indent'] = null; }
+ if(!isset($currblk['inner_width'])) { $currblk['inner_width'] = null; }
+ $cbti = $this->ConvertSize($currblk['text_indent'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ if ($cbti < 0) {
+ $hangind = -($cbti);
+ if (isset($currblk['direction']) && $currblk['direction'] == 'rtl') { // *OTL*
+ $currblk['padding_right'] = max($currblk['padding_right'],$hangind); // *OTL*
+ } // *OTL*
+ else { // *OTL*
+ $currblk['padding_left'] = max($currblk['padding_left'],$hangind);
+ } // *OTL*
+ }
+
+ if (isset($currblk['css_set_width'])) {
+ if (isset($properties['MARGIN-LEFT']) && isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-LEFT'])=='auto' && strtolower($properties['MARGIN-RIGHT'])=='auto') {
+ // Try to reduce margins to accomodate - if still too wide, set margin-right/left=0 (reduces width)
+ $anyextra = $prevblk['inner_width'] - ($currblk['css_set_width'] + $currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right']);
+ if ($anyextra>0) {
+ $currblk['margin_left'] = $currblk['margin_right'] = $anyextra /2;
+ }
+ else {
+ $currblk['margin_left'] = $currblk['margin_right'] = 0;
+ }
+ }
+ else if (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
+ // Try to reduce margin-left to accomodate - if still too wide, set margin-left=0 (reduces width)
+ $currblk['margin_left'] = $prevblk['inner_width'] - ($currblk['css_set_width'] + $currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right'] + $currblk['margin_right']);
+ if ($currblk['margin_left'] < 0) {
+ $currblk['margin_left'] = 0;
+ }
+ }
+ else if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto') {
+ // Try to reduce margin-right to accomodate - if still too wide, set margin-right=0 (reduces width)
+ $currblk['margin_right'] = $prevblk['inner_width'] - ($currblk['css_set_width'] + $currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right'] + $currblk['margin_left']);
+ if ($currblk['margin_right'] < 0) {
+ $currblk['margin_right'] = 0;
+ }
+ }
+ else {
+ if ($currblk['direction'] == 'rtl') { // *OTL*
+ // Try to reduce margin-left to accomodate - if still too wide, set margin-left=0 (reduces width)
+ $currblk['margin_left'] = $prevblk['inner_width'] - ($currblk['css_set_width'] + $currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right'] + $currblk['margin_right']); // *OTL*
+ if ($currblk['margin_left'] < 0) { // *OTL*
+ $currblk['margin_left'] = 0; // *OTL*
+ } // *OTL*
+ } // *OTL*
+ else { // *OTL*
+ // Try to reduce margin-right to accomodate - if still too wide, set margin-right=0 (reduces width)
+ $currblk['margin_right'] = $prevblk['inner_width'] - ($currblk['css_set_width'] + $currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right'] + $currblk['margin_left']);
+ if ($currblk['margin_right'] < 0) {
+ $currblk['margin_right'] = 0;
+ }
+ } // *OTL*
+ }
+ }
+
+ $currblk['outer_left_margin'] = $prevblk['outer_left_margin'] + $currblk['margin_left'] + $prevblk['border_left']['w'] + $prevblk['padding_left'];
+ $currblk['outer_right_margin'] = $prevblk['outer_right_margin'] + $currblk['margin_right'] + $prevblk['border_right']['w'] + $prevblk['padding_right'];
+
+ $currblk['width'] = $this->pgwidth - ($currblk['outer_right_margin'] + $currblk['outer_left_margin']);
+ $currblk['inner_width'] = $currblk['width'] - ($currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right']);
+
+ // Check DIV is not now too narrow to fit text
+ $mw = 2*$this->GetCharWidth('W',false);
+ if ($currblk['inner_width'] < $mw) {
+ $currblk['padding_left'] = 0;
+ $currblk['padding_right'] = 0;
+ $currblk['border_left']['w'] = 0.2;
+ $currblk['border_right']['w'] = 0.2;
+ $currblk['margin_left'] = 0;
+ $currblk['margin_right'] = 0;
+ $currblk['outer_left_margin'] = $prevblk['outer_left_margin'] + $currblk['margin_left'] + $prevblk['border_left']['w'] + $prevblk['padding_left'];
+ $currblk['outer_right_margin'] = $prevblk['outer_right_margin'] + $currblk['margin_right'] + $prevblk['border_right']['w'] + $prevblk['padding_right'];
+ $currblk['width'] = $this->pgwidth - ($currblk['outer_right_margin'] + $currblk['outer_left_margin']);
+ $currblk['inner_width'] = $this->pgwidth - ($currblk['outer_right_margin'] + $currblk['outer_left_margin'] + $currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right']);
+// if ($currblk['inner_width'] < $mw) { $this->Error("DIV is too narrow for text to fit!"); }
+ }
+
+ $this->x = $this->lMargin + $currblk['outer_left_margin'];
+
+/*-- BACKGROUNDS --*/
+ if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->kwt && !$this->ColActive && !$this->keep_block_together) {
+ $ret = $this->SetBackground($properties, $currblk['inner_width']);
+ if ($ret) { $currblk['background-image'] = $ret; }
+ }
+/*-- END BACKGROUNDS --*/
+
+/*-- TABLES --*/
+ if ($this->use_kwt && isset($attr['KEEP-WITH-TABLE']) && !$this->ColActive && !$this->keep_block_together) {
+ $this->kwt = true;
+ $this->kwt_y0 = $this->y;
+ //$this->kwt_x0 = $this->x;
+ $this->kwt_x0 = $this->lMargin; // mPDF 6
+ $this->kwt_height = 0;
+ $this->kwt_buffer = array();
+ $this->kwt_Links = array();
+ $this->kwt_Annots = array();
+ $this->kwt_moved = false;
+ $this->kwt_saved = false;
+ $this->kwt_Reference = array();
+ $this->kwt_BMoutlines = array();
+ $this->kwt_toc = array();
+ }
+ else {
+/*-- END TABLES --*/
+ $this->kwt = false;
+ } // *TABLES*
+
+ //Save x,y coords in case we need to print borders...
+ $currblk['y0'] = $this->y;
+ $currblk['initial_y0'] = $this->y; // mPDF 6
+ $currblk['x0'] = $this->x;
+ $currblk['initial_x0'] = $this->x; // mPDF 6
+ $currblk['initial_startpage'] = $this->page;
+ $currblk['startpage'] = $this->page; // mPDF 6
+ $this->oldy = $this->y;
+
+ $this->lastblocklevelchange = 1 ;
+
+
+ // mPDF 6 Lists
+ if ($tag == 'OL' || $tag == 'UL') {
+ $this->listlvl++;
+ if (isset($attr['START']) && $attr['START']) { $this->listcounter[$this->listlvl] = intval($attr['START'])-1; }
+ else { $this->listcounter[$this->listlvl] = 0; }
+ $this->listitem = array();
+
+ // List-type
+ if (!isset($currblk['list_style_type']) || !$currblk['list_style_type']) {
+ if ($tag == 'OL') $currblk['list_style_type'] = 'decimal';
+ else if ($tag == 'UL') {
+ if ($this->listlvl % 3 == 1) $currblk['list_style_type'] = 'disc';
+ elseif ($this->listlvl % 3 == 2) $currblk['list_style_type'] = 'circle';
+ else $currblk['list_style_type'] = 'square';
+ }
+ }
+
+ // List-image
+ if (!isset($currblk['list_style_image']) || !$currblk['list_style_image']) { $currblk['list_style_image'] = 'none'; }
+
+ // List-position
+ if (!isset($currblk['list_style_position']) || !$currblk['list_style_position']) { $currblk['list_style_position'] = 'outside'; }
+
+ // Default indentation using padding
+ if (strtolower($this->list_auto_mode) == 'mpdf' && isset($currblk['list_style_position']) && $currblk['list_style_position'] == 'outside' && isset($currblk['list_style_image']) && $currblk['list_style_image'] == 'none' && (!isset($currblk['list_style_type']) ||!preg_match('/U\+([a-fA-F0-9]+)/i',$currblk['list_style_type'])) ) {
+ $autopadding = $this->_getListMarkerWidth($currblk,$ahtml,$ihtml);
+ if ($this->listlvl > 1 || $this->list_indent_first_level) { $autopadding += $this->ConvertSize($this->list_indent_default_mpdf,$currblk['inner_width'],$this->FontSize,false); }
+ // autopadding value is applied to left or right according
+ // to dir of block. Once a CSS value is set for padding it overrides this default value.
+ if (isset($properties['PADDING-RIGHT']) && $properties['PADDING-RIGHT']=='auto' && isset($currblk['direction']) && $currblk['direction'] == 'rtl') { $currblk['padding_right'] = $autopadding; }
+ else if (isset($properties['PADDING-LEFT']) && $properties['PADDING-LEFT']=='auto') { $currblk['padding_left'] = $autopadding; }
+ }
+ else {
+ // Initial default value is set by $this->list_indent_default in config.php; this value is applied to left or right according
+ // to dir of block. Once a CSS value is set for padding it overrides this default value.
+ if (isset($properties['PADDING-RIGHT']) && $properties['PADDING-RIGHT']=='auto' && isset($currblk['direction']) && $currblk['direction'] == 'rtl') { $currblk['padding_right'] = $this->ConvertSize($this->list_indent_default,$currblk['inner_width'],$this->FontSize,false); }
+ else if (isset($properties['PADDING-LEFT']) && $properties['PADDING-LEFT']=='auto') { $currblk['padding_left'] = $this->ConvertSize($this->list_indent_default,$currblk['inner_width'],$this->FontSize,false); }
+ }
+ }
+
+
+ // mPDF 6 Lists
+ if ($tag == 'LI') {
+ if ($this->listlvl == 0) { //in case of malformed HTML code. Example:(...)ContentParagraph1 (...)
+ $this->listlvl++; // first depth level
+ $this->listcounter[$this->listlvl] = 0;
+ }
+ $this->listcounter[$this->listlvl]++;
+ $this->listitem = array();
+
+ // Listitem-type
+ $this->_setListMarker($currblk['list_style_type'], $currblk['list_style_image'], $currblk['list_style_position']);
+ }
+
+ // mPDF 6 Bidirectional formatting for block elements
+ $bdf = false;
+ $bdf2 = '';
+ $popd = '';
+
+ // Get current direction
+ if (isset($currblk['direction'])) { $currdir = $currblk['direction']; }
+ else { $currdir = 'ltr'; }
+ if (isset($attr['DIR']) and $attr['DIR'] != '') { $currdir = strtolower($attr['DIR']); }
+ if(isset($properties['DIRECTION'])) { $currdir = strtolower($properties['DIRECTION']); }
+
+ // mPDF 6 bidi
+ // cf. http://www.w3.org/TR/css3-writing-modes/#unicode-bidi
+ if(isset($properties ['UNICODE-BIDI']) && (strtolower($properties ['UNICODE-BIDI'])=='bidi-override' || strtolower($properties ['UNICODE-BIDI'])=='isolate-override')) {
+ if ($currdir == 'rtl') { $bdf = 0x202E; $popd = 'RLOPDF';} // U+202E RLO
+ else { $bdf = 0x202D; $popd = 'LROPDF'; } // U+202D LRO
+ }
+ else if(isset($properties ['UNICODE-BIDI']) && strtolower($properties ['UNICODE-BIDI'])=='plaintext') {
+ $bdf = 0x2068; $popd = 'FSIPDI'; // U+2068 FSI
+ }
+ if ($bdf) {
+ if ($bdf2) { $bdf2 = code2utf($bdf); }
+ $this->OTLdata = array();
+ if($this->tableLevel) { $this->_saveCellTextBuffer(code2utf($bdf).$bdf2); }
+ else { $this->_saveTextBuffer(code2utf($bdf).$bdf2); }
+ $this->biDirectional = true;
+ $currblk['bidicode'] = $popd;
+ }
+
+ break;
+
+ case 'HR':
+ // Added mPDF 3.0 Float DIV - CLEAR
+ if (isset($attr['STYLE'])) {
+ $properties = $this->cssmgr->readInlineCSS($attr['STYLE']);
+ if (isset($properties['CLEAR'])) { $this->ClearFloats(strtoupper($properties['CLEAR']),$this->blklvl); } // *CSS-FLOAT*
+ }
+
+ $this->ignorefollowingspaces = true;
+
+ $objattr = array();
+ $objattr['margin_top'] = 0;
+ $objattr['margin_bottom'] = 0;
+ $objattr['margin_left'] = 0;
+ $objattr['margin_right'] = 0;
+ $objattr['width'] = 0;
+ $objattr['height'] = 0;
+ $objattr['border_top']['w'] = 0;
+ $objattr['border_bottom']['w'] = 0;
+ $objattr['border_left']['w'] = 0;
+ $objattr['border_right']['w'] = 0;
+ $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
+ if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top'] = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['WIDTH'])) { $objattr['width'] = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width']); }
+ else if(isset($attr['WIDTH']) && $attr['WIDTH'] != '') $objattr['width'] = $this->ConvertSize($attr['WIDTH'],$this->blk[$this->blklvl]['inner_width']);
+ if (isset($properties['TEXT-ALIGN'])) { $objattr['align'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
+ else if(isset($attr['ALIGN']) && $attr['ALIGN'] != '') $objattr['align'] = $align[strtolower($attr['ALIGN'])];
+
+ if (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
+ $objattr['align'] = 'R';
+ }
+ if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto') {
+ $objattr['align'] = 'L';
+ if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto' && isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
+ $objattr['align'] = 'C';
+ }
+ }
+ if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
+ else if(isset($attr['COLOR']) && $attr['COLOR'] != '') $objattr['color'] = $this->ConvertColor($attr['COLOR']);
+ if (isset($properties['HEIGHT'])) { $objattr['linewidth'] = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+
+
+/*-- TABLES --*/
+ if ($this->tableLevel) {
+ $objattr['W-PERCENT'] = 100;
+ if (isset($properties['WIDTH']) && stristr($properties['WIDTH'],'%')) {
+ $properties['WIDTH'] += 0; //make "90%" become simply "90"
+ $objattr['W-PERCENT'] = $properties['WIDTH'];
+ }
+ if (isset($attr['WIDTH']) && stristr($attr['WIDTH'],'%')) {
+ $attr['WIDTH'] += 0; //make "90%" become simply "90"
+ $objattr['W-PERCENT'] = $attr['WIDTH'];
+ }
+ }
+/*-- END TABLES --*/
+
+ $objattr['type'] = 'hr';
+ $objattr['height'] = $objattr['linewidth'] + $objattr['margin_top'] + $objattr['margin_bottom'];
+ $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
+
+ // Clear properties - tidy up
+ $properties = array();
+
+/*-- TABLES --*/
+ // Output it to buffers
+ if ($this->tableLevel) {
+ if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
+ $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
+ }
+ elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
+ $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
+ }
+ $this->cell[$this->row][$this->col]['s'] = 0 ;// reset
+ $this->_saveCellTextBuffer($e, $this->HREF);
+ }
+ else {
+/*-- END TABLES --*/
+ $this->_saveTextBuffer($e, $this->HREF);
+ } // *TABLES*
+
+ break;
+
+
+/*-- BARCODES --*/
+
+ case 'BARCODE':
+ $this->ignorefollowingspaces = false;
+ if(isset($attr['CODE']) && $attr['CODE']) {
+ $objattr = array();
+ $objattr['margin_top'] = 0;
+ $objattr['margin_bottom'] = 0;
+ $objattr['margin_left'] = 0;
+ $objattr['margin_right'] = 0;
+ $objattr['padding_top'] = 0;
+ $objattr['padding_bottom'] = 0;
+ $objattr['padding_left'] = 0;
+ $objattr['padding_right'] = 0;
+ $objattr['width'] = 0;
+ $objattr['height'] = 0;
+ $objattr['border_top']['w'] = 0;
+ $objattr['border_bottom']['w'] = 0;
+ $objattr['border_left']['w'] = 0;
+ $objattr['border_right']['w'] = 0;
+ $objattr['code'] = $attr['CODE'];
+
+ if(isset($attr['TYPE'])) {
+ $objattr['btype'] = trim(strtoupper($attr['TYPE']));
+ }
+ else { $objattr['btype'] = 'EAN13'; } // default
+ if (preg_match('/^(EAN13|ISBN|ISSN|EAN8|UPCA|UPCE)P([25])$/',$objattr['btype'],$m)) {
+ $objattr['btype'] = $m[1];
+ $objattr['bsupp'] = $m[2];
+ if (preg_match('/^(\S+)\s+(.*)$/',$objattr['code'],$mm)) {
+ $objattr['code'] = $mm[1];
+ $objattr['bsupp_code'] = $mm[2];
+ }
+ }
+ else { $objattr['bsupp'] = 0; }
+
+ if(isset($attr['TEXT']) && $attr['TEXT']==1) { $objattr['showtext'] = 1; }
+ else { $objattr['showtext'] = 0; }
+ if(isset($attr['SIZE']) && $attr['SIZE']>0) { $objattr['bsize'] = $attr['SIZE']; }
+ else { $objattr['bsize'] = 1; }
+ if(isset($attr['HEIGHT']) && $attr['HEIGHT']>0) { $objattr['bheight'] = $attr['HEIGHT']; }
+ else { $objattr['bheight'] = 1; }
+ if(isset($attr['PR']) && $attr['PR']>0) { $objattr['pr_ratio'] = $attr['PR']; }
+ else { $objattr['pr_ratio'] = ''; }
+ $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
+ if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
+ return;
+ }
+ if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+
+ if (isset($properties['PADDING-TOP'])) { $objattr['padding_top']=$this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['PADDING-BOTTOM'])) { $objattr['padding_bottom'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['PADDING-LEFT'])) { $objattr['padding_left'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['PADDING-RIGHT'])) { $objattr['padding_right'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+
+ if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
+ if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
+ if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
+ if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
+
+ if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
+ if (isset($properties['COLOR']) && $properties['COLOR'] != '') { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
+ else { $objattr['color'] = false; }
+ if (isset($properties['BACKGROUND-COLOR']) && $properties['BACKGROUND-COLOR'] != '') { $objattr['bgcolor'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
+ else { $objattr['bgcolor'] = false; }
+
+ if (!class_exists('PDFBarcode', false)) {
+ include(_MPDF_PATH.'classes/barcode.php');
+ }
+ $this->barcode = new PDFBarcode();
+
+ if ($objattr['btype'] == 'EAN13' || $objattr['btype'] == 'ISBN' || $objattr['btype'] == 'ISSN' || $objattr['btype'] == 'UPCA' || $objattr['btype'] == 'UPCE' || $objattr['btype'] == 'EAN8') {
+ $code = preg_replace('/\-/','',$objattr['code']);
+ if ($objattr['btype'] == 'ISSN' || $objattr['btype'] == 'ISBN') {
+ $arrcode = $this->barcode->getBarcodeArray($code, 'EAN13');
+ }
+ else { $arrcode = $this->barcode->getBarcodeArray($code, $objattr['btype'] ); }
+ if ($arrcode === false) { $this->Error('Error in barcode string.'); }
+
+ if ($objattr['bsupp'] == 2 || $objattr['bsupp'] == 5) { // EAN-2 or -5 Supplement
+ $supparrcode = $this->barcode->getBarcodeArray($objattr['bsupp_code'], 'EAN'.$objattr['bsupp'] );
+ $w = ($arrcode["maxw"] + $arrcode['lightmL'] + $arrcode['lightmR'] + $supparrcode["maxw"] + $supparrcode['sepM']) * $arrcode['nom-X'] * $objattr['bsize'];
+ }
+ else {
+ $w = ($arrcode["maxw"] + $arrcode['lightmL'] + $arrcode['lightmR']) * $arrcode['nom-X'] * $objattr['bsize'];
+ }
+ $h = $arrcode['nom-H'] * $objattr['bsize'] * $objattr['bheight'];
+ // Add height for ISBN string + margin from top of bars
+ if (($objattr['showtext'] && $objattr['btype'] == 'EAN13') || $objattr['btype'] == 'ISBN' || $objattr['btype'] == 'ISSN') {
+ $tisbnm = 1.5 * $objattr['bsize']; // Top margin between TOP TEXT (isbn - if shown) & bars
+ $isbn_fontsize = 2.1 * $objattr['bsize'];
+ $h += $isbn_fontsize + $tisbnm ;
+ }
+ }
+ // QR-code
+ else if ($objattr['btype'] == 'QR') {
+ $w = $h = $objattr['bsize']*25; // Factor of 25mm (default)
+ $objattr['errorlevel'] = 'L';
+ if (isset($attr['ERROR'])) { $objattr['errorlevel'] = $attr['ERROR']; }
+ }
+ else if ($objattr['btype'] == 'IMB' || $objattr['btype'] == 'RM4SCC' || $objattr['btype'] == 'KIX' || $objattr['btype'] == 'POSTNET' || $objattr['btype'] == 'PLANET') {
+ $arrcode = $this->barcode->getBarcodeArray($objattr['code'], $objattr['btype'] );
+ if ($arrcode === false) { $this->Error('Error in barcode string.'); }
+ $w = ($arrcode["maxw"] * $arrcode['nom-X'] * $objattr['bsize']) + $arrcode['quietL'] + $arrcode['quietR'];
+ $h = ($arrcode['nom-H'] * $objattr['bsize']) + (2*$arrcode['quietTB']);
+ }
+ else if (in_array($objattr['btype'], array('C128A','C128B','C128C','EAN128A','EAN128B','EAN128C','C39','C39+','C39E','C39E+','S25','S25+','I25','I25+','I25B','I25B+','C93','MSI','MSI+','CODABAR','CODE11'))) {
+ $arrcode = $this->barcode->getBarcodeArray($objattr['code'], $objattr['btype'], $objattr['pr_ratio'] );
+ if ($arrcode === false) { $this->Error('Error in barcode string.'); }
+ $w = ($arrcode["maxw"] + $arrcode['lightmL'] + $arrcode['lightmR']) * $arrcode['nom-X'] * $objattr['bsize'];
+ $h = ((2*$arrcode['lightTB'] * $arrcode['nom-X']) + $arrcode['nom-H']) * $objattr['bsize'] * $objattr['bheight'];
+ }
+ else { break; }
+
+ $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
+ $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
+
+ $objattr['type'] = 'barcode';
+ $objattr['height'] = $h + $extraheight;
+ $objattr['width'] = $w + $extrawidth;
+ $objattr['barcode_height'] = $h;
+ $objattr['barcode_width'] = $w;
+/*-- CSS-IMAGE-FLOAT --*/
+ if (!$this->ColActive && !$this->tableLevel && !$this->listlvl && !$this->kwt) {
+ if (isset($properties['FLOAT']) && (strtoupper($properties['FLOAT']) == 'RIGHT' || strtoupper($properties['FLOAT']) == 'LEFT')) {
+ $objattr['float'] = substr(strtoupper($properties['FLOAT']),0,1);
+ }
+ }
+/*-- END CSS-IMAGE-FLOAT --*/
+
+ $e = "\xbb\xa4\xactype=barcode,objattr=".serialize($objattr)."\xbb\xa4\xac";
+
+ // Clear properties - tidy up
+ $properties = array();
+
+/*-- TABLES --*/
+ // Output it to buffers
+ if ($this->tableLevel) {
+ $this->_saveCellTextBuffer($e, $this->HREF);
+ $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
+ }
+ else {
+/*-- END TABLES --*/
+ $this->_saveTextBuffer($e, $this->HREF);
+
+ } // *TABLES*
+ }
+ break;
+/*-- END BARCODES --*/
+
+
+ // *********** FORM ELEMENTS ********************
+
+/*-- FORMS --*/
+ case 'SELECT':
+ $this->lastoptionaltag = ''; // Save current HTML specified optional endtag
+ $this->InlineProperties[$tag] = $this->saveInlineProperties();
+ $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
+ if (isset($properties['FONT-FAMILY'])) {
+ $this->SetFont($properties['FONT-FAMILY'],$this->FontStyle,0,false);
+ }
+ if (isset($properties['FONT-SIZE'])) {
+ $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size/_MPDFK);
+ $this->SetFontSize($mmsize*_MPDFK,false);
+ }
+ if (isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK'])=='true') {
+ $this->selectoption['SPELLCHECK'] = true;
+ }
+
+ if (isset($properties['COLOR'])) { $this->selectoption['COLOR'] = $this->ConvertColor($properties['COLOR']); }
+ $this->specialcontent = "type=select";
+ if(isset($attr['DISABLED'])) { $this->selectoption['DISABLED'] = $attr['DISABLED']; }
+ if(isset($attr['READONLY'])) { $this->selectoption['READONLY'] = $attr['READONLY']; }
+ if(isset($attr['REQUIRED'])) { $this->selectoption['REQUIRED'] = $attr['REQUIRED']; }
+ if(isset($attr['EDITABLE'])) { $this->selectoption['EDITABLE'] = $attr['EDITABLE']; }
+ if(isset($attr['TITLE'])) { $this->selectoption['TITLE'] = $attr['TITLE']; }
+ if(isset($attr['MULTIPLE'])) { $this->selectoption['MULTIPLE'] = $attr['MULTIPLE']; }
+ if(isset($attr['SIZE']) && $attr['SIZE']>1) { $this->selectoption['SIZE'] = $attr['SIZE']; }
+ if ($this->useActiveForms) {
+ if(isset($attr['NAME'])) { $this->selectoption['NAME'] = $attr['NAME']; }
+ if (isset($attr['ONCHANGE'])) { $this->selectoption['ONCHANGE'] = $attr['ONCHANGE']; }
+ }
+
+ $properties = array();
+ break;
+
+ case 'OPTION':
+ $this->lastoptionaltag = '';
+ $this->selectoption['ACTIVE'] = true;
+ $this->selectoption['currentSEL'] = false;
+ if (empty($this->selectoption)) {
+ $this->selectoption['MAXWIDTH'] = '';
+ $this->selectoption['SELECTED'] = '';
+ }
+ if (isset($attr['SELECTED'])) {
+ $this->selectoption['SELECTED'] = '';
+ $this->selectoption['currentSEL'] = true;
+ }
+ if(isset($attr['VALUE'])) {
+ $attr['VALUE'] = strcode2utf($attr['VALUE']);
+ $attr['VALUE'] = $this->lesser_entity_decode($attr['VALUE']);
+ if ($this->onlyCoreFonts)
+ $attr['VALUE'] = mb_convert_encoding($attr['VALUE'], $this->mb_enc,'UTF-8');
+ }
+ $this->selectoption['currentVAL'] = $attr['VALUE'];
+ break;
+
+ case 'TEXTAREA':
+ $objattr = array();
+ $objattr['margin_top'] = 0;
+ $objattr['margin_bottom'] = 0;
+ $objattr['margin_left'] = 0;
+ $objattr['margin_right'] = 0;
+ $objattr['width'] = 0;
+ $objattr['height'] = 0;
+ $objattr['border_top']['w'] = 0;
+ $objattr['border_bottom']['w'] = 0;
+ $objattr['border_left']['w'] = 0;
+ $objattr['border_right']['w'] = 0;
+ if(isset($attr['DISABLED'])) { $objattr['disabled'] = true; }
+ if(isset($attr['READONLY'])) { $objattr['readonly'] = true; }
+ if(isset($attr['REQUIRED'])) { $objattr['required'] = true; }
+ if(isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK'])=='true') { $objattr['spellcheck'] = true; }
+ if(isset($attr['TITLE'])) {
+ $objattr['title'] = $attr['TITLE'];
+ if ($this->onlyCoreFonts)
+ $objattr['title'] = mb_convert_encoding($objattr['title'], $this->mb_enc,'UTF-8');
+ }
+ if ($this->useActiveForms) {
+ if(isset($attr['NAME'])) { $objattr['fieldname'] = $attr['NAME']; }
+ $this->mpdfform->form_element_spacing['textarea']['outer']['v'] = 0;
+ $this->mpdfform->form_element_spacing['textarea']['inner']['v'] = 0;
+ if (isset($attr['ONCALCULATE'])) { $objattr['onCalculate'] = $attr['ONCALCULATE']; }
+ else if (isset($attr['ONCHANGE'])) { $objattr['onCalculate'] = $attr['ONCHANGE']; }
+ if (isset($attr['ONVALIDATE'])) { $objattr['onValidate'] = $attr['ONVALIDATE']; }
+ if (isset($attr['ONKEYSTROKE'])) { $objattr['onKeystroke'] = $attr['ONKEYSTROKE']; }
+ if (isset($attr['ONFORMAT'])) { $objattr['onFormat'] = $attr['ONFORMAT']; }
+ }
+ $this->InlineProperties[$tag] = $this->saveInlineProperties();
+ $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
+ if (isset($properties['FONT-FAMILY'])) {
+ $this->SetFont($properties['FONT-FAMILY'],'',0,false);
+ }
+ if (isset($properties['FONT-SIZE'])) {
+ $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size/_MPDFK);
+ $this->SetFontSize($mmsize*_MPDFK,false);
+ }
+ if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
+ $objattr['fontfamily'] = $this->FontFamily;
+ $objattr['fontsize'] = $this->FontSizePt;
+ if ($this->useActiveForms) {
+ if(isset($properties['TEXT-ALIGN'])) { $objattr['text_align'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
+ else if(isset($attr['ALIGN'])) { $objattr['text_align'] = $align[strtolower($attr['ALIGN'])]; }
+ if (isset($properties['OVERFLOW']) && strtolower($properties['OVERFLOW'])=='hidden') { $objattr['donotscroll'] = true; }
+ if (isset($properties['BORDER-TOP-COLOR'])) { $objattr['border-col'] = $this->ConvertColor($properties['BORDER-TOP-COLOR']); }
+ if (isset($properties['BACKGROUND-COLOR'])) { $objattr['background-col'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
+ }
+ $this->SetLineHeight('',$this->mpdfform->textarea_lineheight);
+
+ $w = 0;
+ $h = 0;
+ if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
+
+ $colsize = 20; //HTML default value
+ $rowsize = 2; //HTML default value
+ if (isset($attr['COLS'])) $colsize = intval($attr['COLS']);
+ if (isset($attr['ROWS'])) $rowsize = intval($attr['ROWS']);
+
+ $charsize = $this->GetCharWidth('w',false);
+ if ($w) { $colsize = round(($w-($this->mpdfform->form_element_spacing['textarea']['outer']['h']*2)-($this->mpdfform->form_element_spacing['textarea']['inner']['h']*2))/$charsize); }
+ if ($h) { $rowsize = round(($h-($this->mpdfform->form_element_spacing['textarea']['outer']['v']*2)-($this->mpdfform->form_element_spacing['textarea']['inner']['v']*2))/$this->lineheight); }
+
+ $objattr['type'] = 'textarea';
+ $objattr['width'] = ($colsize * $charsize) + ($this->mpdfform->form_element_spacing['textarea']['outer']['h']*2)+($this->mpdfform->form_element_spacing['textarea']['inner']['h']*2);
+ $objattr['height'] = ($rowsize * $this->lineheight) + ($this->mpdfform->form_element_spacing['textarea']['outer']['v']*2)+($this->mpdfform->form_element_spacing['textarea']['inner']['v']*2);
+ $objattr['rows'] = $rowsize;
+ $objattr['cols'] = $colsize;
+
+ $this->specialcontent = serialize($objattr);
+
+ if ($this->tableLevel) { // *TABLES*
+ $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ; // *TABLES*
+ } // *TABLES*
+
+ // Clear properties - tidy up
+ $properties = array();
+ break;
+
+
+
+ // *********** FORM - INPUT ********************
+
+ case 'INPUT':
+ $this->ignorefollowingspaces = false;
+ if (!isset($attr['TYPE'])) $attr['TYPE'] == 'TEXT';
+ $objattr = array();
+ $objattr['margin_top'] = 0;
+ $objattr['margin_bottom'] = 0;
+ $objattr['margin_left'] = 0;
+ $objattr['margin_right'] = 0;
+ $objattr['width'] = 0;
+ $objattr['height'] = 0;
+ $objattr['border_top']['w'] = 0;
+ $objattr['border_bottom']['w'] = 0;
+ $objattr['border_left']['w'] = 0;
+ $objattr['border_right']['w'] = 0;
+ $objattr['type'] = 'input';
+ if(isset($attr['DISABLED'])) { $objattr['disabled'] = true; }
+ if(isset($attr['READONLY'])) { $objattr['readonly'] = true; }
+ if(isset($attr['REQUIRED'])) { $objattr['required'] = true; }
+ if(isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK'])=='true') { $objattr['spellcheck'] = true; }
+ if(isset($attr['TITLE'])) { $objattr['title'] = $attr['TITLE']; }
+ else if(isset($attr['ALT'])) { $objattr['title'] = $attr['ALT']; }
+ else $objattr['title'] = '';
+ $objattr['title'] = strcode2utf($objattr['title']);
+ $objattr['title'] = $this->lesser_entity_decode($objattr['title']);
+ if ($this->onlyCoreFonts)
+ $objattr['title'] = mb_convert_encoding($objattr['title'], $this->mb_enc,'UTF-8');
+ if ($this->useActiveForms) {
+ if(isset($attr['NAME'])) { $objattr['fieldname'] = $attr['NAME']; }
+ }
+ if(isset($attr['VALUE'])) {
+ $attr['VALUE'] = strcode2utf($attr['VALUE']);
+ $attr['VALUE'] = $this->lesser_entity_decode($attr['VALUE']);
+ if ($this->onlyCoreFonts)
+ $attr['VALUE'] = mb_convert_encoding($attr['VALUE'], $this->mb_enc,'UTF-8');
+ $objattr['value'] = $attr['VALUE'];
+ }
+
+ $this->InlineProperties[$tag] = $this->saveInlineProperties();
+ $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
+ $objattr['vertical-align'] = '';
+
+ if (isset($properties['FONT-FAMILY'])) {
+ $this->SetFont($properties['FONT-FAMILY'],$this->FontStyle,0,false);
+ }
+ if (isset($properties['FONT-SIZE'])) {
+ $mmsize = $this->ConvertSize($properties['FONT-SIZE'],($this->default_font_size/_MPDFK));
+ $this->SetFontSize($mmsize*_MPDFK,false);
+ }
+ if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
+ $objattr['fontfamily'] = $this->FontFamily;
+ $objattr['fontsize'] = $this->FontSizePt;
+ if ($this->useActiveForms) {
+ if(isset($attr['ALIGN'])) { $objattr['text_align'] = $align[strtolower($attr['ALIGN'])]; }
+ else if(isset($properties['TEXT-ALIGN'])) { $objattr['text_align'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
+ if (isset($properties['BORDER-TOP-COLOR'])) { $objattr['border-col'] = $this->ConvertColor($properties['BORDER-TOP-COLOR']); }
+ if (isset($properties['BACKGROUND-COLOR'])) { $objattr['background-col'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
+ }
+
+ $type = '';
+ $texto='';
+ $height = $this->FontSize;
+ $width = 0;
+ $spacesize = $this->GetCharWidth(' ',false);
+
+ $w = 0;
+ if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width']);
+
+ if ($properties['VERTICAL-ALIGN']) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
+
+ switch(strtoupper($attr['TYPE'])){
+ case 'HIDDEN':
+ $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
+ if ($this->useActiveForms) {
+ $this->mpdfform->SetFormText( 0, 0, $objattr['fieldname'], $objattr['value'], $objattr['value'], '', 0, '', true );
+ }
+ if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
+ unset($this->InlineProperties[$tag]);
+ break 2;
+ case 'CHECKBOX': //Draw Checkbox
+ $type = 'CHECKBOX';
+ if (isset($attr['CHECKED'])) { $objattr['checked'] = true; }
+ else { $objattr['checked'] = false; }
+ $width = $this->FontSize;
+ $height = $this->FontSize;
+ break;
+
+ case 'RADIO': //Draw Radio button
+ $type = 'RADIO';
+ if (isset($attr['CHECKED'])) $objattr['checked'] = true;
+ $width = $this->FontSize;
+ $height = $this->FontSize;
+ break;
+
+/*-- IMAGES-CORE --*/
+ case 'IMAGE': // Draw an Image button
+ if(isset($attr['SRC'])) {
+ $type = 'IMAGE';
+ $srcpath = $attr['SRC'];
+ $orig_srcpath = $attr['ORIG_SRC'];
+ // VSPACE and HSPACE converted to margins in MergeCSS
+ if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+
+
+ if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
+ if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
+ if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
+ if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
+
+ $objattr['padding_top'] = 0;
+ $objattr['padding_bottom'] = 0;
+ $objattr['padding_left'] = 0;
+ $objattr['padding_right'] = 0;
+
+ if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
+
+ $w = 0;
+ $h = 0;
+ if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width']);
+ if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width']);
+
+ $extraheight = $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
+ $extrawidth = $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
+
+ // Image file
+ $info=$this->_getImage($srcpath, true, true, $orig_srcpath);
+ if(!$info) {
+ $info = $this->_getImage($this->noImageFile);
+ if ($info) {
+ $srcpath = $this->noImageFile;
+ $w = ($info['w'] * (25.4/$this->dpi));
+ $h = ($info['h'] * (25.4/$this->dpi));
+ }
+ }
+ if(!$info) break;
+ if ($info['cs']=='Indexed') { $objattr['Indexed'] = true; }
+ $objattr['file'] = $srcpath;
+ //Default width and height calculation if needed
+ if($w==0 and $h==0) {
+/*-- IMAGES-WMF --*/
+ if ($info['type']=='wmf') {
+ // WMF units are twips (1/20pt)
+ // divide by 20 to get points
+ // divide by k to get user units
+ $w = abs($info['w'])/(20*_MPDFK);
+ $h = abs($info['h']) / (20*_MPDFK);
+ }
+ else
+/*-- END IMAGES-WMF --*/
+ if ($info['type']=='svg') {
+ // SVG units are pixels
+ $w = abs($info['w'])/_MPDFK;
+ $h = abs($info['h'])/_MPDFK;
+ }
+ else {
+ //Put image at default image dpi
+ $w=($info['w']/_MPDFK) * (72/$this->img_dpi);
+ $h=($info['h']/_MPDFK) * (72/$this->img_dpi);
+ }
+ if (isset($properties['IMAGE-RESOLUTION'])) {
+ if (preg_match('/from-image/i', $properties['IMAGE-RESOLUTION']) && isset($info['set-dpi']) && $info['set-dpi']>0) {
+ $w *= $this->img_dpi / $info['set-dpi'];
+ $h *= $this->img_dpi / $info['set-dpi'];
+ }
+ else if (preg_match('/(\d+)dpi/i', $properties['IMAGE-RESOLUTION'], $m)) {
+ $dpi = $m[1];
+ if ($dpi > 0) {
+ $w *= $this->img_dpi / $dpi;
+ $h *= $this->img_dpi / $dpi;
+ }
+ }
+ }
+ }
+ // IF WIDTH OR HEIGHT SPECIFIED
+ if($w==0) $w=$h*$info['w']/$info['h'];
+ if($h==0) $h=$w*$info['h']/$info['w'];
+ // Resize to maximum dimensions of page
+ $maxWidth = $this->blk[$this->blklvl]['inner_width'];
+ $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 10) ;
+ if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
+ if (($w + $extrawidth) > ($maxWidth + 0.0001) ) { // mPDF 5.7.4 0.0001 to allow for rounding errors when w==maxWidth
+ $w = $maxWidth - $extrawidth;
+ $h=$w*$info['h']/$info['w'];
+ }
+ if ($h + $extraheight > $maxHeight ) {
+ $h = $maxHeight - $extraheight;
+ $w=$h*$info['w']/$info['h'];
+ }
+ $height = $h + $extraheight;
+ $width = $w + $extrawidth;
+ $objattr['type'] = 'image';
+ $objattr['itype'] = $info['type'];
+ $objattr['orig_h'] = $info['h'];
+ $objattr['orig_w'] = $info['w'];
+/*-- IMAGES-WMF --*/
+ if ($info['type']=='wmf') {
+ $objattr['wmf_x'] = $info['x'];
+ $objattr['wmf_y'] = $info['y'];
+ }
+ else
+/*-- END IMAGES-WMF --*/
+ if ($info['type']=='svg') {
+ $objattr['wmf_x'] = $info['x'];
+ $objattr['wmf_y'] = $info['y'];
+ }
+ $objattr['height'] = $h + $extraheight;
+ $objattr['width'] = $w + $extrawidth;
+
+ $objattr['image_height'] = $h;
+ $objattr['image_width'] = $w;
+ $objattr['ID'] = $info['i'];
+ $texto = 'X';
+ if ($this->useActiveForms) {
+ if (isset($attr['ONCLICK'])) { $objattr['onClick'] = $attr['ONCLICK']; }
+ $objattr['type'] = 'input';
+ $type = 'IMAGE';
+ }
+ break;
+ }
+/*-- END IMAGES-CORE --*/
+
+ case 'BUTTON': // Draw a button
+ case 'SUBMIT':
+ case 'RESET':
+ $type = strtoupper($attr['TYPE']);
+ if ($type=='IMAGE') { $type = 'BUTTON'; } // src path not found
+ if(isset($attr['NOPRINT'])) { $objattr['noprint'] = true; }
+ if (!isset($attr['VALUE'])) {
+ $objattr['value'] = ucfirst(strtolower($type));
+ }
+
+ $texto = " " . $objattr['value'] . " ";
+ $width = $this->GetStringWidth($texto) + ($this->mpdfform->form_element_spacing['button']['outer']['h']*2)+($this->mpdfform->form_element_spacing['button']['inner']['h']*2);
+ $height = $this->FontSize + ($this->mpdfform->form_element_spacing['button']['outer']['v']*2)+($this->mpdfform->form_element_spacing['button']['inner']['v']*2);
+ if ($this->useActiveForms) {
+ if (isset($attr['ONCLICK'])) { $objattr['onClick'] = $attr['ONCLICK']; }
+ }
+ break;
+
+ case 'PASSWORD':
+ case 'TEXT':
+ default:
+ if ($type == '') { $type = 'TEXT'; }
+ if(strtoupper($attr['TYPE'])=='PASSWORD') { $type = 'PASSWORD'; }
+ if (isset($attr['VALUE'])) {
+ if ($type == 'PASSWORD') {
+ $num_stars = mb_strlen($attr['VALUE'],$this->mb_enc );
+ $texto = str_repeat('*',$num_stars);
+ }
+ else { $texto = $attr['VALUE']; }
+ }
+ $xw = ($this->mpdfform->form_element_spacing['input']['outer']['h']*2)+($this->mpdfform->form_element_spacing['input']['inner']['h']*2);
+ $xh = ($this->mpdfform->form_element_spacing['input']['outer']['v']*2)+($this->mpdfform->form_element_spacing['input']['inner']['v']*2);
+ if ($w) { $width = $w + $xw; }
+ else { $width = (20 * $spacesize) + $xw; } // Default width in chars
+ if (isset($attr['SIZE']) and ctype_digit($attr['SIZE']) ) $width = ($attr['SIZE'] * $spacesize) + $xw;
+ $height = $this->FontSize + $xh;
+ if (isset($attr['MAXLENGTH']) and ctype_digit($attr['MAXLENGTH']) ) $objattr['maxlength'] = $attr['MAXLENGTH'];
+ if ($this->useActiveForms) {
+ if (isset($attr['ONCALCULATE'])) { $objattr['onCalculate'] = $attr['ONCALCULATE']; }
+ else if (isset($attr['ONCHANGE'])) { $objattr['onCalculate'] = $attr['ONCHANGE']; }
+ if (isset($attr['ONVALIDATE'])) { $objattr['onValidate'] = $attr['ONVALIDATE']; }
+ if (isset($attr['ONKEYSTROKE'])) { $objattr['onKeystroke'] = $attr['ONKEYSTROKE']; }
+ if (isset($attr['ONFORMAT'])) { $objattr['onFormat'] = $attr['ONFORMAT']; }
+ }
+ break;
+ }
+
+ $objattr['subtype'] = $type;
+ $objattr['text'] = $texto;
+ $objattr['width'] = $width;
+ $objattr['height'] = $height;
+ $e = "\xbb\xa4\xactype=input,objattr=".serialize($objattr)."\xbb\xa4\xac";
+
+ // Clear properties - tidy up
+ $properties = array();
+
+/*-- TABLES --*/
+ // Output it to buffers
+ if ($this->tableLevel) {
+ $this->_saveCellTextBuffer($e, $this->HREF);
+ $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
+
+ }
+ else {
+/*-- END TABLES --*/
+ $this->_saveTextBuffer($e, $this->HREF);
+ } // *TABLES*
+
+ if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
+ unset($this->InlineProperties[$tag]);
+
+ break; // END of INPUT
+/*-- END FORMS --*/
+
+
+ // *********** GRAPH ********************
+ case 'JPGRAPH':
+ if (!$this->useGraphs) { break; }
+ if ($attr['TABLE']) { $gid = strtoupper($attr['TABLE']); }
+ else { $gid = '0'; }
+ if (!is_array($this->graphs[$gid]) || count($this->graphs[$gid])==0 ) { break; }
+ $this->ignorefollowingspaces = false;
+ include_once(_MPDF_PATH.'graph.php');
+ $this->graphs[$gid]['attr'] = $attr;
+
+
+ if (isset($this->graphs[$gid]['attr']['WIDTH']) && $this->graphs[$gid]['attr']['WIDTH']) {
+ $this->graphs[$gid]['attr']['cWIDTH']=$this->ConvertSize($this->graphs[$gid]['attr']['WIDTH'],$this->blk[$this->blklvl]['inner_width']);
+ } // mm
+ if (isset($this->graphs[$gid]['attr']['HEIGHT']) && $this->graphs[$gid]['attr']['HEIGHT']) {
+ $this->graphs[$gid]['attr']['cHEIGHT']=$this->ConvertSize($this->graphs[$gid]['attr']['HEIGHT'],$this->blk[$this->blklvl]['inner_width']);
+ }
+
+ $graph_img = print_graph($this->graphs[$gid],$this->blk[$this->blklvl]['inner_width']);
+ if ($graph_img) {
+ if(isset($attr['ROTATE'])) {
+ if ($attr['ROTATE']==90 || $attr['ROTATE']==-90) {
+ $tmpw = $graph_img['w'];
+ $graph_img['w']= $graph_img['h'];
+ $graph_img['h']= $tmpw;
+ }
+ }
+ $attr['SRC'] = $graph_img['file'];
+ $attr['WIDTH'] = $graph_img['w'];
+ $attr['HEIGHT'] = $graph_img['h'];
+ }
+ else { break; }
+
+ // *********** IMAGE ********************
+/*-- IMAGES-CORE --*/
+ case 'IMG':
+ $this->ignorefollowingspaces = false;
+ if ($this->progressBar) { $this->UpdateProgressBar(1,'','IMG'); } // *PROGRESS-BAR*
+ $objattr = array();
+ $objattr['margin_top'] = 0;
+ $objattr['margin_bottom'] = 0;
+ $objattr['margin_left'] = 0;
+ $objattr['margin_right'] = 0;
+ $objattr['padding_top'] = 0;
+ $objattr['padding_bottom'] = 0;
+ $objattr['padding_left'] = 0;
+ $objattr['padding_right'] = 0;
+ $objattr['width'] = 0;
+ $objattr['height'] = 0;
+ $objattr['border_top']['w'] = 0;
+ $objattr['border_bottom']['w'] = 0;
+ $objattr['border_left']['w'] = 0;
+ $objattr['border_right']['w'] = 0;
+ if(isset($attr['SRC'])) {
+ $srcpath = $attr['SRC'];
+ $orig_srcpath = (isset($attr['ORIG_SRC']) ? $attr['ORIG_SRC'] : '');
+ $properties = $this->cssmgr->MergeCSS('',$tag,$attr);
+ if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
+ return;
+ }
+ if (isset($properties['Z-INDEX']) && $this->current_layer==0) {
+ $v = intval($properties['Z-INDEX']);
+ if ($v > 0) {
+ $objattr['z-index'] = $v;
+ }
+ }
+
+ $objattr['visibility'] = 'visible';
+ if (isset($properties['VISIBILITY'])) {
+ $v = strtolower($properties['VISIBILITY']);
+ if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility=='visible') {
+ $objattr['visibility'] = $v;
+ }
+ }
+
+ // VSPACE and HSPACE converted to margins in MergeCSS
+ if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+
+ if (isset($properties['PADDING-TOP'])) { $objattr['padding_top']=$this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['PADDING-BOTTOM'])) { $objattr['padding_bottom'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['PADDING-LEFT'])) { $objattr['padding_left'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['PADDING-RIGHT'])) { $objattr['padding_right'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+
+ if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
+ if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
+ if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
+ if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
+
+ if (isset($properties['VERTICAL-ALIGN'])) { $objattr['vertical-align'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
+ $w = 0;
+ $h = 0;
+ if(isset($properties['WIDTH'])) $w = $this->ConvertSize($properties['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ else if(isset($attr['WIDTH'])) $w = $this->ConvertSize($attr['WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ if(isset($properties['HEIGHT'])) $h = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ else if(isset($attr['HEIGHT'])) $h = $this->ConvertSize($attr['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ $maxw=$maxh=$minw=$minh=false;
+ if(isset($properties['MAX-WIDTH'])) $maxw = $this->ConvertSize($properties['MAX-WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ else if(isset($attr['MAX-WIDTH'])) $maxw = $this->ConvertSize($attr['MAX-WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ if(isset($properties['MAX-HEIGHT'])) $maxh = $this->ConvertSize($properties['MAX-HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ else if(isset($attr['MAX-HEIGHT'])) $maxh = $this->ConvertSize($attr['MAX-HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ if(isset($properties['MIN-WIDTH'])) $minw = $this->ConvertSize($properties['MIN-WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ else if(isset($attr['MIN-WIDTH'])) $minw = $this->ConvertSize($attr['MIN-WIDTH'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ if(isset($properties['MIN-HEIGHT'])) $minh = $this->ConvertSize($properties['MIN-HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ else if(isset($attr['MIN-HEIGHT'])) $minh = $this->ConvertSize($attr['MIN-HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+
+ if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { $objattr['opacity'] = $properties['OPACITY']; }
+ if ($this->HREF) {
+ if (strpos($this->HREF,".") === false && strpos($this->HREF,"@") !== 0) {
+ $href = $this->HREF;
+ while(array_key_exists($href,$this->internallink)) $href="#".$href;
+ $this->internallink[$href] = $this->AddLink();
+ $objattr['link'] = $this->internallink[$href];
+ }
+ else { $objattr['link'] = $this->HREF; }
+ }
+ $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
+ $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
+
+ // mPDF 5.7.3 TRANSFORMS
+ if (isset($properties['BACKGROUND-COLOR']) && $properties['BACKGROUND-COLOR'] != '') { $objattr['bgcolor'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
+
+/*-- BACKGROUNDS --*/
+ if(isset($properties['GRADIENT-MASK']) && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/',$properties['GRADIENT-MASK'])) {
+ $objattr['GRADIENT-MASK'] = $properties['GRADIENT-MASK'];
+ }
+/*-- END BACKGROUNDS --*/
+
+ // mPDF 6
+ $interpolation = false;
+ if (isset($properties['IMAGE-RENDERING']) && $properties['IMAGE-RENDERING']) {
+ if (strtolower($properties['IMAGE-RENDERING']) == 'crisp-edges') { $interpolation = false; }
+ else if (strtolower($properties['IMAGE-RENDERING']) == 'optimizequality') { $interpolation = true; }
+ else if (strtolower($properties['IMAGE-RENDERING']) == 'smooth') { $interpolation = true; }
+ else if (strtolower($properties['IMAGE-RENDERING']) == 'auto') { $interpolation = $this->interpolateImages; }
+ else { $interpolation = false; }
+ $info['interpolation'] = $interpolation;
+ }
+
+ // Image file
+ $info=$this->_getImage($srcpath, true, true, $orig_srcpath, $interpolation); // mPDF 6
+ if(!$info) {
+ $info = $this->_getImage($this->noImageFile);
+ if ($info) {
+ $srcpath = $this->noImageFile;
+ $w = ($info['w'] * (25.4/$this->dpi));
+ $h = ($info['h'] * (25.4/$this->dpi));
+ }
+ }
+ if(!$info) break;
+
+ if(isset($attr['ROTATE'])) { $image_orientation = $attr['ROTATE']; }
+ else if(isset($properties['IMAGE-ORIENTATION'])) { $image_orientation = $properties['IMAGE-ORIENTATION']; }
+ else { $image_orientation = 0; }
+ if($image_orientation) {
+ if ($image_orientation==90 || $image_orientation==-90 || $image_orientation==270) {
+ $tmpw = $info['w'];
+ $info['w'] = $info['h'];
+ $info['h'] = $tmpw;
+ }
+ $objattr['ROTATE'] = $image_orientation;
+ }
+
+ $objattr['file'] = $srcpath;
+ //Default width and height calculation if needed
+ if($w==0 and $h==0) {
+/*-- IMAGES-WMF --*/
+ if ($info['type']=='wmf') {
+ // WMF units are twips (1/20pt)
+ // divide by 20 to get points
+ // divide by k to get user units
+ $w = abs($info['w'])/(20*_MPDFK);
+ $h = abs($info['h']) / (20*_MPDFK);
+ }
+ else
+/*-- END IMAGES-WMF --*/
+ if ($info['type']=='svg') {
+ // SVG units are pixels
+ $w = abs($info['w'])/_MPDFK;
+ $h = abs($info['h'])/_MPDFK;
+ }
+ else {
+ //Put image at default image dpi
+ $w=($info['w']/_MPDFK) * (72/$this->img_dpi);
+ $h=($info['h']/_MPDFK) * (72/$this->img_dpi);
+ }
+ if (isset($properties['IMAGE-RESOLUTION'])) {
+ if (preg_match('/from-image/i', $properties['IMAGE-RESOLUTION']) && isset($info['set-dpi']) && $info['set-dpi']>0) {
+ $w *= $this->img_dpi / $info['set-dpi'];
+ $h *= $this->img_dpi / $info['set-dpi'];
+ }
+ else if (preg_match('/(\d+)dpi/i', $properties['IMAGE-RESOLUTION'], $m)) {
+ $dpi = $m[1];
+ if ($dpi > 0) {
+ $w *= $this->img_dpi / $dpi;
+ $h *= $this->img_dpi / $dpi;
+ }
+ }
+ }
+ }
+ // IF WIDTH OR HEIGHT SPECIFIED
+ if($w==0) $w=abs($h*$info['w']/$info['h']);
+ if($h==0) $h=abs($w*$info['h']/$info['w']);
+
+ if ($minw && $w<$minw) { $w = $minw; $h=abs($w*$info['h']/$info['w']); }
+ if ($maxw && $w>$maxw) { $w = $maxw; $h=abs($w*$info['h']/$info['w']); }
+ if ($minh && $h<$minh) { $h = $minh; $w=abs($h*$info['w']/$info['h']); }
+ if ($maxh && $h>$maxh) { $h = $maxh; $w=abs($h*$info['w']/$info['h']); }
+
+ // Resize to maximum dimensions of page
+ $maxWidth = $this->blk[$this->blklvl]['inner_width'];
+ $maxHeight = $this->h - ($this->tMargin + $this->bMargin + 1) ;
+ if ($this->fullImageHeight) { $maxHeight = $this->fullImageHeight; }
+ if (($w + $extrawidth) > ($maxWidth + 0.0001) ) { // mPDF 5.7.4 0.0001 to allow for rounding errors when w==maxWidth
+ $w = $maxWidth - $extrawidth;
+ $h=abs($w*$info['h']/$info['w']);
+ }
+
+ if ($h + $extraheight > $maxHeight ) {
+ $h = $maxHeight - $extraheight;
+ $w=abs($h*$info['w']/$info['h']);
+ }
+ $objattr['type'] = 'image';
+ $objattr['itype'] = $info['type'];
+
+ $objattr['orig_h'] = $info['h'];
+ $objattr['orig_w'] = $info['w'];
+/*-- IMAGES-WMF --*/
+ if ($info['type']=='wmf') {
+ $objattr['wmf_x'] = $info['x'];
+ $objattr['wmf_y'] = $info['y'];
+ }
+ else
+/*-- END IMAGES-WMF --*/
+ if ($info['type']=='svg') {
+ $objattr['wmf_x'] = $info['x'];
+ $objattr['wmf_y'] = $info['y'];
+ }
+ $objattr['height'] = $h + $extraheight;
+ $objattr['width'] = $w + $extrawidth;
+ $objattr['image_height'] = $h;
+ $objattr['image_width'] = $w;
+/*-- CSS-IMAGE-FLOAT --*/
+ if (!$this->ColActive && !$this->tableLevel && !$this->listlvl && !$this->kwt) {
+ if (isset($properties['FLOAT']) && (strtoupper($properties['FLOAT']) == 'RIGHT' || strtoupper($properties['FLOAT']) == 'LEFT')) {
+ $objattr['float'] = substr(strtoupper($properties['FLOAT']),0,1);
+ }
+ }
+/*-- END CSS-IMAGE-FLOAT --*/
+ // mPDF 5.7.3 TRANSFORMS
+ if (isset($properties['TRANSFORM']) && !$this->ColActive && !$this->kwt) {
+ $objattr['transform'] = $properties['TRANSFORM'];
+ }
+
+ $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
+
+ // Clear properties - tidy up
+ $properties = array();
+
+/*-- TABLES --*/
+ // Output it to buffers
+ if ($this->tableLevel) {
+ $this->_saveCellTextBuffer($e, $this->HREF);
+ $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
+ }
+ else {
+/*-- END TABLES --*/
+ $this->_saveTextBuffer($e, $this->HREF);
+ } // *TABLES*
+/*-- ANNOTATIONS --*/
+ if ($this->title2annots && isset($attr['TITLE'])) {
+ $objattr = array();
+ $objattr['margin_top'] = 0;
+ $objattr['margin_bottom'] = 0;
+ $objattr['margin_left'] = 0;
+ $objattr['margin_right'] = 0;
+ $objattr['width'] = 0;
+ $objattr['height'] = 0;
+ $objattr['border_top']['w'] = 0;
+ $objattr['border_bottom']['w'] = 0;
+ $objattr['border_left']['w'] = 0;
+ $objattr['border_right']['w'] = 0;
+ $objattr['CONTENT'] = $attr['TITLE'];
+ $objattr['type'] = 'annot';
+ $objattr['POS-X'] = 0;
+ $objattr['POS-Y'] = 0;
+ $objattr['ICON'] = 'Comment';
+ $objattr['AUTHOR'] = '';
+ $objattr['SUBJECT'] = '';
+ $objattr['OPACITY'] = $this->annotOpacity;
+ $objattr['COLOR'] = $this->ConvertColor('yellow');
+ $e = "\xbb\xa4\xactype=annot,objattr=".serialize($objattr)."\xbb\xa4\xac";
+ if($this->tableLevel) { // *TABLES*
+ $this->cell[$this->row][$this->col]['textbuffer'][] = array($e); // *TABLES*
+ } // *TABLES*
+ else { // *TABLES*
+ $this->textbuffer[] = array($e);
+ } // *TABLES*
+ }
+/*-- END ANNOTATIONS --*/
+ }
+ break;
+/*-- END IMAGES-CORE --*/
+
+
+ // *********** CIRCULAR TEXT = TEXTCIRCLE ********************
+ case 'TEXTCIRCLE':
+ $objattr = array();
+ $objattr['margin_top'] = 0;
+ $objattr['margin_bottom'] = 0;
+ $objattr['margin_left'] = 0;
+ $objattr['margin_right'] = 0;
+ $objattr['padding_top'] = 0;
+ $objattr['padding_bottom'] = 0;
+ $objattr['padding_left'] = 0;
+ $objattr['padding_right'] = 0;
+ $objattr['width'] = 0;
+ $objattr['height'] = 0;
+ $objattr['border_top']['w'] = 0;
+ $objattr['border_bottom']['w'] = 0;
+ $objattr['border_left']['w'] = 0;
+ $objattr['border_right']['w'] = 0;
+ $objattr['top-text'] = '';
+ $objattr['bottom-text'] = '';
+ $objattr['r'] = 20; // radius (default value here for safety)
+ $objattr['space-width'] = 120;
+ $objattr['char-width'] = 100;
+
+ $this->InlineProperties[$tag] = $this->saveInlineProperties();
+ $properties = $this->cssmgr->MergeCSS('INLINE',$tag,$attr);
+
+ if(isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY'])=='none') {
+ return;
+ }
+ if (isset($attr['R'])) { $objattr['r']=$this->ConvertSize($attr['R'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if(isset($attr['TOP-TEXT'])) {
+ $objattr['top-text'] = strcode2utf($attr['TOP-TEXT']);
+ $objattr['top-text'] = $this->lesser_entity_decode($objattr['top-text']);
+ if ($this->onlyCoreFonts)
+ $objattr['top-text'] = mb_convert_encoding($objattr['top-text'], $this->mb_enc,'UTF-8');
+ }
+ if(isset($attr['BOTTOM-TEXT'])) {
+ $objattr['bottom-text'] = strcode2utf($attr['BOTTOM-TEXT']);
+ $objattr['bottom-text'] = $this->lesser_entity_decode($objattr['bottom-text']);
+ if ($this->onlyCoreFonts)
+ $objattr['bottom-text'] = mb_convert_encoding($objattr['bottom-text'], $this->mb_enc,'UTF-8');
+ }
+ if(isset($attr['SPACE-WIDTH']) && $attr['SPACE-WIDTH']) { $objattr['space-width'] = $attr['SPACE-WIDTH']; }
+ if(isset($attr['CHAR-WIDTH']) && $attr['CHAR-WIDTH']) { $objattr['char-width'] = $attr['CHAR-WIDTH']; }
+
+ // VISIBILITY
+ $objattr['visibility'] = 'visible';
+ if (isset($properties['VISIBILITY'])) {
+ $v = strtolower($properties['VISIBILITY']);
+ if (($v == 'hidden' || $v == 'printonly' || $v == 'screenonly') && $this->visibility=='visible') {
+ $objattr['visibility'] = $v;
+ }
+ }
+ if (isset($properties['FONT-SIZE'])) {
+ if (strtolower($properties['FONT-SIZE'])=='auto') {
+ if ($objattr['top-text'] && $objattr['bottom-text']) {
+ $objattr['fontsize'] = -2;
+ }
+ else {
+ $objattr['fontsize'] = -1;
+ }
+ }
+ else {
+ $mmsize = $this->ConvertSize($properties['FONT-SIZE'],($this->default_font_size/_MPDFK));
+ $this->SetFontSize($mmsize*_MPDFK,false);
+ $objattr['fontsize'] = $this->FontSizePt;
+ }
+ }
+ if(isset($attr['DIVIDER'])) {
+ $objattr['divider'] = strcode2utf($attr['DIVIDER']);
+ $objattr['divider'] = $this->lesser_entity_decode($objattr['divider']);
+ if ($this->onlyCoreFonts)
+ $objattr['divider'] = mb_convert_encoding($objattr['divider'], $this->mb_enc,'UTF-8');
+
+ }
+
+ if (isset($properties['COLOR'])) { $objattr['color'] = $this->ConvertColor($properties['COLOR']); }
+
+ $objattr['fontstyle'] = '';
+ if (isset($properties['FONT-WEIGHT'])) {
+ if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $objattr['fontstyle'] .= 'B'; }
+ }
+ if (isset($properties['FONT-STYLE'])) {
+ if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $objattr['fontstyle'] .= 'I'; }
+ }
+
+ if (isset($properties['FONT-FAMILY'])) {
+ $this->SetFont($properties['FONT-FAMILY'],$this->FontStyle,0,false);
+ }
+ $objattr['fontfamily'] = $this->FontFamily;
+
+ // VSPACE and HSPACE converted to margins in MergeCSS
+ if (isset($properties['MARGIN-TOP'])) { $objattr['margin_top']=$this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['MARGIN-BOTTOM'])) { $objattr['margin_bottom'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['MARGIN-LEFT'])) { $objattr['margin_left'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['MARGIN-RIGHT'])) { $objattr['margin_right'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+
+ if (isset($properties['PADDING-TOP'])) { $objattr['padding_top']=$this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['PADDING-BOTTOM'])) { $objattr['padding_bottom'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['PADDING-LEFT'])) { $objattr['padding_left'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ if (isset($properties['PADDING-RIGHT'])) { $objattr['padding_right'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+
+ if (isset($properties['BORDER-TOP'])) { $objattr['border_top'] = $this->border_details($properties['BORDER-TOP']); }
+ if (isset($properties['BORDER-BOTTOM'])) { $objattr['border_bottom'] = $this->border_details($properties['BORDER-BOTTOM']); }
+ if (isset($properties['BORDER-LEFT'])) { $objattr['border_left'] = $this->border_details($properties['BORDER-LEFT']); }
+ if (isset($properties['BORDER-RIGHT'])) { $objattr['border_right'] = $this->border_details($properties['BORDER-RIGHT']); }
+
+ if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { $objattr['opacity'] = $properties['OPACITY']; }
+ if (isset($properties['BACKGROUND-COLOR']) && $properties['BACKGROUND-COLOR'] != '') { $objattr['bgcolor'] = $this->ConvertColor($properties['BACKGROUND-COLOR']); }
+ else { $objattr['bgcolor'] = false; }
+ if ($this->HREF) {
+ if (strpos($this->HREF,".") === false && strpos($this->HREF,"@") !== 0) {
+ $href = $this->HREF;
+ while(array_key_exists($href,$this->internallink)) $href="#".$href;
+ $this->internallink[$href] = $this->AddLink();
+ $objattr['link'] = $this->internallink[$href];
+ }
+ else { $objattr['link'] = $this->HREF; }
+ }
+ $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w'];
+ $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w'];
+
+
+ $w = $objattr['r']*2;
+ $h = $w;
+ $objattr['height'] = $h + $extraheight;
+ $objattr['width'] = $w + $extrawidth;
+ $objattr['type'] = 'textcircle';
+
+ $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
+
+ // Clear properties - tidy up
+ $properties = array();
+
+/*-- TABLES --*/
+ // Output it to buffers
+ if ($this->tableLevel) {
+ $this->_saveCellTextBuffer($e, $this->HREF);
+ $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ;
+ }
+ else {
+/*-- END TABLES --*/
+ $this->_saveTextBuffer($e, $this->HREF);
+ } // *TABLES*
+
+ if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
+ unset($this->InlineProperties[$tag]);
+
+ break;
+
+
+/*-- TABLES --*/
+
+ case 'TABLE': // TABLE-BEGIN
+ $this->tdbegin = false;
+ $this->lastoptionaltag = '';
+ // Disable vertical justification in columns
+ if ($this->ColActive) { $this->colvAlign = ''; } // *COLUMNS*
+ if ($this->lastblocklevelchange == 1) { $blockstate = 1; } // Top margins/padding only
+ else if ($this->lastblocklevelchange < 1) { $blockstate = 0; } // NO margins/padding
+ // called from block after new div e.g. ... ... Outputs block top margin/border and padding
+ if (count($this->textbuffer) == 0 && $this->lastblocklevelchange == 1 && !$this->tableLevel && !$this->kwt) {
+ $this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,1,true, $this->blk[$this->blklvl]['direction']);
+ $this->finishFlowingBlock(true); // true = END of flowing block
+ }
+ else if (!$this->tableLevel && count($this->textbuffer)) { $this->printbuffer($this->textbuffer,$blockstate); }
+
+ $this->textbuffer=array();
+ $this->lastblocklevelchange = -1;
+
+
+
+ if ($this->tableLevel) { // i.e. now a nested table coming...
+ // Save current level table
+ $this->cell['PARENTCELL'] = $this->saveInlineProperties();
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['baseProperties']= $this->base_table_properties;
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] = $this->cell;
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currrow'] = $this->row;
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currcol'] = $this->col;
+ }
+ $this->tableLevel++;
+ $this->cssmgr->tbCSSlvl++;
+
+ if ($this->tableLevel>1) { // inherit table properties from cell in which nested
+ //$this->base_table_properties['FONT-KERNING'] = ($this->textvar & FC_KERNING); // mPDF 6
+ $this->base_table_properties['LETTER-SPACING'] = $this->lSpacingCSS ;
+ $this->base_table_properties['WORD-SPACING'] = $this->wSpacingCSS ;
+ // mPDF 6
+ $direction = $this->cell[$this->row][$this->col]['direction'];
+ $txta = $this->cell[$this->row][$this->col]['a'];
+ $cellLineHeight = $this->cell[$this->row][$this->col]['cellLineHeight'];
+ $cellLineStackingStrategy = $this->cell[$this->row][$this->col]['cellLineStackingStrategy'];
+ $cellLineStackingShift = $this->cell[$this->row][$this->col]['cellLineStackingShift'];
+ }
+
+ if (isset($this->tbctr[$this->tableLevel])) { $this->tbctr[$this->tableLevel]++; }
+ else { $this->tbctr[$this->tableLevel] = 1; }
+
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['level'] = $this->tableLevel;
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['levelid'] = $this->tbctr[$this->tableLevel];
+
+ if ($this->tableLevel > $this->innermostTableLevel) { $this->innermostTableLevel = $this->tableLevel; }
+ if ($this->tableLevel > 1) {
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nestedpos'] = array($this->row,$this->col,$this->tbctr[($this->tableLevel-1)]);
+ }
+ //++++++++++++++++++++++++++++
+
+ $this->cell = array();
+ $this->col=-1; //int
+ $this->row=-1; //int
+ $table = &$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]];
+
+ // New table - any level
+ $table['direction'] = $this->directionality;
+ $table['bgcolor'] = false;
+ $table['va'] = false;
+ $table['txta'] = false;
+ $table['topntail'] = false;
+ $table['thead-underline'] = false;
+ $table['border'] = false;
+ $table['border_details']['R']['w'] = 0;
+ $table['border_details']['L']['w'] = 0;
+ $table['border_details']['T']['w'] = 0;
+ $table['border_details']['B']['w'] = 0;
+ $table['border_details']['R']['style'] = '';
+ $table['border_details']['L']['style'] = '';
+ $table['border_details']['T']['style'] = '';
+ $table['border_details']['B']['style'] = '';
+ $table['max_cell_border_width']['R'] = 0;
+ $table['max_cell_border_width']['L'] = 0;
+ $table['max_cell_border_width']['T'] = 0;
+ $table['max_cell_border_width']['B'] = 0;
+ $table['padding']['L'] = false;
+ $table['padding']['R'] = false;
+ $table['padding']['T'] = false;
+ $table['padding']['B'] = false;
+ $table['margin']['L'] = false;
+ $table['margin']['R'] = false;
+ $table['margin']['T'] = false;
+ $table['margin']['B'] = false;
+ $table['a'] = false;
+ $table['border_spacing_H'] = false;
+ $table['border_spacing_V'] = false;
+ $table['decimal_align'] = false;
+ $this->Reset();
+ $this->InlineProperties = array();
+ $this->InlineBDF=array(); // mPDF 6
+ $this->InlineBDFctr= 0; // mPDF 6
+ $table['nc'] = $table['nr'] = 0;
+ $this->tablethead = 0;
+ $this->tabletfoot = 0;
+ $this->tabletheadjustfinished = false;
+
+ // mPDF 6
+ if ($this->tableLevel>1) { // inherit table properties from cell in which nested
+ $table['direction'] = $direction;
+ $table['txta'] = $txta;
+ $table['cellLineHeight'] = $cellLineHeight;
+ $table['cellLineStackingStrategy'] = $cellLineStackingStrategy;
+ $table['cellLineStackingShift'] = $cellLineStackingShift;
+ }
+
+
+ if ($this->blockjustfinished && !count($this->textbuffer) && $this->y != $this->tMargin && $this->collapseBlockMargins && $this->tableLevel==1) { $lastbottommargin = $this->lastblockbottommargin; }
+ else { $lastbottommargin = 0; }
+ $this->lastblockbottommargin = 0;
+ $this->blockjustfinished=false;
+
+ if ($this->tableLevel==1) {
+ $table['headernrows'] = 0;
+ $table['footernrows'] = 0;
+ $this->base_table_properties = array();
+ }
+
+ // ADDED CSS FUNCIONS FOR TABLE
+ if ($this->cssmgr->tbCSSlvl==1) {
+ $properties = $this->cssmgr->MergeCSS('TOPTABLE',$tag,$attr);
+ }
+ else {
+ $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
+ }
+
+ $w = '';
+ if (isset($properties['WIDTH'])) { $w = $properties['WIDTH']; }
+ else if (isset($attr['WIDTH']) && $attr['WIDTH']) { $w = $attr['WIDTH']; }
+
+ if (isset($attr['ALIGN']) && isset($align[strtolower($attr['ALIGN'])])) { $table['a'] = $align[strtolower($attr['ALIGN'])]; }
+ if (!$table['a']) {
+ if ($table['direction'] == 'rtl' ) { $table['a'] = 'R'; }
+ else { $table['a'] = 'L'; }
+ }
+
+ if(isset($properties['DIRECTION']) && $properties['DIRECTION']) { $table['direction'] = strtolower($properties['DIRECTION']); }
+ else if(isset($attr['DIR']) && $attr['DIR']) { $table['direction'] = strtolower($attr['DIR']); }
+ else if ($this->tableLevel == 1) { $table['direction'] = $this->blk[$this->blklvl]['direction']; }
+
+ if (isset($properties['BACKGROUND-COLOR'])) { $table['bgcolor'][-1] = $properties['BACKGROUND-COLOR']; }
+ else if (isset($properties['BACKGROUND'])) { $table['bgcolor'][-1] = $properties['BACKGROUND']; }
+ else if (isset($attr['BGCOLOR'])) { $table['bgcolor'][-1] = $attr['BGCOLOR']; }
+
+ if (isset($properties['VERTICAL-ALIGN']) && isset($align[strtolower($properties['VERTICAL-ALIGN'])])) { $table['va'] = $align[strtolower($properties['VERTICAL-ALIGN'])]; }
+ if (isset($properties['TEXT-ALIGN']) && isset($align[strtolower($properties['TEXT-ALIGN'])])) { $table['txta'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
+
+ if (isset($properties['AUTOSIZE']) && $properties['AUTOSIZE'] && $this->tableLevel ==1) {
+ $this->shrink_this_table_to_fit = $properties['AUTOSIZE'];
+ if ($this->shrink_this_table_to_fit < 1) { $this->shrink_this_table_to_fit = 0; }
+ }
+ if (isset($properties['ROTATE']) && $properties['ROTATE'] && $this->tableLevel ==1) {
+ $this->table_rotate = $properties['ROTATE'];
+ }
+ if (isset($properties['TOPNTAIL'])) { $table['topntail'] = $properties['TOPNTAIL']; }
+ if (isset($properties['THEAD-UNDERLINE'])) { $table['thead-underline'] = $properties['THEAD-UNDERLINE']; }
+
+ if (isset($properties['BORDER'])) {
+ $bord = $this->border_details($properties['BORDER']);
+ if ($bord['s']) {
+ $table['border'] = _BORDER_ALL;
+ $table['border_details']['R'] = $bord;
+ $table['border_details']['L'] = $bord;
+ $table['border_details']['T'] = $bord;
+ $table['border_details']['B'] = $bord;
+ }
+ }
+ if (isset($properties['BORDER-RIGHT'])) {
+ if ($table['direction'] == 'rtl') { // *OTL*
+ $table['border_details']['R'] = $this->border_details($properties['BORDER-LEFT']); // *OTL*
+ } // *OTL*
+ else { // *OTL*
+ $table['border_details']['R'] = $this->border_details($properties['BORDER-RIGHT']);
+ } // *OTL*
+ $this->setBorder($table['border'], _BORDER_RIGHT, $table['border_details']['R']['s']);
+ }
+ if (isset($properties['BORDER-LEFT'])) {
+ if ($table['direction'] == 'rtl') { // *OTL*
+ $table['border_details']['L'] = $this->border_details($properties['BORDER-RIGHT']); // *OTL*
+ } // *OTL*
+ else { // *OTL*
+ $table['border_details']['L'] = $this->border_details($properties['BORDER-LEFT']);
+ } // *OTL*
+ $this->setBorder($table['border'], _BORDER_LEFT, $table['border_details']['L']['s']);
+ }
+ if (isset($properties['BORDER-BOTTOM'])) {
+ $table['border_details']['B'] = $this->border_details($properties['BORDER-BOTTOM']);
+ $this->setBorder($table['border'], _BORDER_BOTTOM, $table['border_details']['B']['s']);
+ }
+ if (isset($properties['BORDER-TOP'])) {
+ $table['border_details']['T'] = $this->border_details($properties['BORDER-TOP']);
+ $this->setBorder($table['border'], _BORDER_TOP, $table['border_details']['T']['s']);
+ }
+ if ($table['border']){
+ $this->table_border_css_set = 1;
+ }
+ else {
+ $this->table_border_css_set = 0;
+ }
+
+ // mPDF 6
+ if (isset($properties['LANG']) && $properties['LANG']) {
+ if ($this->autoLangToFont && !$this->usingCoreFont) {
+ if ($properties['LANG'] != $this->default_lang && $properties['LANG'] != 'UTF-8') {
+ list ($coreSuitable,$mpdf_pdf_unifont) = GetLangOpts($properties['LANG'], $this->useAdobeCJK, $this->fontdata);
+ if ($mpdf_pdf_unifont) { $properties['FONT-FAMILY'] = $mpdf_pdf_unifont; }
+ }
+ }
+ $this->currentLang = $properties['LANG'];
+ }
+
+
+ if (isset($properties['FONT-FAMILY'])) {
+ $this->default_font = $properties['FONT-FAMILY'];
+ $this->SetFont($this->default_font,'',0,false);
+ }
+ $this->base_table_properties['FONT-FAMILY'] = $this->FontFamily;
+
+ if (isset($properties['FONT-SIZE'])) {
+ if ($this->tableLevel>1) { $mmsize = $this->ConvertSize($properties['FONT-SIZE'], $this->base_table_properties['FONT-SIZE']); }
+ else { $mmsize = $this->ConvertSize($properties['FONT-SIZE'],$this->default_font_size/_MPDFK); }
+ if ($mmsize) {
+ $this->default_font_size = $mmsize*(_MPDFK);
+ $this->SetFontSize($this->default_font_size,false);
+ }
+ }
+ $this->base_table_properties['FONT-SIZE'] = $this->FontSize.'mm';
+
+ if (isset($properties['FONT-WEIGHT'])) {
+ if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this->base_table_properties['FONT-WEIGHT'] = 'BOLD'; }
+ }
+ if (isset($properties['FONT-STYLE'])) {
+ if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this->base_table_properties['FONT-STYLE'] = 'ITALIC'; }
+ }
+ if (isset($properties['COLOR'])) {
+ $this->base_table_properties['COLOR'] = $properties['COLOR'];
+ }
+ if (isset($properties['FONT-KERNING'])) {
+ $this->base_table_properties['FONT-KERNING'] = $properties['FONT-KERNING'];
+ }
+ if (isset($properties['LETTER-SPACING'])) {
+ $this->base_table_properties['LETTER-SPACING'] = $properties['LETTER-SPACING'];
+ }
+ if (isset($properties['WORD-SPACING'])) {
+ $this->base_table_properties['WORD-SPACING'] = $properties['WORD-SPACING'];
+ }
+ // mPDF 6
+ if (isset($properties['HYPHENS'])) {
+ $this->base_table_properties['HYPHENS'] = $properties['HYPHENS'];
+ }
+ if(isset($properties['LINE-HEIGHT']) && $properties['LINE-HEIGHT']) { $table['cellLineHeight'] = $this->fixLineheight($properties['LINE-HEIGHT']); }
+ else if ($this->tableLevel == 1) { $table['cellLineHeight'] = $this->blk[$this->blklvl]['line_height']; }
+
+ if(isset($properties['LINE-STACKING-STRATEGY']) && $properties['LINE-STACKING-STRATEGY']) { $table['cellLineStackingStrategy'] = strtolower($properties['LINE-STACKING-STRATEGY']); }
+ else if ($this->tableLevel == 1 && isset($this->blk[$this->blklvl]['line_stacking_strategy'])) { $table['cellLineStackingStrategy'] = $this->blk[$this->blklvl]['line_stacking_strategy']; }
+ else { $table['cellLineStackingStrategy'] = 'inline-line-height'; }
+
+ if(isset($properties['LINE-STACKING-SHIFT']) && $properties['LINE-STACKING-SHIFT']) { $table['cellLineStackingShift'] = strtolower($properties['LINE-STACKING-SHIFT']); }
+ else if ($this->tableLevel == 1 && isset($this->blk[$this->blklvl]['line_stacking_shift'])) { $table['cellLineStackingShift'] = $this->blk[$this->blklvl]['line_stacking_shift']; }
+ else { $table['cellLineStackingShift'] = 'consider-shifts'; }
+
+ if (isset($properties['PADDING-LEFT'])) {
+ $table['padding']['L'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ }
+ if (isset($properties['PADDING-RIGHT'])) {
+ $table['padding']['R'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ }
+ if (isset($properties['PADDING-TOP'])) {
+ $table['padding']['T'] = $this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ }
+ if (isset($properties['PADDING-BOTTOM'])) {
+ $table['padding']['B'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ }
+
+ if (isset($properties['MARGIN-TOP'])) {
+ if ($lastbottommargin) {
+ $tmp = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ if ($tmp > $lastbottommargin) { $properties['MARGIN-TOP'] -= $lastbottommargin; }
+ else { $properties['MARGIN-TOP'] = 0; }
+ }
+ $table['margin']['T'] = $this->ConvertSize($properties['MARGIN-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ }
+
+ if (isset($properties['MARGIN-BOTTOM'])) {
+ $table['margin']['B'] = $this->ConvertSize($properties['MARGIN-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ }
+ if (isset($properties['MARGIN-LEFT'])) {
+ $table['margin']['L'] = $this->ConvertSize($properties['MARGIN-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ }
+
+ if (isset($properties['MARGIN-RIGHT'])) {
+ $table['margin']['R'] = $this->ConvertSize($properties['MARGIN-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ }
+ if (isset($properties['MARGIN-LEFT']) && isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-LEFT'])=='auto' && strtolower($properties['MARGIN-RIGHT'])=='auto') {
+ $table['a'] = 'C';
+ }
+ else if (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT'])=='auto') {
+ $table['a'] = 'R';
+ }
+ else if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT'])=='auto') {
+ $table['a'] = 'L';
+ }
+
+ if (isset($properties['BORDER-COLLAPSE']) && strtoupper($properties['BORDER-COLLAPSE'])=='SEPARATE') {
+ $table['borders_separate'] = true;
+ }
+ else {
+ $table['borders_separate'] = false;
+ }
+
+ // mPDF 5.7.3
+
+ if (isset($properties['BORDER-SPACING-H'])) {
+ $table['border_spacing_H'] = $this->ConvertSize($properties['BORDER-SPACING-H'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ }
+ if (isset($properties['BORDER-SPACING-V'])) {
+ $table['border_spacing_V'] = $this->ConvertSize($properties['BORDER-SPACING-V'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ }
+ // mPDF 5.7.3
+ if (!$table['borders_separate']) { $table['border_spacing_H'] = $table['border_spacing_V'] = 0; }
+
+ if (isset($properties['EMPTY-CELLS'])) {
+ $table['empty_cells'] = strtolower($properties['EMPTY-CELLS']); // 'hide' or 'show'
+ }
+ else { $table['empty_cells'] = ''; }
+
+ if (isset($properties['PAGE-BREAK-INSIDE']) && strtoupper($properties['PAGE-BREAK-INSIDE'])=='AVOID' && $this->tableLevel==1 && !$this->writingHTMLfooter) {
+ $this->table_keep_together = true;
+ }
+ else if ($this->tableLevel==1) {
+ $this->table_keep_together = false;
+ }
+ if (isset($properties['PAGE-BREAK-AFTER']) && $this->tableLevel==1) {
+ $table['page_break_after'] = strtoupper($properties['PAGE-BREAK-AFTER']);
+ }
+
+/*-- BACKGROUNDS --*/
+ if (isset($properties['BACKGROUND-GRADIENT']) && !$this->kwt && !$this->ColActive) { $table['gradient'] = $properties['BACKGROUND-GRADIENT']; }
+
+ if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->kwt && !$this->ColActive) {
+ $ret = $this->SetBackground($properties, $currblk['inner_width']);
+ if ($ret) { $table['background-image'] = $ret; }
+ }
+/*-- END BACKGROUNDS --*/
+
+ if (isset($properties['OVERFLOW'])) {
+ $table['overflow'] = strtolower($properties['OVERFLOW']); // 'hidden' 'wrap' or 'visible' or 'auto'
+ if (($this->ColActive || $this->tableLevel>1) && $table['overflow']=='visible') { unset($table['overflow']); }
+ }
+
+ $properties = array();
+
+
+ if (isset($attr['CELLPADDING'])) {
+ $table['cell_padding'] = $attr['CELLPADDING'];
+ }
+ else {
+ $table['cell_padding'] = false;
+ }
+
+ if (isset($attr['BORDER']) && $attr['BORDER']=='1') {
+ $this->table_border_attr_set = 1;
+ $bord = $this->border_details('#000000 1px solid');
+ if ($bord['s']) {
+ $table['border'] = _BORDER_ALL;
+ $table['border_details']['R'] = $bord;
+ $table['border_details']['L'] = $bord;
+ $table['border_details']['T'] = $bord;
+ $table['border_details']['B'] = $bord;
+ }
+ }
+ else {
+ $this->table_border_attr_set = 0;
+ }
+
+ if ($w) {
+ $maxwidth = $this->blk[$this->blklvl]['inner_width'];
+ if ($table['borders_separate']) {
+ $tblblw = $table['margin']['L'] + $table['margin']['R'] + $table['border_details']['L']['w']/2 + $table['border_details']['R']['w']/2;
+ }
+ else {
+ $tblblw = $table['margin']['L'] + $table['margin']['R'] + $table['max_cell_border_width']['L']/2 + $table['max_cell_border_width']['R']/2;
+ }
+ if (strpos($w,'%') && $this->tableLevel == 1 && !$this->ignore_table_percents ) {
+ // % needs to be of inner box without table margins etc.
+ $maxwidth -= $tblblw ;
+ $wmm = $this->ConvertSize($w,$maxwidth,$this->FontSize,false);
+ $table['w'] = $wmm + $tblblw ;
+ }
+ if (strpos($w,'%') && $this->tableLevel > 1 && !$this->ignore_table_percents && $this->keep_table_proportions) {
+ $table['wpercent'] = $w + 0; // makes 80% -> 80
+ }
+ if (!strpos($w,'%') && !$this->ignore_table_widths ) {
+ $wmm = $this->ConvertSize($w,$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ $table['w'] = $wmm + $tblblw ;
+ }
+ if (!$this->keep_table_proportions) {
+ if (isset($table['w']) && $table['w'] > $this->blk[$this->blklvl]['inner_width']) { $table['w'] = $this->blk[$this->blklvl]['inner_width']; }
+ }
+ }
+
+ if (isset($attr['AUTOSIZE']) && $this->tableLevel==1) {
+ $this->shrink_this_table_to_fit = $attr['AUTOSIZE'];
+ if ($this->shrink_this_table_to_fit < 1) { $this->shrink_this_table_to_fit = 1; }
+ }
+ if (isset($attr['ROTATE']) && $this->tableLevel==1) {
+ $this->table_rotate = $attr['ROTATE'];
+ }
+
+ //++++++++++++++++++++++++++++
+ if ($this->table_rotate) {
+ $this->tbrot_Links = array();
+ $this->tbrot_Annots = array();
+ $this->tbrotForms = array();
+ $this->tbrot_BMoutlines = array();
+ $this->tbrot_toc = array();
+ }
+
+ if ($this->kwt) {
+ if ($this->table_rotate) { $this->table_keep_together = true; }
+ $this->kwt = false;
+ $this->kwt_saved = true;
+ }
+
+ if ($this->tableLevel==1 && $this->useGraphs) {
+ if (isset($attr['ID']) && $attr['ID']) { $this->currentGraphId = strtoupper($attr['ID']); }
+ else { $this->currentGraphId = '0'; }
+ $this->graphs[$this->currentGraphId] = array();
+ }
+ //++++++++++++++++++++++++++++
+ $this->plainCell_properties = array();
+ unset($table);
+ break;
+
+ case 'THEAD':
+ $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
+ $this->cssmgr->tbCSSlvl++;
+ $this->tablethead = 1;
+ $this->tabletfoot = 0;
+ $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
+ if (isset($properties['FONT-WEIGHT'])) {
+ if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this->thead_font_weight = 'B'; }
+ else { $this->thead_font_weight = ''; }
+ }
+
+ if (isset($properties['FONT-STYLE'])) {
+ if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this->thead_font_style = 'I'; }
+ else { $this->thead_font_style = ''; }
+ }
+ if (isset($properties['FONT-VARIANT'])) {
+ if (strtoupper($properties['FONT-VARIANT']) == 'SMALL-CAPS') { $this->thead_font_smCaps = 'S'; }
+ else { $this->thead_font_smCaps = ''; }
+ }
+
+ if (isset($properties['VERTICAL-ALIGN'])) {
+ $this->thead_valign_default = $properties['VERTICAL-ALIGN'];
+ }
+ if (isset($properties['TEXT-ALIGN'])) {
+ $this->thead_textalign_default = $properties['TEXT-ALIGN'];
+ }
+ $properties = array();
+ break;
+
+ case 'TFOOT':
+ $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
+ $this->cssmgr->tbCSSlvl++;
+ $this->tabletfoot = 1;
+ $this->tablethead = 0;
+ $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
+ if (isset($properties['FONT-WEIGHT'])) {
+ if (strtoupper($properties['FONT-WEIGHT']) == 'BOLD') { $this->tfoot_font_weight = 'B'; }
+ else { $this->tfoot_font_weight = ''; }
+ }
+
+ if (isset($properties['FONT-STYLE'])) {
+ if (strtoupper($properties['FONT-STYLE']) == 'ITALIC') { $this->tfoot_font_style = 'I'; }
+ else { $this->tfoot_font_style = ''; }
+ }
+ if (isset($properties['FONT-VARIANT'])) {
+ if (strtoupper($properties['FONT-VARIANT']) == 'SMALL-CAPS') { $this->tfoot_font_smCaps = 'S'; }
+ else { $this->tfoot_font_smCaps = ''; }
+ }
+
+ if (isset($properties['VERTICAL-ALIGN'])) {
+ $this->tfoot_valign_default = $properties['VERTICAL-ALIGN'];
+ }
+ if (isset($properties['TEXT-ALIGN'])) {
+ $this->tfoot_textalign_default = $properties['TEXT-ALIGN'];
+ }
+ $properties = array();
+ break;
+
+
+ case 'TBODY':
+ $this->tablethead = 0;
+ $this->tabletfoot = 0;
+ $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
+ $this->cssmgr->tbCSSlvl++;
+ $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
+ break;
+
+
+ case 'TR':
+ $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
+ $this->cssmgr->tbCSSlvl++;
+ $this->row++;
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr']++;
+ $this->col = -1;
+ $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
+
+ if (!$this->simpleTables && (!isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['borders_separate']) || !$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['borders_separate'])) {
+ if (isset($properties['BORDER-LEFT']) && $properties['BORDER-LEFT']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-left'][$this->row] = $properties['BORDER-LEFT']; }
+ if (isset($properties['BORDER-RIGHT']) && $properties['BORDER-RIGHT']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-right'][$this->row] = $properties['BORDER-RIGHT']; }
+ if (isset($properties['BORDER-TOP']) && $properties['BORDER-TOP']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-top'][$this->row] = $properties['BORDER-TOP']; }
+ if (isset($properties['BORDER-BOTTOM']) && $properties['BORDER-BOTTOM']) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-bottom'][$this->row] = $properties['BORDER-BOTTOM']; }
+ }
+
+ if (isset($properties['BACKGROUND-COLOR'])) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$this->row] = $properties['BACKGROUND-COLOR']; }
+ else if (isset($attr['BGCOLOR'])) $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$this->row] = $attr['BGCOLOR'];
+
+/*-- BACKGROUNDS --*/
+ if (isset($properties['BACKGROUND-GRADIENT']) && !$this->kwt && !$this->ColActive) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'][$this->row] = $properties['BACKGROUND-GRADIENT']; }
+
+ if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->kwt && !$this->ColActive) {
+ $ret = $this->SetBackground($properties, $currblk['inner_width']);
+ if ($ret) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'][$this->row] = $ret; }
+ }
+/*-- END BACKGROUNDS --*/
+
+
+
+
+ if (isset($properties['TEXT-ROTATE'])) {
+ $this->trow_text_rotate = $properties['TEXT-ROTATE'];
+ }
+ if (isset($attr['TEXT-ROTATE'])) $this->trow_text_rotate = $attr['TEXT-ROTATE'];
+
+ if ($this->tablethead) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_thead'][$this->row] = true; }
+ if ($this->tabletfoot) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'][$this->row] = true; }
+ $properties = array();
+ break;
+
+
+ case 'TH':
+ case 'TD':
+ $this->ignorefollowingspaces = true;
+ $this->lastoptionaltag = $tag; // Save current HTML specified optional endtag
+ $this->cssmgr->tbCSSlvl++;
+ $this->InlineProperties = array();
+ $this->InlineBDF=array(); // mPDF 6
+ $this->InlineBDFctr= 0; // mPDF 6
+ $this->tdbegin = true;
+ $this->col++;
+ while (isset($this->cell[$this->row][$this->col])) { $this->col++; }
+
+ //Update number column
+ if ($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nc'] < $this->col+1) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nc'] = $this->col+1; }
+
+ $table = &$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]];
+
+ $c = array('a' => false,
+ 'R' => false,
+ 'nowrap' => false,
+ 'bgcolor' => false,
+ 'padding' => array('L' => false,
+ 'R' => false,
+ 'T' => false,
+ 'B' => false
+ )
+ );
+
+ if ($this->simpleTables && $this->row==0 && $this->col==0){
+ $table['simple']['border'] = false;
+ $table['simple']['border_details']['R']['w'] = 0;
+ $table['simple']['border_details']['L']['w'] = 0;
+ $table['simple']['border_details']['T']['w'] = 0;
+ $table['simple']['border_details']['B']['w'] = 0;
+ $table['simple']['border_details']['R']['style'] = '';
+ $table['simple']['border_details']['L']['style'] = '';
+ $table['simple']['border_details']['T']['style'] = '';
+ $table['simple']['border_details']['B']['style'] = '';
+ }
+ else if (!$this->simpleTables) {
+ $c['border'] = false;
+ $c['border_details']['R']['w'] = 0;
+ $c['border_details']['L']['w'] = 0;
+ $c['border_details']['T']['w'] = 0;
+ $c['border_details']['B']['w'] = 0;
+ $c['border_details']['mbw']['BL'] = 0;
+ $c['border_details']['mbw']['BR'] = 0;
+ $c['border_details']['mbw']['RT'] = 0;
+ $c['border_details']['mbw']['RB'] = 0;
+ $c['border_details']['mbw']['TL'] = 0;
+ $c['border_details']['mbw']['TR'] = 0;
+ $c['border_details']['mbw']['LT'] = 0;
+ $c['border_details']['mbw']['LB'] = 0;
+ $c['border_details']['R']['style'] = '';
+ $c['border_details']['L']['style'] = '';
+ $c['border_details']['T']['style'] = '';
+ $c['border_details']['B']['style'] = '';
+ $c['border_details']['R']['s'] = 0;
+ $c['border_details']['L']['s'] = 0;
+ $c['border_details']['T']['s'] = 0;
+ $c['border_details']['B']['s'] = 0;
+ $c['border_details']['R']['c'] = $this->ConvertColor(0);
+ $c['border_details']['L']['c'] = $this->ConvertColor(0);
+ $c['border_details']['T']['c'] = $this->ConvertColor(0);
+ $c['border_details']['B']['c'] = $this->ConvertColor(0);
+ $c['border_details']['R']['dom'] = 0;
+ $c['border_details']['L']['dom'] = 0;
+ $c['border_details']['T']['dom'] = 0;
+ $c['border_details']['B']['dom'] = 0;
+ $c['border_details']['cellposdom'] = 0;
+ }
+
+
+ if ($table['va']) { $c['va'] = $table['va']; }
+ if ($table['txta']) { $c['a'] = $table['txta']; }
+ if ($this->table_border_attr_set) {
+ if ($table['border_details']) {
+ if (!$this->simpleTables){
+ $c['border_details']['R'] = $table['border_details']['R'];
+ $c['border_details']['L'] = $table['border_details']['L'];
+ $c['border_details']['T'] = $table['border_details']['T'];
+ $c['border_details']['B'] = $table['border_details']['B'];
+ $c['border'] = $table['border'];
+ $c['border_details']['L']['dom'] = 1;
+ $c['border_details']['R']['dom'] = 1;
+ $c['border_details']['T']['dom'] = 1;
+ $c['border_details']['B']['dom'] = 1;
+ }
+ else if ($this->simpleTables && $this->row==0 && $this->col==0){
+ $table['simple']['border_details']['R'] = $table['border_details']['R'];
+ $table['simple']['border_details']['L'] = $table['border_details']['L'];
+ $table['simple']['border_details']['T'] = $table['border_details']['T'];
+ $table['simple']['border_details']['B'] = $table['border_details']['B'];
+ $table['simple']['border'] = $table['border'];
+ }
+ }
+ }
+ // INHERITED THEAD CSS Properties
+ if ($this->tablethead) {
+ if ($this->thead_valign_default) $c['va'] = $align[strtolower($this->thead_valign_default)];
+ if ($this->thead_textalign_default) $c['a'] = $align[strtolower($this->thead_textalign_default)];
+ if ($this->thead_font_weight == 'B') { $this->SetStyle('B',true); }
+ if ($this->thead_font_style == 'I') { $this->SetStyle('I',true); }
+ if ($this->thead_font_smCaps == 'S') { $this->textvar = ($this->textvar | FC_SMALLCAPS); } // mPDF 5.7.1
+ }
+
+ // INHERITED TFOOT CSS Properties
+ if ($this->tabletfoot) {
+ if ($this->tfoot_valign_default) $c['va'] = $align[strtolower($this->tfoot_valign_default)];
+ if ($this->tfoot_textalign_default) $c['a'] = $align[strtolower($this->tfoot_textalign_default)];
+ if ($this->tfoot_font_weight == 'B') { $this->SetStyle('B',true); }
+ if ($this->tfoot_font_style == 'I') { $this->SetStyle('I',true); }
+ if ($this->tfoot_font_style == 'S') { $this->textvar = ($this->textvar | FC_SMALLCAPS); } // mPDF 5.7.1
+ }
+
+
+ if ($this->trow_text_rotate){
+ $c['R'] = $this->trow_text_rotate;
+ }
+
+ $this->cell_border_dominance_L = 0;
+ $this->cell_border_dominance_R = 0;
+ $this->cell_border_dominance_T = 0;
+ $this->cell_border_dominance_B = 0;
+
+ $properties = $this->cssmgr->MergeCSS('TABLE',$tag,$attr);
+
+ $properties = $this->cssmgr->array_merge_recursive_unique($this->base_table_properties, $properties);
+
+ $this->Reset(); // mPDF 6 ?????????????????????
+
+ $this->setCSS($properties,'TABLECELL',$tag);
+
+ $c['dfs'] = $this->FontSize; // Default Font size
+
+
+ if (isset($properties['BACKGROUND-COLOR'])) { $c['bgcolor'] = $properties['BACKGROUND-COLOR']; }
+ else if (isset($properties['BACKGROUND'])) { $c['bgcolor'] = $properties['BACKGROUND']; }
+ else if (isset($attr['BGCOLOR'])) $c['bgcolor'] = $attr['BGCOLOR'];
+
+
+
+/*-- BACKGROUNDS --*/
+ if (isset($properties['BACKGROUND-GRADIENT'])) { $c['gradient'] = $properties['BACKGROUND-GRADIENT']; }
+ else { $c['gradient'] = false; }
+
+ if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE'] && !$this->keep_block_together) {
+ $ret = $this->SetBackground($properties, $this->blk[$this->blklvl]['inner_width']);
+ if ($ret) { $c['background-image'] = $ret; }
+ }
+/*-- END BACKGROUNDS --*/
+ if (isset($properties['VERTICAL-ALIGN'])) { $c['va']=$align[strtolower($properties['VERTICAL-ALIGN'])]; }
+ else if (isset($attr['VALIGN'])) $c['va'] = $align[strtolower($attr['VALIGN'])];
+
+
+ if (isset($properties['TEXT-ALIGN']) && $properties['TEXT-ALIGN']) {
+ if (substr($properties['TEXT-ALIGN'],0,1)=='D') { $c['a'] = $properties['TEXT-ALIGN']; }
+ else { $c['a'] = $align[strtolower($properties['TEXT-ALIGN'])]; }
+ }
+ if (isset($attr['ALIGN']) && $attr['ALIGN']) {
+ if (strtolower($attr['ALIGN']) == 'char') {
+ if (isset($attr['CHAR']) && $attr['CHAR']) {
+ $char = html_entity_decode($attr['CHAR']);
+ $char = strcode2utf($char);
+ $d = array_search($char,$this->decimal_align);
+ if ($d !== false) { $c['a'] = $d.'R'; }
+ }
+ else { $c['a'] = 'DPR'; }
+ }
+ else { $c['a'] = $align[strtolower($attr['ALIGN'])]; }
+ }
+
+ // mPDF 6
+ $c['direction'] = $table['direction'];
+ if (isset($attr['DIR']) and $attr['DIR'] != '') { $c['direction'] = strtolower($attr['DIR']); }
+ if(isset($properties['DIRECTION'])) { $c['direction'] = strtolower($properties['DIRECTION']); }
+
+ if (!$c['a']) {
+ if (isset($c['direction']) && $c['direction'] == 'rtl' ) { $c['a'] = 'R'; }
+ else { $c['a'] = 'L'; }
+ }
+
+ $c['cellLineHeight'] = $table['cellLineHeight'];
+ if(isset($properties['LINE-HEIGHT'])) { $c['cellLineHeight'] = $this->fixLineheight($properties['LINE-HEIGHT']); }
+
+ $c['cellLineStackingStrategy'] = $table['cellLineStackingStrategy'];
+ if(isset($properties['LINE-STACKING-STRATEGY'])) { $c['cellLineStackingStrategy'] = strtolower($properties['LINE-STACKING-STRATEGY']); }
+
+ $c['cellLineStackingShift'] = $table['cellLineStackingShift'];
+ if(isset($properties['LINE-STACKING-SHIFT'])) { $c['cellLineStackingShift'] = strtolower($properties['LINE-STACKING-SHIFT']); }
+
+ if (isset($properties['TEXT-ROTATE']) && ($properties['TEXT-ROTATE'] || $properties['TEXT-ROTATE']==="0")){
+ $c['R'] = $properties['TEXT-ROTATE'];
+ }
+ if (isset($properties['BORDER'])) {
+ $bord = $this->border_details($properties['BORDER']);
+ if ($bord['s']) {
+ if (!$this->simpleTables){
+ $c['border'] = _BORDER_ALL;
+ $c['border_details']['R'] = $bord;
+ $c['border_details']['L'] = $bord;
+ $c['border_details']['T'] = $bord;
+ $c['border_details']['B'] = $bord;
+ $c['border_details']['L']['dom'] = $this->cell_border_dominance_L;
+ $c['border_details']['R']['dom'] = $this->cell_border_dominance_R;
+ $c['border_details']['T']['dom'] = $this->cell_border_dominance_T;
+ $c['border_details']['B']['dom'] = $this->cell_border_dominance_B;
+ }
+ else if ($this->simpleTables && $this->row==0 && $this->col==0){
+ $table['simple']['border'] = _BORDER_ALL;
+ $table['simple']['border_details']['R'] = $bord;
+ $table['simple']['border_details']['L'] = $bord;
+ $table['simple']['border_details']['T'] = $bord;
+ $table['simple']['border_details']['B'] = $bord;
+ }
+ }
+ }
+ if (!$this->simpleTables){
+ if (isset($properties['BORDER-RIGHT']) && $properties['BORDER-RIGHT']) {
+ $c['border_details']['R'] = $this->border_details($properties['BORDER-RIGHT']);
+ $this->setBorder($c['border'], _BORDER_RIGHT, $c['border_details']['R']['s']);
+ $c['border_details']['R']['dom'] = $this->cell_border_dominance_R;
+ }
+ if (isset($properties['BORDER-LEFT']) && $properties['BORDER-LEFT']) {
+ $c['border_details']['L'] = $this->border_details($properties['BORDER-LEFT']);
+ $this->setBorder($c['border'], _BORDER_LEFT, $c['border_details']['L']['s']);
+ $c['border_details']['L']['dom'] = $this->cell_border_dominance_L;
+ }
+ if (isset($properties['BORDER-BOTTOM']) && $properties['BORDER-BOTTOM']) {
+ $c['border_details']['B'] = $this->border_details($properties['BORDER-BOTTOM']);
+ $this->setBorder($c['border'], _BORDER_BOTTOM, $c['border_details']['B']['s']);
+ $c['border_details']['B']['dom'] = $this->cell_border_dominance_B;
+ }
+ if (isset($properties['BORDER-TOP']) && $properties['BORDER-TOP']) {
+ $c['border_details']['T'] = $this->border_details($properties['BORDER-TOP']);
+ $this->setBorder($c['border'], _BORDER_TOP, $c['border_details']['T']['s']);
+ $c['border_details']['T']['dom'] = $this->cell_border_dominance_T;
+ }
+ }
+ else if ($this->simpleTables && $this->row==0 && $this->col==0){
+ if (isset($properties['BORDER-LEFT']) && $properties['BORDER-LEFT']) {
+ $bord = $this->border_details($properties['BORDER-LEFT']);
+ if ($bord['s']) { $table['simple']['border'] = _BORDER_ALL; }
+ else { $table['simple']['border'] = 0; }
+ $table['simple']['border_details']['R'] = $bord;
+ $table['simple']['border_details']['L'] = $bord;
+ $table['simple']['border_details']['T'] = $bord;
+ $table['simple']['border_details']['B'] = $bord;
+ }
+ }
+
+ if ($this->simpleTables && $this->row==0 && $this->col==0 && !$table['borders_separate'] && $table['simple']['border'] ){
+ $table['border_details'] = $table['simple']['border_details'];
+ $table['border'] = $table['simple']['border'];
+ }
+
+ // Border set on TR (if collapsed only)
+ if (!$table['borders_separate'] && !$this->simpleTables && isset($table['trborder-left'][$this->row])) {
+ if ($this->col==0) {
+ $left = $this->border_details($table['trborder-left'][$this->row]);
+ $c['border_details']['L'] = $left;
+ $this->setBorder($c['border'], _BORDER_LEFT, $c['border_details']['L']['s']);
+ }
+ $c['border_details']['B'] = $this->border_details($table['trborder-bottom'][$this->row]);
+ $this->setBorder($c['border'], _BORDER_BOTTOM, $c['border_details']['B']['s']);
+ $c['border_details']['T'] = $this->border_details($table['trborder-top'][$this->row]);
+ $this->setBorder($c['border'], _BORDER_TOP, $c['border_details']['T']['s']);
+ }
+
+ if ($this->packTableData && !$this->simpleTables) {
+ $c['borderbin'] = $this->_packCellBorder($c);
+ unset($c['border']);
+ unset($c['border_details']);
+ }
+
+ if (isset($properties['PADDING-LEFT'])) {
+ $c['padding']['L'] = $this->ConvertSize($properties['PADDING-LEFT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ }
+ if (isset($properties['PADDING-RIGHT'])) {
+ $c['padding']['R'] = $this->ConvertSize($properties['PADDING-RIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ }
+ if (isset($properties['PADDING-BOTTOM'])) {
+ $c['padding']['B'] = $this->ConvertSize($properties['PADDING-BOTTOM'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ }
+ if (isset($properties['PADDING-TOP'])) {
+ $c['padding']['T'] = $this->ConvertSize($properties['PADDING-TOP'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ }
+
+ $w = '';
+ if (isset($properties['WIDTH'])) { $w = $properties['WIDTH']; }
+ else if (isset($attr['WIDTH'])) { $w = $attr['WIDTH']; }
+ if ($w) {
+ if (strpos($w,'%') && !$this->ignore_table_percents ) { $c['wpercent'] = $w + 0; } // makes 80% -> 80
+ else if (!strpos($w,'%') && !$this->ignore_table_widths ) { $c['w'] = $this->ConvertSize($w,$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ }
+
+ if (isset($properties['HEIGHT']) && !strpos($properties['HEIGHT'],'%')) { $c['h'] = $this->ConvertSize($properties['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false); }
+ else if (isset($attr['HEIGHT']) && !strpos($attr['HEIGHT'],'%')) $c['h'] = $this->ConvertSize($attr['HEIGHT'],$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+
+ if (isset($properties['WHITE-SPACE'])) {
+ if (strtoupper($properties['WHITE-SPACE']) == 'NOWRAP') { $c['nowrap']= 1; }
+ }
+ $properties = array();
+
+
+ if (isset($attr['TEXT-ROTATE'])) {
+ $c['R'] = $attr['TEXT-ROTATE'];
+ }
+ if (isset($attr['NOWRAP']) && $attr['NOWRAP']) $c['nowrap']= 1;
+
+ $this->cell[$this->row][$this->col] = $c;
+ unset($c);
+ $this->cell[$this->row][$this->col]['s'] = 0 ;
+
+ $cs = $rs = 1;
+ if (isset($attr['COLSPAN']) && $attr['COLSPAN']>1) $cs = $this->cell[$this->row][$this->col]['colspan'] = $attr['COLSPAN'];
+ if ($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nc'] < $this->col+$cs) {
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nc'] = $this->col+$cs;
+ } // following code moved outside if...
+ for($l=$this->col; $l < $this->col+$cs ;$l++) {
+ if ($l-$this->col) $this->cell[$this->row][$l] = 0;
+ }
+ if (isset($attr['ROWSPAN']) && $attr['ROWSPAN']>1) $rs = $this->cell[$this->row][$this->col]['rowspan'] = $attr['ROWSPAN'];
+ for ($k=$this->row ; $k < $this->row+$rs ;$k++) {
+ for($l=$this->col; $l < $this->col+$cs ;$l++) {
+ if ($k-$this->row || $l-$this->col) $this->cell[$k][$l] = 0;
+ }
+ }
+ unset($table);
+ break;
+/*-- END TABLES --*/
+
+
+
+ }//end of switch
+}
+
+
+// LIST MARKERS // mPDF 6 Lists
+function _setListMarker($listitemtype, $listitemimage, $listitemposition) {
+ // if position:inside (and NOT table) - output now as a textbuffer; (so if next is block, will move to new line)
+ // else if position:outside (and NOT table) - output in front of first textbuffer output by setting listitem (cf. _saveTextBuffer)
+ $e = '';
+ $this->listitem = '';
+ $spacer = ' ';
+ // IMAGE
+ if ($listitemimage && $listitemimage != 'none') {
+ $listitemimage = trim(preg_replace('/url\(["\']*(.*?)["\']*\)/','\\1',$listitemimage));
+
+ // ? Restrict maximum height/width of list marker??
+ $maxWidth = 100;
+ $maxHeight = 100;
+
+ $objattr = array();
+ $objattr['margin_top'] = 0;
+ $objattr['margin_bottom'] = 0;
+ $objattr['margin_left'] = 0;
+ $objattr['margin_right'] = 0;
+ $objattr['padding_top'] = 0;
+ $objattr['padding_bottom'] = 0;
+ $objattr['padding_left'] = 0;
+ $objattr['padding_right'] = 0;
+ $objattr['width'] = 0;
+ $objattr['height'] = 0;
+ $objattr['border_top']['w'] = 0;
+ $objattr['border_bottom']['w'] = 0;
+ $objattr['border_left']['w'] = 0;
+ $objattr['border_right']['w'] = 0;
+ $objattr['visibility'] = 'visible';
+ $srcpath = $listitemimage;
+ $orig_srcpath = $listitemimage;
+
+ $objattr['vertical-align'] = 'BS'; // vertical alignment of marker (baseline)
+ $w = 0;
+ $h = 0;
+
+ // Image file
+ $info=$this->_getImage($srcpath, true, true, $orig_srcpath);
+ if(!$info) return;
+ if ($info['w']==0 && $info['h']==0) {
+ $info['h'] = $this->ConvertSize('1em',$this->blk[$this->blklvl]['inner_width'],$this->FontSize,false);
+ }
+ $objattr['file'] = $srcpath;
+ //Default width and height calculation if needed
+ if($w==0 and $h==0) {
+/*-- IMAGES-WMF --*/
+ if ($info['type']=='wmf') {
+ // WMF units are twips (1/20pt)
+ // divide by 20 to get points
+ // divide by k to get user units
+ $w = abs($info['w'])/(20*_MPDFK);
+ $h = abs($info['h']) / (20*_MPDFK);
+ }
+ else
+/*-- END IMAGES-WMF --*/
+ if ($info['type']=='svg') {
+ // SVG units are pixels
+ $w = abs($info['w'])/_MPDFK;
+ $h = abs($info['h'])/_MPDFK;
+ }
+ else {
+ //Put image at default image dpi
+ $w=($info['w']/_MPDFK) * (72/$this->img_dpi);
+ $h=($info['h']/_MPDFK) * (72/$this->img_dpi);
+ }
+ }
+ // IF WIDTH OR HEIGHT SPECIFIED
+ if($w==0) $w=abs($h*$info['w']/$info['h']);
+ if($h==0) $h=abs($w*$info['h']/$info['w']);
+
+ if ($w > $maxWidth ) {
+ $w = $maxWidth;
+ $h=abs($w*$info['h']/$info['w']);
+ }
+
+ if ($h > $maxHeight ) {
+ $h = $maxHeight ;
+ $w=abs($h*$info['w']/$info['h']);
+ }
+ $objattr['type'] = 'image';
+ $objattr['itype'] = $info['type'];
+
+ $objattr['orig_h'] = $info['h'];
+ $objattr['orig_w'] = $info['w'];
+/*-- IMAGES-WMF --*/
+ if ($info['type']=='wmf') {
+ $objattr['wmf_x'] = $info['x'];
+ $objattr['wmf_y'] = $info['y'];
+ }
+ else
+/*-- END IMAGES-WMF --*/
+ if ($info['type']=='svg') {
+ $objattr['wmf_x'] = $info['x'];
+ $objattr['wmf_y'] = $info['y'];
+ }
+ $objattr['height'] = $h;
+ $objattr['width'] = $w;
+ $objattr['image_height'] = $h;
+ $objattr['image_width'] = $w;
+
+ $objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr');
+ $objattr['listmarker'] = true;
+
+ $objattr['listmarkerposition'] = $listitemposition;
+
+ $e = "\xbb\xa4\xactype=image,objattr=".serialize($objattr)."\xbb\xa4\xac";
+ $this->_saveTextBuffer($e);
+
+ if ($listitemposition == 'inside') {
+ $e = $spacer;
+ $this->_saveTextBuffer($e);
+ }
+ }
+ // SYMBOL (needs new font)
+ else if ($listitemtype == 'disc' || $listitemtype == 'circle' || $listitemtype == 'square') {
+ $objattr = array();
+ $objattr['type'] = 'listmarker';
+ $objattr['listmarkerposition'] = $listitemposition;
+ $objattr['width'] = 0;
+ $size = $this->ConvertSize($this->list_symbol_size,$this->FontSize);
+ $objattr['size'] = $size;
+ $objattr['offset'] = $this->ConvertSize($this->list_marker_offset,$this->FontSize);
+
+ if ($listitemposition == 'inside') {
+ $objattr['width'] = $size + $objattr['offset'];
+ }
+
+ $objattr['height'] = $this->FontSize;
+ $objattr['vertical-align'] = 'T';
+ $objattr['text'] = $list_item_marker;
+ $objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr');
+ $objattr['bullet'] = $listitemtype;
+ $objattr['colorarray'] = $this->colorarray;
+ $objattr['fontfamily'] = $this->FontFamily;
+ $objattr['fontsize'] = $this->FontSize;
+ $objattr['fontsizept'] = $this->FontSizePt;
+ $objattr['fontstyle'] = $this->FontStyle;
+
+ $e = "\xbb\xa4\xactype=listmarker,objattr=".serialize($objattr)."\xbb\xa4\xac";
+ $this->listitem = $this->_saveTextBuffer($e, '', '', true); // true returns array
+
+ // if ($listitemposition == 'inside') {
+ // $e = $spacer;
+ // $this->_saveTextBuffer($e);
+ // }
+ }
+ // SYMBOL 2 (needs new font)
+ else if (preg_match('/U\+([a-fA-F0-9]+)/i',$listitemtype,$m)) {
+ if ($this->_charDefined($this->CurrentFont['cw'],hexdec($m[1]))) { $list_item_marker = codeHex2utf($m[1]); }
+ else { $list_item_marker = '-'; }
+ if (preg_match('/rgb\(.*?\)/',$listitemtype,$m)) {
+ $list_item_color = $this->ConvertColor($m[0]);
+ }
+ else { $list_item_color = ''; }
+
+ // SAVE then SET COLR
+ $save_colorarray = $this->colorarray;
+ if ($list_item_color) { $this->colorarray = $list_item_color; }
+
+ if ($listitemposition == 'inside') {
+ $e = $list_item_marker . $spacer;
+ $this->_saveTextBuffer($e);
+ }
+ else {
+ $objattr = array();
+ $objattr['type'] = 'listmarker';
+ $objattr['width'] = 0;
+ $objattr['height'] = $this->FontSize;
+ $objattr['vertical-align'] = 'T';
+ $objattr['text'] = $list_item_marker;
+ $objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr');
+ $objattr['colorarray'] = $this->colorarray;
+ $objattr['fontfamily'] = $this->FontFamily;
+ $objattr['fontsize'] = $this->FontSize;
+ $objattr['fontsizept'] = $this->FontSizePt;
+ $objattr['fontstyle'] = $this->FontStyle;
+ $e = "\xbb\xa4\xactype=listmarker,objattr=".serialize($objattr)."\xbb\xa4\xac";
+ $this->listitem = $this->_saveTextBuffer($e, '', '', true); // true returns array
+ }
+ // RESET COLOR
+ $this->colorarray = $save_colorarray;
+ }
+ // TEXT
+ else {
+ $counter = $this->listcounter[$this->listlvl];
+ if ($listitemtype=='none') { return; }
+ $num = $this->_getStyledNumber($counter, $listitemtype, true);
+
+ if ($listitemposition == 'inside') {
+ $e = $num . $this->list_number_suffix . $spacer;
+ $this->_saveTextBuffer($e);
+ }
+ else {
+ if (isset($this->blk[$this->blklvl]['direction']) && $this->blk[$this->blklvl]['direction'] == 'rtl') {
+ // REPLACE MIRRORED RTL $this->list_number_suffix e.g. ) -> ( (NB could use UCDN::$mirror_pairs)
+ $m = strtr($this->list_number_suffix, ")]}", "([{") . $num;
+ }
+ else { $m = $num . $this->list_number_suffix; }
+
+ $objattr = array();
+ $objattr['type'] = 'listmarker';
+ $objattr['width'] = 0;
+ $objattr['height'] = $this->FontSize;
+ $objattr['vertical-align'] = 'T';
+ $objattr['text'] = $m;
+ $objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr');
+ $objattr['colorarray'] = $this->colorarray;
+ $objattr['fontfamily'] = $this->FontFamily;
+ $objattr['fontsize'] = $this->FontSize;
+ $objattr['fontsizept'] = $this->FontSizePt;
+ $objattr['fontstyle'] = $this->FontStyle;
+ $e = "\xbb\xa4\xactype=listmarker,objattr=".serialize($objattr)."\xbb\xa4\xac";
+
+ $this->listitem = $this->_saveTextBuffer($e, '', '', true); // true returns array
+ }
+ }
+
+
+}
+
+// mPDF Lists
+function _getListMarkerWidth(&$currblk,&$a,&$i) {
+ $blt_width = 0;
+
+ $markeroffset = $this->ConvertSize($this->list_marker_offset,$this->FontSize);
+
+ // Get Maximum number in the list
+ $maxnum = $this->listcounter[$this->listlvl];
+ if ($currblk['list_style_type'] != 'disc' && $currblk['list_style_type'] != 'circle' && $currblk['list_style_type'] != 'square') {
+ $lvl = 1;
+ for($j=$i+2;$jGetStringWidth(str_repeat('5',strlen($maxnum)).$this->list_number_suffix);
+ break;
+ case 'none':
+ $blt_width = 0;
+ break;
+ case 'upper-alpha':
+ case 'upper-latin':
+ case 'A':
+ $maxnumA = $this->dec2alpha($maxnum,true);
+ if ($maxnum < 13) { $blt_width = $this->GetStringWidth('D'.$this->list_number_suffix); }
+ else { $blt_width = $this->GetStringWidth(str_repeat('W',strlen($maxnumA)).$this->list_number_suffix); }
+ break;
+ case 'lower-alpha':
+ case 'lower-latin':
+ case 'a':
+ $maxnuma = $this->dec2alpha($maxnum,false);
+ if ($maxnum < 13) { $blt_width = $this->GetStringWidth('b'.$this->list_number_suffix); }
+ else { $blt_width = $this->GetStringWidth(str_repeat('m',strlen($maxnuma)).$this->list_number_suffix); }
+ break;
+ case 'upper-roman':
+ case 'I':
+ if ($maxnum>87) { $bbit = 87; }
+ else if ($maxnum>86) { $bbit = 86; }
+ else if ($maxnum>37) { $bbit = 38; }
+ else if ($maxnum>36) { $bbit = 37; }
+ else if ($maxnum>27) { $bbit = 28; }
+ else if ($maxnum>26) { $bbit = 27; }
+ else if ($maxnum>17) { $bbit = 18; }
+ else if ($maxnum>16) { $bbit = 17; }
+ else if ($maxnum>7) { $bbit = 8; }
+ else if ($maxnum>6) { $bbit = 7; }
+ else if ($maxnum>3) { $bbit = 4; }
+ else { $bbit = $maxnum; }
+ $maxlnum = $this->dec2roman($bbit,true);
+ $blt_width = $this->GetStringWidth($maxlnum.$this->list_number_suffix);
+ break;
+ case 'lower-roman':
+ case 'i':
+ if ($maxnum>87) { $bbit = 87; }
+ else if ($maxnum>86) { $bbit = 86; }
+ else if ($maxnum>37) { $bbit = 38; }
+ else if ($maxnum>36) { $bbit = 37; }
+ else if ($maxnum>27) { $bbit = 28; }
+ else if ($maxnum>26) { $bbit = 27; }
+ else if ($maxnum>17) { $bbit = 18; }
+ else if ($maxnum>16) { $bbit = 17; }
+ else if ($maxnum>7) { $bbit = 8; }
+ else if ($maxnum>6) { $bbit = 7; }
+ else if ($maxnum>3) { $bbit = 4; }
+ else { $bbit = $maxnum; }
+ $maxlnum = $this->dec2roman($bbit,false);
+ $blt_width = $this->GetStringWidth($maxlnum.$this->list_number_suffix);
+ break;
+
+ case 'disc':
+ case 'circle':
+ case 'square':
+ $size = $this->ConvertSize($this->list_symbol_size,$this->FontSize);
+ $offset = $this->ConvertSize($this->list_marker_offset,$this->FontSize);
+ $blt_width = $size + $offset;
+ break;
+
+ case 'arabic-indic':
+ $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, 0x0660),strlen($maxnum)).$this->list_number_suffix);
+ break;
+ case 'persian':
+ case 'urdu':
+ $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, 0x06F0),strlen($maxnum)).$this->list_number_suffix);
+ break;
+ case 'bengali':
+ $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, 0x09E6),strlen($maxnum)).$this->list_number_suffix);
+ break;
+ case 'devanagari':
+ $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, 0x0966),strlen($maxnum)).$this->list_number_suffix);
+ break;
+ case 'gujarati':
+ $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, 0x0AE6),strlen($maxnum)).$this->list_number_suffix);
+ break;
+ case 'gurmukhi':
+ $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, 0x0A66),strlen($maxnum)).$this->list_number_suffix);
+ break;
+ case 'kannada':
+ $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, 0x0CE6),strlen($maxnum)).$this->list_number_suffix);
+ break;
+ case 'malayalam':
+ $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(6, 0x0D66),strlen($maxnum)).$this->list_number_suffix);
+ break;
+ case 'oriya':
+ $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, 0x0B66),strlen($maxnum)).$this->list_number_suffix);
+ break;
+ case 'telugu':
+ $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(3, 0x0C66),strlen($maxnum)).$this->list_number_suffix);
+ break;
+ case 'tamil':
+ $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(9, 0x0BE6),strlen($maxnum)).$this->list_number_suffix);
+ break;
+ case 'thai':
+ $blt_width = $this->GetStringWidth(str_repeat($this->dec2other(5, 0x0E50),strlen($maxnum)).$this->list_number_suffix);
+ break;
+ default:
+ $blt_width = $this->GetStringWidth(str_repeat('5',strlen($maxnum)).$this->list_number_suffix);
+ break;
+ }
+
+
+
+ return ($blt_width + $markeroffset);
+}
+
+
+
+function CloseTag($tag,&$ahtml,&$ihtml) { // mPDF 6
+
+ //Closing tag
+ if($tag=='OPTION') { $this->selectoption['ACTIVE'] = false; $this->lastoptionaltag = ''; }
+
+ if($tag=='TTS' or $tag=='TTA' or $tag=='TTZ') {
+ if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
+ unset($this->InlineProperties[$tag]);
+ $ltag = strtolower($tag);
+ $this->$ltag = false;
+ }
+
+
+ if($tag=='FONT' || $tag=='SPAN' || $tag=='CODE' || $tag=='KBD' || $tag=='SAMP' || $tag=='TT' || $tag=='VAR'
+ || $tag=='INS' || $tag=='STRONG' || $tag=='CITE' || $tag=='SUB' || $tag=='SUP' || $tag=='S' || $tag=='STRIKE' || $tag=='DEL'
+ || $tag=='Q' || $tag=='EM' || $tag=='B' || $tag=='I' || $tag=='U' | $tag=='SMALL' || $tag=='BIG' || $tag=='ACRONYM'
+ || $tag=='MARK' || $tag=='TIME' || $tag=='PROGRESS' || $tag=='METER' || $tag== 'BDO' || $tag== 'BDI'
+ ) {
+
+ $annot = false; // mPDF 6
+ $bdf = false; // mPDF 6
+
+ // mPDF 5.7.3 Inline tags
+ if ($tag=='PROGRESS' || $tag=='METER') {
+ if (isset($this->InlineProperties[$tag]) && $this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
+ unset($this->InlineProperties[$tag]);
+ if (isset($this->InlineAnnots[$tag]) && $this->InlineAnnots[$tag]) { $annot = $this->InlineAnnots[$tag]; } // *ANNOTATIONS*
+ unset($this->InlineAnnots[$tag]); // *ANNOTATIONS*
+ }
+ else {
+ if (isset($this->InlineProperties[$tag]) && count($this->InlineProperties[$tag])) {
+ $tmpProps = array_pop($this->InlineProperties[$tag]); // mPDF 5.7.4
+ $this->restoreInlineProperties($tmpProps);
+ }
+ if (isset($this->InlineAnnots[$tag]) && count($this->InlineAnnots[$tag])) { // *ANNOTATIONS*
+ $annot = array_pop($this->InlineAnnots[$tag]); // *ANNOTATIONS*
+ } // *ANNOTATIONS*
+ if (isset($this->InlineBDF[$tag]) && count($this->InlineBDF[$tag])) { // mPDF 6
+ $bdfarr = array_pop($this->InlineBDF[$tag]);
+ $bdf = $bdfarr[0];
+ }
+ }
+
+/*-- ANNOTATIONS --*/
+ if ($annot) { // mPDF 6
+ if($this->tableLevel) { // *TABLES*
+ $this->cell[$this->row][$this->col]['textbuffer'][] = array($annot); // *TABLES*
+ } // *TABLES*
+ else { // *TABLES*
+ $this->textbuffer[] = array($annot);
+ } // *TABLES*
+ }
+/*-- END ANNOTATIONS --*/
+
+ // mPDF 6 bidi
+ // mPDF 6 Bidirectional formatting for inline elements
+ if ($bdf) {
+ $popf = $this->_setBidiCodes('end', $bdf);
+ $this->OTLdata = array();
+ if($this->tableLevel) { $this->_saveCellTextBuffer($popf); }
+ else { $this->_saveTextBuffer($popf); }
+ }
+
+ } // End of (most) Inline elements eg SPAN
+
+
+ if($tag=='METER' || $tag=='PROGRESS') {
+ $this->ignorefollowingspaces = false;
+ $this->inMeter = false;
+ }
+
+
+ if($tag=='A') {
+ $this->HREF='';
+ if (isset($this->InlineProperties['A'])) { $this->restoreInlineProperties($this->InlineProperties['A']); }
+ unset($this->InlineProperties['A']);
+ }
+
+ if($tag=='LEGEND') {
+ if (count($this->textbuffer) && !$this->tableLevel) {
+ $leg = $this->textbuffer[(count($this->textbuffer)-1)];
+ unset($this->textbuffer[(count($this->textbuffer)-1)]);
+ $this->textbuffer = array_values($this->textbuffer);
+ $this->blk[$this->blklvl]['border_legend'] = $leg;
+ $this->blk[$this->blklvl]['margin_top'] += ($leg[11]/2)/_MPDFK;
+ $this->blk[$this->blklvl]['padding_top'] += ($leg[11]/2)/_MPDFK;
+ }
+ if (isset($this->InlineProperties['LEGEND'])) { $this->restoreInlineProperties($this->InlineProperties['LEGEND']); }
+ unset($this->InlineProperties['LEGEND']);
+ $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
+ }
+
+
+
+/*-- FORMS --*/
+ // *********** FORM ELEMENTS ********************
+
+ if($tag=='TEXTAREA') {
+ $this->ignorefollowingspaces = false;
+ $this->specialcontent = '';
+ if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
+ unset($this->InlineProperties[$tag]);
+ }
+
+
+ if($tag=='SELECT') {
+ $this->ignorefollowingspaces = false;
+ $this->lastoptionaltag = '';
+ $texto = '';
+ $OTLdata = false;
+ if (isset($this->selectoption['SELECTED'])) { $texto = $this->selectoption['SELECTED']; }
+ if (isset($this->selectoption['SELECTED-OTLDATA'])) { $OTLdata = $this->selectoption['SELECTED-OTLDATA']; }
+
+ if ($this->useActiveForms) { $w = $this->selectoption['MAXWIDTH']; }
+ else { $w = $this->GetStringWidth($texto, true, $OTLdata); }
+ if ($w == 0) { $w = 5; }
+ $objattr['type'] = 'select';
+ $objattr['text'] = $texto;
+ $objattr['OTLdata'] = $OTLdata;
+ if (isset($this->selectoption['NAME'])) { $objattr['fieldname'] = $this->selectoption['NAME']; }
+ if (isset($this->selectoption['READONLY'])) { $objattr['readonly'] = true; }
+ if (isset($this->selectoption['REQUIRED'])) { $objattr['required'] = true; }
+ if (isset($this->selectoption['SPELLCHECK'])) { $objattr['spellcheck'] = true; }
+ if (isset($this->selectoption['EDITABLE'])) { $objattr['editable'] = true; }
+ if (isset($this->selectoption['ONCHANGE'])) { $objattr['onChange'] = $this->selectoption['ONCHANGE']; }
+ if (isset($this->selectoption['ITEMS'])) { $objattr['items'] = $this->selectoption['ITEMS']; }
+ if (isset($this->selectoption['MULTIPLE'])) { $objattr['multiple'] = $this->selectoption['MULTIPLE']; }
+ if (isset($this->selectoption['DISABLED'])) { $objattr['disabled'] = $this->selectoption['DISABLED']; }
+ if (isset($this->selectoption['TITLE'])) { $objattr['title'] = $this->selectoption['TITLE']; }
+ if (isset($this->selectoption['COLOR'])) { $objattr['color'] = $this->selectoption['COLOR']; }
+ if (isset($this->selectoption['SIZE'])) { $objattr['size'] = $this->selectoption['SIZE']; }
+ if (isset($objattr['size']) && $objattr['size']>1) { $rows=$objattr['size']; } else { $rows = 1; }
+
+ $objattr['fontfamily'] = $this->FontFamily;
+ $objattr['fontsize'] = $this->FontSizePt;
+
+ $objattr['width'] = $w + ($this->mpdfform->form_element_spacing['select']['outer']['h']*2)+($this->mpdfform->form_element_spacing['select']['inner']['h']*2) + ($this->FontSize*1.4);
+ $objattr['height'] = ($this->FontSize*$rows) + ($this->mpdfform->form_element_spacing['select']['outer']['v']*2)+($this->mpdfform->form_element_spacing['select']['inner']['v']*2);
+ $e = "\xbb\xa4\xactype=select,objattr=".serialize($objattr)."\xbb\xa4\xac";
+
+ // Clear properties - tidy up
+ $properties = array();
+
+ // Output it to buffers
+ if ($this->tableLevel) { // *TABLES*
+ $this->_saveCellTextBuffer($e, $this->HREF);
+ $this->cell[$this->row][$this->col]['s'] += $objattr['width'] ; // *TABLES*
+ } // *TABLES*
+ else { // *TABLES*
+ $this->_saveTextBuffer($e, $this->HREF);
+ } // *TABLES*
+
+ $this->selectoption = array();
+ $this->specialcontent = '';
+
+ if ($this->InlineProperties[$tag]) { $this->restoreInlineProperties($this->InlineProperties[$tag]); }
+ unset($this->InlineProperties[$tag]);
+
+ }
+/*-- END FORMS --*/
+
+
+ // *********** BLOCKS ********************
+ // mPDF 6 Lists
+ if($tag=='P' || $tag=='DIV' || $tag=='H1' || $tag=='H2' || $tag=='H3' || $tag=='H4' || $tag=='H5' || $tag=='H6' || $tag=='PRE'
+ || $tag=='FORM' || $tag=='ADDRESS' || $tag=='BLOCKQUOTE' || $tag=='CENTER' || $tag=='DT' || $tag=='DD' || $tag=='DL'
+ || $tag=='CAPTION' || $tag=='FIELDSET' || $tag=='UL' || $tag=='OL' || $tag=='LI'
+ || $tag=='ARTICLE' || $tag=='ASIDE' || $tag=='FIGURE' || $tag=='FIGCAPTION' || $tag=='FOOTER' || $tag=='HEADER' || $tag=='HGROUP'
+ || $tag=='MAIN' || $tag=='NAV' || $tag=='SECTION' || $tag=='DETAILS' || $tag=='SUMMARY'
+ ) {
+
+ // mPDF 6 bidi
+ // Block
+ // If unicode-bidi set, any embedding levels, isolates, or overrides started by this box are closed
+ if (isset($this->blk[$this->blklvl]['bidicode'])) {
+ $blockpost = $this->_setBidiCodes('end', $this->blk[$this->blklvl]['bidicode']);
+ if ($blockpost) {
+ $this->OTLdata = array();
+ if($this->tableLevel) { $this->_saveCellTextBuffer($blockpost); }
+ else { $this->_saveTextBuffer($blockpost); }
+ }
+ }
+
+ $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
+ $this->blockjustfinished=true;
+
+ $this->lastblockbottommargin = $this->blk[$this->blklvl]['margin_bottom'];
+ // mPDF 6 Lists
+ if ($tag == 'UL' || $tag == 'OL') {
+ if ($this->listlvl>0 && $this->tableLevel) {
+ if (isset($this->listtype[$this->listlvl])) unset($this->listtype[$this->listlvl]);
+ }
+ $this->listlvl--;
+ $this->listitem = array();
+ }
+ if ($tag == 'LI') {
+ $this->listitem = array();
+ }
+
+ if (preg_match('/^H\d/',$tag) && !$this->tableLevel && !$this->writingToC) {
+ if (isset($this->h2toc[$tag]) || isset($this->h2bookmarks[$tag])) {
+ $content = '';
+ if (count($this->textbuffer)==1) { $content = $this->textbuffer[0][0]; }
+ else {
+ for ($i=0;$itextbuffer);$i++) {
+ if (substr($this->textbuffer[$i][0],0,3) != "\xbb\xa4\xac") { //inline object
+ $content .= $this->textbuffer[$i][0];
+ }
+ }
+ }
+/*-- TOC --*/
+ if (isset($this->h2toc[$tag])) {
+ $objattr = array();
+ $objattr['type'] = 'toc';
+ $objattr['toclevel'] = $this->h2toc[$tag];
+ $objattr['CONTENT'] = htmlspecialchars($content);
+ $e = "\xbb\xa4\xactype=toc,objattr=".serialize($objattr)."\xbb\xa4\xac";
+ array_unshift($this->textbuffer,array($e));
+ }
+/*-- END TOC --*/
+/*-- BOOKMARKS --*/
+ if (isset($this->h2bookmarks[$tag])) {
+ $objattr = array();
+ $objattr['type'] = 'bookmark';
+ $objattr['bklevel'] = $this->h2bookmarks[$tag];
+ $objattr['CONTENT'] = $content;
+ $e = "\xbb\xa4\xactype=toc,objattr=".serialize($objattr)."\xbb\xa4\xac";
+ array_unshift($this->textbuffer,array($e));
+ }
+/*-- END BOOKMARKS --*/
+ }
+ }
+
+/*-- TABLES --*/
+ if($this->tableLevel) {
+ if ($this->linebreakjustfinished) { $this->blockjustfinished=false; }
+ if (isset($this->InlineProperties['BLOCKINTABLE'])) {
+ if ($this->InlineProperties['BLOCKINTABLE']) { $this->restoreInlineProperties($this->InlineProperties['BLOCKINTABLE']); }
+ unset($this->InlineProperties['BLOCKINTABLE']);
+ }
+ if($tag=='PRE') { $this->ispre=false; }
+ return;
+ }
+/*-- END TABLES --*/
+ $this->lastoptionaltag = '';
+ $this->divbegin=false;
+
+ $this->linebreakjustfinished=false;
+
+ $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
+
+/*-- CSS-FLOAT --*/
+ // If float contained in a float, need to extend bottom to allow for it
+ $currpos = $this->page*1000 + $this->y;
+ if (isset($this->blk[$this->blklvl]['float_endpos']) && $this->blk[$this->blklvl]['float_endpos'] > $currpos) {
+ $old_page = $this->page;
+ $new_page = intval($this->blk[$this->blklvl]['float_endpos'] /1000);
+ if ($old_page != $new_page) {
+ $s = $this->PrintPageBackgrounds();
+ // Writes after the marker so not overwritten later by page background etc.
+ $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
+ $this->pageBackgrounds = array();
+ $this->page = $new_page;
+ $this->ResetMargins();
+ $this->Reset();
+ $this->pageoutput[$this->page] = array();
+ }
+ $this->y = (($this->blk[$this->blklvl]['float_endpos'] *1000) % 1000000)/1000; // mod changes operands to integers before processing
+ }
+/*-- END CSS-FLOAT --*/
+
+
+ //Print content
+ if ($this->lastblocklevelchange == 1) { $blockstate = 3; } // Top & bottom margins/padding
+ else if ($this->lastblocklevelchange == -1) { $blockstate = 2; } // Bottom margins/padding only
+ else { $blockstate = 0; }
+ // called from after e.g. ... Outputs block margin/border and padding
+ if (count($this->textbuffer) && $this->textbuffer[count($this->textbuffer)-1]) {
+ if (substr($this->textbuffer[count($this->textbuffer)-1][0],0,3) != "\xbb\xa4\xac") { // not special content
+ // Right trim last content and adjust OTLdata
+ if (preg_match('/[ ]+$/',$this->textbuffer[count($this->textbuffer)-1][0], $m)) {
+ $strip = strlen($m[0]);
+ $this->textbuffer[count($this->textbuffer)-1][0] = substr($this->textbuffer[count($this->textbuffer)-1][0],0,(strlen($this->textbuffer[count($this->textbuffer)-1][0])-$strip));
+/*-- OTL --*/
+ if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) {
+ $this->otl->trimOTLdata($this->textbuffer[count($this->textbuffer)-1][18], false, true); // mPDF 6 ZZZ99K
+ }
+/*-- END OTL --*/
+ }
+ }
+ }
+
+ if (count($this->textbuffer) == 0 && $this->lastblocklevelchange != 0) {
+ //$this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,2,true, (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr'));
+ $this->newFlowingBlock( $this->blk[$this->blklvl]['width'],$this->lineheight,'',false,$blockstate,true, (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr'));
+ $this->finishFlowingBlock(true); // true = END of flowing block
+ $this->PaintDivBB('',$blockstate);
+ }
+ else {
+ $this->printbuffer($this->textbuffer,$blockstate);
+ }
+
+
+ $this->textbuffer=array();
+
+ if ($this->kwt) {
+ $this->kwt_height = $this->y - $this->kwt_y0;
+ }
+
+/*-- CSS-IMAGE-FLOAT --*/
+ $this->printfloatbuffer();
+/*-- END CSS-IMAGE-FLOAT --*/
+
+ if($tag=='PRE') { $this->ispre=false; }
+
+/*-- CSS-FLOAT --*/
+ if ($this->blk[$this->blklvl]['float'] == 'R') {
+ // If width not set, here would need to adjust and output buffer
+ $s = $this->PrintPageBackgrounds();
+ // Writes after the marker so not overwritten later by page background etc.
+ $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
+ $this->pageBackgrounds = array();
+ $this->Reset();
+ $this->pageoutput[$this->page] = array();
+
+ for($i=($this->blklvl-1); $i >= 0; $i--) {
+ if (isset($this->blk[$i]['float_endpos'])) { $this->blk[$i]['float_endpos'] = max($this->blk[$i]['float_endpos'], ($this->page*1000 + $this->y)); }
+ else { $this->blk[$i]['float_endpos'] = $this->page*1000 + $this->y; }
+ }
+
+ $this->floatDivs[] = array(
+ 'side'=>'R',
+ 'startpage'=>$this->blk[$this->blklvl]['startpage'] ,
+ 'y0'=>$this->blk[$this->blklvl]['float_start_y'] ,
+ 'startpos'=> ($this->blk[$this->blklvl]['startpage']*1000 + $this->blk[$this->blklvl]['float_start_y']),
+ 'endpage'=>$this->page ,
+ 'y1'=>$this->y ,
+ 'endpos'=> ($this->page*1000 + $this->y),
+ 'w'=> $this->blk[$this->blklvl]['float_width'],
+ 'blklvl'=>$this->blklvl,
+ 'blockContext' => $this->blk[$this->blklvl-1]['blockContext']
+ );
+
+ $this->y = $this->blk[$this->blklvl]['float_start_y'] ;
+ $this->page = $this->blk[$this->blklvl]['startpage'] ;
+ $this->ResetMargins();
+ $this->pageoutput[$this->page] = array();
+ }
+ if ($this->blk[$this->blklvl]['float'] == 'L') {
+ // If width not set, here would need to adjust and output buffer
+ $s = $this->PrintPageBackgrounds();
+ // Writes after the marker so not overwritten later by page background etc.
+ $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS'.$this->uniqstr.')/', '\\1'."\n".$s."\n", $this->pages[$this->page]);
+ $this->pageBackgrounds = array();
+ $this->Reset();
+ $this->pageoutput[$this->page] = array();
+
+ for($i=($this->blklvl-1); $i >= 0; $i--) {
+ if (isset($this->blk[$i]['float_endpos'])) { $this->blk[$i]['float_endpos'] = max($this->blk[$i]['float_endpos'], ($this->page*1000 + $this->y)); }
+ else { $this->blk[$i]['float_endpos'] = $this->page*1000 + $this->y; }
+ }
+
+ $this->floatDivs[] = array(
+ 'side'=>'L',
+ 'startpage'=>$this->blk[$this->blklvl]['startpage'] ,
+ 'y0'=>$this->blk[$this->blklvl]['float_start_y'] ,
+ 'startpos'=> ($this->blk[$this->blklvl]['startpage']*1000 + $this->blk[$this->blklvl]['float_start_y']),
+ 'endpage'=>$this->page ,
+ 'y1'=>$this->y ,
+ 'endpos'=> ($this->page*1000 + $this->y),
+ 'w'=> $this->blk[$this->blklvl]['float_width'],
+ 'blklvl'=>$this->blklvl,
+ 'blockContext' => $this->blk[$this->blklvl-1]['blockContext']
+ );
+
+ $this->y = $this->blk[$this->blklvl]['float_start_y'] ;
+ $this->page = $this->blk[$this->blklvl]['startpage'] ;
+ $this->ResetMargins();
+ $this->pageoutput[$this->page] = array();
+ }
+/*-- END CSS-FLOAT --*/
+
+ if (isset($this->blk[$this->blklvl]['visibility']) && $this->blk[$this->blklvl]['visibility']!='visible') {
+ $this->SetVisibility('visible');
+ }
+
+ if (isset($this->blk[$this->blklvl]['page_break_after'])) { $page_break_after = $this->blk[$this->blklvl]['page_break_after']; }
+ else { $page_break_after = ''; }
+
+ //Reset values
+ $this->Reset();
+
+ if (isset($this->blk[$this->blklvl]['z-index']) && $this->blk[$this->blklvl]['z-index'] > 0) {
+ $this->EndLayer();
+ }
+
+ // mPDF 6 page-break-inside:avoid
+ if ($this->blk[$this->blklvl]['keep_block_together']) {
+ $movepage=false;
+ // If page-break-inside:avoid section has broken to new page but fits on one side - then move:
+ if (($this->page - $this->kt_p00) == 1 && $this->y < $this->kt_y00) {
+ $movepage=true;
+ }
+ if (($this->page - $this->kt_p00) > 0) {
+ for ($i=$this->page;$i>$this->kt_p00;$i--) {
+ unset($this->pages[$i]);
+ if (isset($this->blk[$this->blklvl]['bb_painted'][$i])) { unset($this->blk[$this->blklvl]['bb_painted'][$i]); }
+ if (isset($this->blk[$this->blklvl]['marginCorrected'][$i])) { unset($this->blk[$this->blklvl]['marginCorrected'][$i]); }
+ if (isset($this->pageoutput[$i])) { unset($this->pageoutput[$i]); }
+ }
+ $this->page = $this->kt_p00;
+ }
+ $this->keep_block_together = 0;
+ $this->pageoutput[$this->page] = array();
+
+ $this->y = $this->kt_y00;
+ $ihtml = $this->blk[$this->blklvl]['array_i']-1;
+
+ $ahtml[$ihtml+1] .= ' pagebreakavoidchecked="true";'; // avoid re-iterating; read in OpenTag()
+
+ unset($this->blk[$this->blklvl]);
+ $this->blklvl--;
+
+ for ($blklvl=1;$blklvl<=$this->blklvl;$blklvl++) {
+ $this->blk[$blklvl]['y0'] = $this->blk[$blklvl]['initial_y0'] ;
+ $this->blk[$blklvl]['x0'] = $this->blk[$blklvl]['initial_x0'] ;
+ $this->blk[$blklvl]['startpage'] = $this->blk[$blklvl]['initial_startpage'] ;
+ }
+
+ if (isset($this->blk[$this->blklvl]['x0'])) { $this->x = $this->blk[$this->blklvl]['x0']; }
+ else { $this->x=$this->lMargin; }
+
+ $this->lastblocklevelchange = 0;
+ $this->ResetMargins();
+ if ($movepage) { $this->AddPage(); }
+ return;
+ }
+
+ if ($this->blklvl > 0) { // ==0 SHOULDN'T HAPPEN - NOT XHTML
+ if ($this->blk[$this->blklvl]['tag'] == $tag) {
+ unset($this->blk[$this->blklvl]);
+ $this->blklvl--;
+ }
+ //else { echo $tag; exit; } // debug - forces error if incorrectly nested html tags
+ }
+
+ $this->lastblocklevelchange = -1 ;
+ // Reset Inline-type properties
+ if (isset($this->blk[$this->blklvl]['InlineProperties'])) { $this->restoreInlineProperties($this->blk[$this->blklvl]['InlineProperties']); }
+
+ $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
+
+ if (!$this->tableLevel && $page_break_after) {
+ $save_blklvl = $this->blklvl;
+ $save_blk = $this->blk;
+ $save_silp = $this->saveInlineProperties();
+ $save_ilp = $this->InlineProperties;
+ $save_bflp = $this->InlineBDF;
+ $save_bflpc = $this->InlineBDFctr; // mPDF 6
+
+ // mPDF 6 pagebreaktype
+ $startpage = $this->page;
+ $pagebreaktype = $this->defaultPagebreakType;
+ if ($this->ColActive) { $pagebreaktype = 'cloneall'; }
+
+ // mPDF 6 pagebreaktype
+ $this->_preForcedPagebreak($pagebreaktype);
+
+ if ($page_break_after == 'RIGHT') { $this->AddPage($this->CurOrientation,'NEXT-ODD','','','','','', '','', '','','','','','',0,0,0,0); }
+ else if ($page_break_after == 'LEFT') { $this->AddPage($this->CurOrientation,'NEXT-EVEN','','','','','', '','', '','','','','','',0,0,0,0); }
+ else { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0); }
+
+ // mPDF 6 pagebreaktype
+ $this->_postForcedPagebreak($pagebreaktype, $startpage, $save_blk, $save_blklvl);
+
+ $this->InlineProperties = $save_ilp;
+ $this->InlineBDF = $save_bflp;
+ $this->InlineBDFctr = $save_bflpc; // mPDF 6
+ $this->restoreInlineProperties($save_silp);
+ }
+ // mPDF 6 bidi
+ // Block
+ // If unicode-bidi set, any embedding levels, isolates, or overrides reopened in the continuing block
+ if (isset($this->blk[$this->blklvl]['bidicode'])) {
+ $blockpre = $this->_setBidiCodes('start', $this->blk[$this->blklvl]['bidicode']);
+ if ($blockpre) {
+ $this->OTLdata = array();
+ if($this->tableLevel) { $this->_saveCellTextBuffer($blockpre); }
+ else { $this->_saveTextBuffer($blockpre); }
+ }
+ }
+
+ }
+
+
+/*-- TABLES --*/
+
+ if($tag=='TH') $this->SetStyle('B',false);
+
+ if(($tag=='TH' or $tag=='TD') && $this->tableLevel) {
+ $this->lastoptionaltag = 'TR';
+ unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
+ $this->cssmgr->tbCSSlvl--;
+ if (!$this->tdbegin) { return; }
+ $this->tdbegin = false;
+ // Added for correct calculation of cell column width - otherwise misses the last line if not end etc.
+ if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
+ if (!is_array($this->cell[$this->row][$this->col])) { $this->Error("You may have an error in your HTML code e.g. </td></td>"); }
+ $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
+ }
+ elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
+ $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
+ }
+
+ // Remove last if at end of cell
+ if (isset($this->cell[$this->row][$this->col]['textbuffer'])) { $ntb = count($this->cell[$this->row][$this->col]['textbuffer']); }
+ else { $ntb = 0; }
+ if ($ntb>1 && $this->cell[$this->row][$this->col]['textbuffer'][$ntb-1][0] == "\n") {
+ unset($this->cell[$this->row][$this->col]['textbuffer'][$ntb-1]);
+ }
+
+ if ($this->tablethead) {
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_thead'][$this->row] = true;
+ if ($this->tableLevel==1) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['headernrows'] = max($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['headernrows'] , ($this->row+1)); }
+ }
+ if ($this->tabletfoot) {
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'][$this->row] = true;
+ if ($this->tableLevel==1) { $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['footernrows'] = max($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['footernrows'] , ($this->row+1 - $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['headernrows'] )); }
+ }
+ $this->Reset();
+ }
+
+ if($tag=='TR' && $this->tableLevel) {
+ // If Border set on TR - Update right border
+ if (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-left'][$this->row])) {
+ $c =& $this->cell[$this->row][$this->col];
+ if ($c) {
+ if ($this->packTableData) {
+ $cell = $this->_unpackCellBorder($c['borderbin'] );
+ }
+ else { $cell = $c; }
+ $cell['border_details']['R'] = $this->border_details($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trborder-right'][$this->row]);
+ $this->setBorder($cell['border'], _BORDER_RIGHT, $cell['border_details']['R']['s']);
+ if ($this->packTableData) {
+ $c['borderbin'] = $this->_packCellBorder($cell);
+ unset($c['border']);
+ unset($c['border_details']);
+ }
+ else { $c = $cell; }
+ }
+ }
+ $this->lastoptionaltag = '';
+ unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
+ $this->cssmgr->tbCSSlvl--;
+ $this->trow_text_rotate = '';
+ $this->tabletheadjustfinished = false;
+ }
+
+ if($tag=='TBODY') {
+ $this->lastoptionaltag = '';
+ unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
+ $this->cssmgr->tbCSSlvl--;
+ }
+
+ if($tag=='THEAD') {
+ $this->lastoptionaltag = '';
+ unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
+ $this->cssmgr->tbCSSlvl--;
+ $this->tablethead = 0;
+ $this->tabletheadjustfinished = true;
+ $this->ResetStyles();
+ $this->thead_font_weight = '';
+ $this->thead_font_style = '';
+ $this->thead_font_smCaps = '';
+
+ $this->thead_valign_default = '';
+ $this->thead_textalign_default = '';
+ }
+
+ if($tag=='TFOOT') {
+ $this->lastoptionaltag = '';
+ unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
+ $this->cssmgr->tbCSSlvl--;
+ $this->tabletfoot = 0;
+ $this->ResetStyles();
+ $this->tfoot_font_weight = '';
+ $this->tfoot_font_style = '';
+ $this->tfoot_font_smCaps = '';
+
+ $this->tfoot_valign_default = '';
+ $this->tfoot_textalign_default = '';
+ }
+
+ if($tag=='TABLE') { // TABLE-END (
+ if ($this->progressBar) { $this->UpdateProgressBar(1,'','TABLE'); } // *PROGRESS-BAR*
+ if ($this->progressBar) { $this->UpdateProgressBar(7,0,''); } // *PROGRESS-BAR*
+ $this->lastoptionaltag = '';
+ unset($this->cssmgr->tablecascadeCSS[$this->cssmgr->tbCSSlvl]);
+ $this->cssmgr->tbCSSlvl--;
+ $this->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces
+ // mPDF 5.7.3
+ // In case a colspan (on a row after first row) exceeded number of columns in table
+ for ($k=0; $k < $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr']; $k++) {
+ for($l=0; $l < $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nc']; $l++) {
+ if (!isset($this->cell[$k][$l])) {
+ for ($n=$l-1; $n>=0; $n--) {
+ if (isset($this->cell[$k][$n]) && $this->cell[$k][$n]!=0) { break; }
+ }
+ $this->cell[$k][$l] = array(
+ 'a' => 'C',
+ 'va' => 'M',
+ 'R' => false,
+ 'nowrap' => false,
+ 'bgcolor' => false,
+ 'padding' => array('L' => false, 'R' => false, 'T' => false, 'B' => false),
+ 'gradient' => false,
+ 's' => 0,
+ 'maxs' => 0,
+ 'textbuffer' => array(),
+ 'dfs' => $this->FontSize,
+ );
+
+ if (!$this->simpleTables){
+ $this->cell[$k][$l]['border'] = 0;
+ $this->cell[$k][$l]['border_details']['R'] = array('s' => 0, 'w' => 0, 'c' => false, 'style' => 'none', 'dom' => 0);
+ $this->cell[$k][$l]['border_details']['L'] = array('s' => 0, 'w' => 0, 'c' => false, 'style' => 'none', 'dom' => 0);
+ $this->cell[$k][$l]['border_details']['T'] = array('s' => 0, 'w' => 0, 'c' => false, 'style' => 'none', 'dom' => 0);
+ $this->cell[$k][$l]['border_details']['B'] = array('s' => 0, 'w' => 0, 'c' => false, 'style' => 'none', 'dom' => 0);
+ $this->cell[$k][$l]['border_details']['mbw'] = array('BL' =>0,'BR' =>0,'RT' =>0,'RB' =>0,'TL' =>0,'TR' =>0,'LT' =>0,'LB' =>0);
+ if ($this->packTableData) {
+ $this->cell[$k][$l]['borderbin'] = $this->_packCellBorder($this->cell[$k][$l]);
+ unset($this->cell[$k][$l]['border']);
+ unset($this->cell[$k][$l]['border_details']);
+ }
+ }
+ }
+ }
+ }
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] = $this->cell;
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['wc'] = array_pad(array(),$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nc'],array('miw'=>0,'maw'=>0));
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['hr'] = array_pad(array(),$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr'],0);
+
+ // Move table footer row to end of table
+ if (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot']) && count($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'])) {
+ $tfrows = array();
+ foreach($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'] AS $r=>$val) {
+ if ($val) { $tfrows[] = $r; }
+ }
+ $temp = array();
+ $temptf = array();
+ foreach($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] AS $k=>$row) {
+ if (in_array($k,$tfrows)) {
+ $temptf[] = $row;
+ }
+ else {
+ $temp[] = $row;
+ }
+ }
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'] = array();
+ for($i=count($temp) ; $i<(count($temp)+count($temptf)); $i++) {
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['is_tfoot'][$i] = true;
+ }
+ // Update nestedpos row references
+ if (isset($this->table[($this->tableLevel+1)]) && count($this->table[($this->tableLevel+1)])) {
+ foreach($this->table[($this->tableLevel+1)] AS $nid=>$nested) {
+ $this->table[($this->tableLevel+1)][$nid]['nestedpos'][0] -= count($temptf);
+ }
+ }
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'] = array_merge($temp, $temptf);
+
+ // Update other arays set on row number
+ // [trbackground-images] [trgradients]
+ $temptrbgi = array();
+ $temptrbgg = array();
+ $temptrbgc = array();
+ if (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][-1])) {
+ $temptrbgc[-1] = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][-1];
+ }
+ for($k=0; $k<$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr']; $k++) {
+ if (!in_array($k,$tfrows)) {
+ $temptrbgi[] = (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'][$k]) ? $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'][$k] : null);
+ $temptrbgg[] = (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'][$k]) ? $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'][$k] : null);
+ $temptrbgc[] = (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$k]) ? $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$k] : null);
+ }
+ }
+ for($k=0; $k<$this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['nr']; $k++) {
+ if (in_array($k,$tfrows)) {
+ $temptrbgi[] = (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'][$k]) ? $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'][$k] : null);
+ $temptrbgg[] = (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'][$k]) ? $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'][$k] : null);
+ $temptrbgc[] = (isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$k]) ? $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'][$k] : null);
+ }
+ }
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trbackground-images'] = $temptrbgi;
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['trgradients'] = $temptrbgg;
+ $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['bgcolor'] = $temptrbgc ;
+ // Should Update all other arays set on row number, but cell properties have been set so not needed
+ // [bgcolor] [trborder-left] [trborder-right] [trborder-top] [trborder-bottom]
+ }
+
+ if ($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['direction']=='rtl') {
+ $this->_reverseTableDir($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]);
+ }
+
+ // Fix Borders *********************************************
+ $this->_fixTableBorders($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]);
+
+ if ($this->progressBar) { $this->UpdateProgressBar(7,10,' '); } // *PROGRESS-BAR*
+
+ if ($this->ColActive) { $this->table_rotate = 0; } // *COLUMNS*
+ if ($this->table_rotate <> 0) {
+ $this->tablebuffer = '';
+ // Max width for rotated table
+ $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 1);
+ $this->tbrot_maxh = $this->blk[$this->blklvl]['inner_width'] ; // Max width for rotated table
+ $this->tbrot_align = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['a'] ;
+ }
+ $this->shrin_k = 1;
+
+ if ($this->shrink_tables_to_fit < 1) { $this->shrink_tables_to_fit = 1; }
+ if (!$this->shrink_this_table_to_fit) { $this->shrink_this_table_to_fit = $this->shrink_tables_to_fit; }
+
+ if ($this->tableLevel>1) {
+ // deal with nested table
+
+ $this->_tableColumnWidth($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]],true);
+
+ $tmiw = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['miw'];
+ $tmaw = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['maw'];
+ $tl = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['tl'];
+
+ // Go down to lower table level
+ $this->tableLevel--;
+
+ // Reset lower level table
+ $this->base_table_properties = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['baseProperties'];
+ // mPDF 5.7.3
+ $this->default_font = $this->base_table_properties['FONT-FAMILY'];
+ $this->SetFont($this->default_font,'',0,false);
+ $this->default_font_size = $this->ConvertSize($this->base_table_properties['FONT-SIZE'])*(_MPDFK);
+ $this->SetFontSize($this->default_font_size,false);
+
+ $this->cell = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['cells'];
+ if (isset($this->cell['PARENTCELL'])) {
+ if ($this->cell['PARENTCELL']) { $this->restoreInlineProperties($this->cell['PARENTCELL']); }
+ unset($this->cell['PARENTCELL']);
+ }
+ $this->row = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currrow'];
+ $this->col = $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['currcol'];
+ $objattr = array();
+ $objattr['type'] = 'nestedtable';
+ $objattr['nestedcontent'] = $this->tbctr[($this->tableLevel+1)];
+ $objattr['table'] = $this->tbctr[$this->tableLevel];
+ $objattr['row'] = $this->row;
+ $objattr['col'] = $this->col;
+ $objattr['level'] = $this->tableLevel;
+ $e = "\xbb\xa4\xactype=nestedtable,objattr=".serialize($objattr)."\xbb\xa4\xac";
+ $this->_saveCellTextBuffer($e);
+ $this->cell[$this->row][$this->col]['s'] += $tl ;
+ if (!isset($this->cell[$this->row][$this->col]['maxs'])) {
+ $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
+ }
+ elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) {
+ $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'];
+ }
+ $this->cell[$this->row][$this->col]['s'] = 0;// reset
+ if ((isset($this->cell[$this->row][$this->col]['nestedmaw']) && $this->cell[$this->row][$this->col]['nestedmaw'] < $tmaw) || !isset($this->cell[$this->row][$this->col]['nestedmaw'])) { $this->cell[$this->row][$this->col]['nestedmaw'] = $tmaw ; }
+ if ((isset($this->cell[$this->row][$this->col]['nestedmiw']) && $this->cell[$this->row][$this->col]['nestedmiw'] < $tmiw) || !isset($this->cell[$this->row][$this->col]['nestedmiw'])) { $this->cell[$this->row][$this->col]['nestedmiw'] = $tmiw ; }
+ $this->tdbegin = true;
+ $this->nestedtablejustfinished = true;
+ $this->ignorefollowingspaces = true;
+ return;
+ }
+ $this->cMarginL = 0;
+ $this->cMarginR = 0;
+ $this->cMarginT = 0;
+ $this->cMarginB = 0;
+ $this->cellPaddingL = 0;
+ $this->cellPaddingR = 0;
+ $this->cellPaddingT = 0;
+ $this->cellPaddingB = 0;
+
+ if (isset($this->table[1][1]['overflow']) && $this->table[1][1]['overflow']=='visible') {
+ if ($this->kwt || $this->table_rotate || $this->table_keep_together || $this->ColActive) {
+ $this->kwt = false;
+ $this->table_rotate = 0;
+ $this->table_keep_together = false;
+ //die("mPDF Warning: You cannot use CSS overflow:visible together with any of these functions: 'Keep-with-table', rotated tables, page-break-inside:avoid, or columns");
+ }
+ $this->_tableColumnWidth($this->table[1][1],true);
+ $this->_tableWidth($this->table[1][1]);
+ }
+ else {
+ if (!$this->kwt_saved) { $this->kwt_height = 0; }
+
+ list($check,$tablemiw) = $this->_tableColumnWidth($this->table[1][1],true);
+ $save_table = $this->table;
+ $reset_to_minimum_width = false;
+ $added_page = false;
+
+ if ($check > 1) {
+ if ($check > $this->shrink_this_table_to_fit && $this->table_rotate) {
+ if ($this->y != $this->tMargin) {
+ $this->AddPage($this->CurOrientation);
+ $this->kwt_moved = true;
+ }
+ $added_page = true;
+ $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
+ //$check = $tablemiw/$this->tbrot_maxw; // undo any shrink
+ $check = 1; // undo any shrink
+ }
+ $reset_to_minimum_width = true;
+ }
+
+ if ($reset_to_minimum_width) {
+ $this->shrin_k = $check;
+
+ $this->default_font_size /= $this->shrin_k;
+ $this->SetFontSize($this->default_font_size, false );
+
+ $this->shrinkTable($this->table[1][1],$this->shrin_k);
+
+ $this->_tableColumnWidth($this->table[1][1],false); // repeat
+
+ // Starting at $this->innermostTableLevel
+ // Shrink table values - and redo columnWidth
+ for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
+ for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
+ $this->shrinkTable($this->table[$lvl][$nid],$this->shrin_k);
+ $this->_tableColumnWidth($this->table[$lvl][$nid],false);
+ }
+ }
+ }
+
+ // Set table cell widths for top level table
+ // Use $shrin_k to resize but don't change again
+ $this->SetLineHeight('',$this->table[1][1]['cellLineHeight']);
+
+ // Top level table
+ $this->_tableWidth($this->table[1][1]);
+
+ }
+
+ // Now work through any nested tables setting child table[w'] = parent cell['w']
+ // Now do nested tables _tableWidth
+ for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
+ for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
+ // HERE set child table width = cell width
+
+ list($parentrow, $parentcol, $parentnid) = $this->table[$lvl][$nid]['nestedpos'];
+
+ $c =& $this->table[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol];
+
+ if (isset($c['colspan']) && $c['colspan']> 1) {
+ $parentwidth = 0;
+ for($cs=0;$cs<$c['colspan'] ; $cs++) {
+ $parentwidth += $this->table[($lvl-1)][$parentnid]['wc'][$parentcol+$cs];
+ }
+ }
+ else { $parentwidth = $this->table[($lvl-1)][$parentnid]['wc'][$parentcol]; }
+
+
+ //$parentwidth -= ALLOW FOR PADDING ETC.in parent cell
+ if (!$this->simpleTables){
+ if ($this->packTableData) {
+ list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
+ }
+ else {
+ $br = $c['border_details']['R']['w'];
+ $bl = $c['border_details']['L']['w'];
+ }
+ if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
+ $parentwidth -= $br + $bl
+ + $c['padding']['L']
+ + $c['padding']['R']
+ + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
+ }
+ else {
+ $parentwidth -= $br/2 + $bl/2
+ + $c['padding']['L']
+ + $c['padding']['R'];
+ }
+ }
+ else if ($this->simpleTables){
+ if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
+ $parentwidth -= $this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']
+ + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']
+ + $c['padding']['L']
+ + $c['padding']['R']
+ + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
+ }
+ else {
+ $parentwidth -= $this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']/2
+ + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']/2
+ + $c['padding']['L']
+ + $c['padding']['R'];
+ }
+ }
+ if (isset($this->table[$lvl][$nid]['wpercent']) && $this->table[$lvl][$nid]['wpercent'] && $lvl>1) {
+ $this->table[$lvl][$nid]['w'] = $parentwidth;
+ }
+ else if ($parentwidth > $this->table[$lvl][$nid]['maw']) {
+ $this->table[$lvl][$nid]['w'] = $this->table[$lvl][$nid]['maw'];
+ }
+ else {
+ $this->table[$lvl][$nid]['w'] = $parentwidth;
+ }
+ unset($c);
+ $this->_tableWidth($this->table[$lvl][$nid]);
+ }
+ }
+
+ // Starting at $this->innermostTableLevel
+ // Cascade back up nested tables: setting heights back up the tree
+ for($lvl=$this->innermostTableLevel;$lvl>0;$lvl--) {
+ for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
+ list($tableheight,$maxrowheight,$fullpage,$remainingpage, $maxfirstrowheight) = $this->_tableHeight($this->table[$lvl][$nid]); }
+ }
+ if ($this->progressBar) { $this->UpdateProgressBar(7,20,' '); } // *PROGRESS-BAR*
+ if ($this->table[1][1]['overflow']=='visible') {
+ if ($maxrowheight > $fullpage) { die("mPDF Warning: A Table row is greater than available height. You cannot use CSS overflow:visible"); }
+ if ($maxfirstrowheight > $remainingpage) { $this->AddPage($this->CurOrientation); }
+ $r = 0; $c = 0; $p = 0; $y = 0;
+ $finished = false;
+ while (!$finished) {
+ list($finished,$r,$c,$p,$y,$y0) = $this->_tableWrite($this->table[1][1],true,$r,$c,$p,$y);
+ if (!$finished) {
+ $this->AddPage($this->CurOrientation);
+ // If printed something on first spread, set same y
+ if ($r==0 && $y0 > -1) { $this->y = $y0; }
+ }
+ }
+ }
+ else {
+ $recalculate = 1;
+ $forcerecalc = false;
+ // RESIZING ALGORITHM
+ if ($maxrowheight > $fullpage) {
+ $recalculate = $this->tbsqrt($maxrowheight / $fullpage, 1);
+ $forcerecalc = true;
+ }
+ else if ($this->table_rotate) { // NB $remainingpage == $fullpage == the width of the page
+ if ($tableheight > $remainingpage) {
+ // If can fit on remainder of page whilst respecting autsize value..
+ if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, 1)) <= $this->shrink_this_table_to_fit) {
+ $recalculate = $this->tbsqrt($tableheight / $remainingpage, 1);
+ }
+ else if (!$added_page) {
+ if ($this->y != $this->tMargin) {
+ $this->AddPage($this->CurOrientation);
+ $this->kwt_moved = true;
+ }
+ $added_page = true;
+ $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
+ // 0.001 to force it to recalculate
+ $recalculate = (1 / $this->shrin_k) + 0.001; // undo any shrink
+ }
+ }
+ else { $recalculate = 1; }
+ }
+ else if ($this->table_keep_together || ($this->table[1][1]['nr']==1 && !$this->writingHTMLfooter)) {
+ if ($tableheight > $fullpage) {
+ if (($this->shrin_k * $this->tbsqrt($tableheight / $fullpage, 1)) <= $this->shrink_this_table_to_fit) {
+ $recalculate = $this->tbsqrt($tableheight / $fullpage, 1);
+ }
+ else if ($this->tableMinSizePriority) {
+ $this->table_keep_together = false;
+ $recalculate = 1.001;
+ }
+ else {
+ if ($this->y != $this->tMargin) {
+ $this->AddPage($this->CurOrientation);
+ $this->kwt_moved = true;
+ }
+ $added_page = true;
+ $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
+ $recalculate = $this->tbsqrt($tableheight / $fullpage, 1);
+ }
+ }
+ else if ($tableheight > $remainingpage) {
+ // If can fit on remainder of page whilst respecting autsize value..
+ if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, 1)) <= $this->shrink_this_table_to_fit) {
+ $recalculate = $this->tbsqrt($tableheight / $remainingpage, 1);
+ }
+ else {
+ if ($this->y != $this->tMargin) {
+ // mPDF 6
+ if ($this->AcceptPageBreak()) { $this->AddPage($this->CurOrientation); }
+ else if ($this->ColActive && $tableheight > (($this->h-$this->bMargin)-$this->y0)) {
+ $this->AddPage($this->CurOrientation);
+ }
+ $this->kwt_moved = true;
+ }
+ $added_page = true;
+ $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
+ $recalculate = 1.001;
+ }
+ }
+ else { $recalculate = 1; }
+ }
+ else { $recalculate = 1; }
+
+ if ($recalculate > $this->shrink_this_table_to_fit && !$forcerecalc) { $recalculate = $this->shrink_this_table_to_fit; }
+
+ $iteration = 1;
+
+ // RECALCULATE
+ while($recalculate <> 1) {
+ $this->shrin_k1 = $recalculate ;
+ $this->shrin_k *= $recalculate ;
+ $this->default_font_size /= ($this->shrin_k1) ;
+ $this->SetFontSize($this->default_font_size, false );
+ $this->SetLineHeight('',$this->table[1][1]['cellLineHeight']);
+ $this->table = $save_table;
+ if ($this->shrin_k <> 1) { $this->shrinkTable($this->table[1][1],$this->shrin_k); }
+ $this->_tableColumnWidth($this->table[1][1],false); // repeat
+
+ // Starting at $this->innermostTableLevel
+ // Shrink table values - and redo columnWidth
+ for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
+ for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
+ if ($this->shrin_k <> 1) { $this->shrinkTable($this->table[$lvl][$nid],$this->shrin_k); }
+ $this->_tableColumnWidth($this->table[$lvl][$nid],false);
+ }
+ }
+ // Set table cell widths for top level table
+
+ // Top level table
+ $this->_tableWidth($this->table[1][1]);
+
+ // Now work through any nested tables setting child table[w'] = parent cell['w']
+ // Now do nested tables _tableWidth
+ for($lvl=2;$lvl<=$this->innermostTableLevel;$lvl++) {
+ for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
+ // HERE set child table width = cell width
+
+ list($parentrow, $parentcol, $parentnid) = $this->table[$lvl][$nid]['nestedpos'];
+ $c =& $this->table[($lvl-1)][$parentnid]['cells'][$parentrow][$parentcol];
+
+ if (isset($c['colspan']) && $c['colspan']> 1) {
+ $parentwidth = 0;
+ for($cs=0;$cs<$c['colspan'] ; $cs++) {
+ $parentwidth += $this->table[($lvl-1)][$parentnid]['wc'][$parentcol+$cs];
+ }
+ }
+ else { $parentwidth = $this->table[($lvl-1)][$parentnid]['wc'][$parentcol]; }
+
+ //$parentwidth -= ALLOW FOR PADDING ETC.in parent cell
+ if (!$this->simpleTables){
+ if ($this->packTableData) {
+ list($bt,$br,$bb,$bl) = $this->_getBorderWidths($c['borderbin']);
+ }
+ else {
+ $br = $c['border_details']['R']['w'];
+ $bl = $c['border_details']['L']['w'];
+ }
+ if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
+ $parentwidth -= $br + $bl
+ + $c['padding']['L']
+ + $c['padding']['R']
+ + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
+ }
+ else {
+ $parentwidth -= $br/2 + $bl/2
+ + $c['padding']['L']
+ + $c['padding']['R'];
+ }
+ }
+ else if ($this->simpleTables){
+ if ($this->table[$lvl-1][$parentnid]['borders_separate']) {
+ $parentwidth -= $this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']
+ + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']
+ + $c['padding']['L']
+ + $c['padding']['R']
+ + $this->table[($lvl-1)][$parentnid]['border_spacing_H'];
+ }
+ else {
+ $parentwidth -= ($this->table[($lvl-1)][$parentnid]['simple']['border_details']['L']['w']
+ + $this->table[($lvl-1)][$parentnid]['simple']['border_details']['R']['w']) /2
+ + $c['padding']['L']
+ + $c['padding']['R'];
+ }
+ }
+ if (isset($this->table[$lvl][$nid]['wpercent']) && $this->table[$lvl][$nid]['wpercent'] && $lvl>1) {
+ $this->table[$lvl][$nid]['w'] = $parentwidth;
+ }
+ else if ($parentwidth > $this->table[$lvl][$nid]['maw']) {
+ $this->table[$lvl][$nid]['w'] = $this->table[$lvl][$nid]['maw'] ;
+ }
+ else {
+ $this->table[$lvl][$nid]['w'] = $parentwidth;
+ }
+ unset($c);
+ $this->_tableWidth($this->table[$lvl][$nid]);
+ }
+ }
+
+ // Starting at $this->innermostTableLevel
+ // Cascade back up nested tables: setting heights back up the tree
+ for($lvl=$this->innermostTableLevel;$lvl>0;$lvl--) {
+ for ($nid=1; $nid<=$this->tbctr[$lvl]; $nid++) {
+ list($tableheight,$maxrowheight,$fullpage,$remainingpage, $maxfirstrowheight) = $this->_tableHeight($this->table[$lvl][$nid]); }
+ }
+
+ // RESIZING ALGORITHM
+
+ if ($maxrowheight > $fullpage) { $recalculate = $this->tbsqrt($maxrowheight / $fullpage, $iteration); $iteration++; }
+ else if ($this->table_rotate && $tableheight > $remainingpage && !$added_page) {
+ // If can fit on remainder of page whilst respecting autosize value..
+ if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, $iteration)) <= $this->shrink_this_table_to_fit) {
+ $recalculate = $this->tbsqrt($tableheight / $remainingpage, $iteration); $iteration++;
+ }
+ else {
+ if (!$added_page) {
+ $this->AddPage($this->CurOrientation);
+ $added_page = true;
+ $this->kwt_moved = true;
+ $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
+ }
+ // 0.001 to force it to recalculate
+ $recalculate = (1 / $this->shrin_k) + 0.001; // undo any shrink
+ }
+ }
+ else if ($this->table_keep_together || ($this->table[1][1]['nr']==1 && !$this->writingHTMLfooter)) {
+ if ($tableheight > $fullpage) {
+ if (($this->shrin_k * $this->tbsqrt($tableheight / $fullpage, $iteration)) <= $this->shrink_this_table_to_fit) {
+ $recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); $iteration++;
+ }
+ else if ($this->tableMinSizePriority) {
+ $this->table_keep_together = false;
+ $recalculate = (1 / $this->shrin_k) + 0.001;
+ }
+ else {
+ if (!$added_page && $this->y != $this->tMargin) {
+ $this->AddPage($this->CurOrientation);
+ $added_page = true;
+ $this->kwt_moved = true;
+ $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
+ }
+ $recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); $iteration++;
+ }
+ }
+ else if ($tableheight > $remainingpage) {
+ // If can fit on remainder of page whilst respecting autosize value..
+ if (($this->shrin_k * $this->tbsqrt($tableheight / $remainingpage, $iteration)) <= $this->shrink_this_table_to_fit) {
+ $recalculate = $this->tbsqrt($tableheight / $remainingpage, $iteration); $iteration++;
+ }
+ else {
+ if (!$added_page) {
+ // mPDF 6
+ if ($this->AcceptPageBreak()) { $this->AddPage($this->CurOrientation); }
+ else if ($this->ColActive && $tableheight > (($this->h-$this->bMargin)-$this->y0)) {
+ $this->AddPage($this->CurOrientation);
+ }
+ $added_page = true;
+ $this->kwt_moved = true;
+ $this->tbrot_maxw = $this->h - ($this->y + $this->bMargin + 5) - $this->kwt_height;
+ }
+
+ //$recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); $iteration++;
+ $recalculate = (1 / $this->shrin_k) + 0.001; // undo any shrink
+ }
+ }
+ else { $recalculate = 1; }
+ }
+ else { $recalculate = 1; }
+ }
+
+
+ if ($maxfirstrowheight > $remainingpage && !$added_page && !$this->table_rotate && !$this->ColActive && !$this->table_keep_together && !$this->writingHTMLheader && !$this->writingHTMLfooter) {
+ $this->AddPage($this->CurOrientation);
+ $this->kwt_moved = true;
+ }
+
+ // keep-with-table: if page has advanced, print out buffer now, else done in fn. _Tablewrite()
+ if ($this->kwt_saved && $this->kwt_moved) {
+ $this->printkwtbuffer();
+ $this->kwt_moved = false;
+ $this->kwt_saved = false;
+ }
+
+ if ($this->progressBar) { $this->UpdateProgressBar(7,30,' '); } // *PROGRESS-BAR*
+ // Recursively writes all tables starting at top level
+ $this->_tableWrite($this->table[1][1]);
+
+ if ($this->table_rotate && $this->tablebuffer) {
+ $this->PageBreakTrigger=$this->h-$this->bMargin;
+ $save_tr = $this->table_rotate;
+ $save_y = $this->y;
+ $this->table_rotate = 0;
+ $this->y = $this->tbrot_y0;
+ $h = $this->tbrot_w;
+ $this->DivLn($h,$this->blklvl,true);
+
+ $this->table_rotate = $save_tr;
+ $this->y = $save_y;
+
+ $this->printtablebuffer();
+ }
+ $this->table_rotate = 0;
+ }
+
+
+ $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'];
+
+ $this->maxPosR = max($this->maxPosR , ($this->x + $this->table[1][1]['w']));
+
+ $this->blockjustfinished=true;
+ $this->lastblockbottommargin = $this->table[1][1]['margin']['B'];
+ //Reset values
+
+ if (isset($this->table[1][1]['page_break_after'])) { $page_break_after = $this->table[1][1]['page_break_after']; }
+ else { $page_break_after = ''; }
+
+ // Keep-with-table
+ $this->kwt = false;
+ $this->kwt_y0 = 0;
+ $this->kwt_x0 = 0;
+ $this->kwt_height = 0;
+ $this->kwt_buffer = array();
+ $this->kwt_Links = array();
+ $this->kwt_Annots = array();
+ $this->kwt_moved = false;
+ $this->kwt_saved = false;
+
+ $this->kwt_Reference = array();
+ $this->kwt_BMoutlines = array();
+ $this->kwt_toc = array();
+
+ $this->shrin_k = 1;
+ $this->shrink_this_table_to_fit = 0;
+
+ unset($this->table);
+ $this->table=array(); //array
+ $this->tableLevel=0;
+ $this->tbctr=array();
+ $this->innermostTableLevel=0;
+ $this->cssmgr->tbCSSlvl = 0;
+ $this->cssmgr->tablecascadeCSS = array();
+
+ unset($this->cell);
+ $this->cell=array(); //array
+
+ $this->col=-1; //int
+ $this->row=-1; //int
+ $this->Reset();
+
+ $this->cellPaddingL = 0;
+ $this->cellPaddingT = 0;
+ $this->cellPaddingR = 0;
+ $this->cellPaddingB = 0;
+ $this->cMarginL = 0;
+ $this->cMarginT = 0;
+ $this->cMarginR = 0;
+ $this->cMarginB = 0;
+ $this->default_font_size = $this->original_default_font_size;
+ $this->default_font = $this->original_default_font;
+ $this->SetFontSize($this->default_font_size, false);
+ $this->SetFont($this->default_font,'',0,false);
+ $this->SetLineHeight();
+ if (isset($this->blk[$this->blklvl]['InlineProperties'])) { $this->restoreInlineProperties($this->blk[$this->blklvl]['InlineProperties']);}
+ if ($this->progressBar) { $this->UpdateProgressBar(7,100,' '); } // *PROGRESS-BAR*
+
+ if ($page_break_after) {
+ $save_blklvl = $this->blklvl;
+ $save_blk = $this->blk;
+ $save_silp = $this->saveInlineProperties();
+ $save_ilp = $this->InlineProperties;
+ $save_bflp = $this->InlineBDF;
+ $save_bflpc = $this->InlineBDFctr; // mPDF 6
+
+ // mPDF 6 pagebreaktype
+ $startpage = $this->page;
+ $pagebreaktype = $this->defaultPagebreakType;
+ if ($this->ColActive) { $pagebreaktype = 'cloneall'; }
+
+ // mPDF 6 pagebreaktype
+ $this->_preForcedPagebreak($pagebreaktype);
+
+ if ($page_break_after == 'RIGHT') { $this->AddPage($this->CurOrientation,'NEXT-ODD','','','','','', '','', '','','','','','',0,0,0,0); }
+ else if ($page_break_after == 'LEFT') { $this->AddPage($this->CurOrientation,'NEXT-EVEN','','','','','', '','', '','','','','','',0,0,0,0); }
+ else { $this->AddPage($this->CurOrientation,'','','','','','', '','', '','','','','','',0,0,0,0); }
+
+ // mPDF 6 pagebreaktype
+ $this->_postForcedPagebreak($pagebreaktype, $startpage, $save_blk, $save_blklvl);
+
+ $this->InlineProperties = $save_ilp;
+ $this->InlineBDF = $save_bflp;
+ $this->InlineBDFctr = $save_bflpc; // mPDF 6
+ $this->restoreInlineProperties($save_silp);
+
+ }
+ }
+/*-- END TABLES --*/
+
+}
+
+
+/*-- TABLES --*/
+// This function determines the shrink factor when resizing tables
+// val is the table_height / page_height_available
+// returns a scaling factor used as $shrin_k to resize the table
+// Overcompensating will be quicker but may unnecessarily shrink table too much
+// Undercompensating means it will reiterate more times (taking more processing time)
+function tbsqrt($val, $iteration=3) {
+ $k = 4; // Alters number of iterations until it returns $val itself - Must be > 2
+ // Probably best guess and most accurate
+ if ($iteration==1) return sqrt($val);
+ // Faster than using sqrt (because it won't undercompensate), and gives reasonable results
+ //return 1+(($val-1)/2);
+ $x = 2-(($iteration-2)/($k-2));
+ if ($x == 0) { $ret = $val+0.00001; }
+ else if ($x < 0) { $ret = 1 + ( pow(2, ($iteration-2-$k))/1000 ); }
+ else { $ret = 1+(($val-1)/$x); }
+ return $ret;
+}
+/*-- END TABLES --*/
+
+
+
+function _saveTextBuffer($t, $link = '', $intlink = '', $return=false) { // mPDF 6 Lists
+ $arr = array();
+ $arr[0] = $t;
+ if (isset($link) && $link) $arr[1] = $link;
+ $arr[2] = $this->currentfontstyle;
+ if (isset($this->colorarray) && $this->colorarray) $arr[3] = $this->colorarray;
+ $arr[4] = $this->currentfontfamily;
+ $arr[5] = $this->currentLang; // mPDF 6
+ if (isset($intlink) && $intlink) $arr[7] = $intlink;
+ // mPDF 6
+ // If Kerning set for OTL, and useOTL has positive value, but has not set for this particular script,
+ // set for kerning via kern table
+ // e.g. Latin script when useOTL set as 0x80
+ if (isset($this->OTLtags['Plus']) && strpos($this->OTLtags['Plus'],'kern')!==false && empty($this->OTLdata['GPOSinfo'])) {
+ $this->textvar = ($this->textvar | FC_KERNING);
+ }
+ $arr[8] = $this->textvar; // mPDF 5.7.1
+ if (isset($this->textparam) && $this->textparam) $arr[9] = $this->textparam;
+ if (isset($this->spanbgcolorarray) && $this->spanbgcolorarray) $arr[10] = $this->spanbgcolorarray;
+ $arr[11] = $this->currentfontsize;
+ if (isset($this->ReqFontStyle) && $this->ReqFontStyle) $arr[12] = $this->ReqFontStyle;
+ if (isset($this->lSpacingCSS) && $this->lSpacingCSS) $arr[14] = $this->lSpacingCSS;
+ if (isset($this->wSpacingCSS) && $this->wSpacingCSS) $arr[15] = $this->wSpacingCSS;
+ if (isset($this->spanborddet) && $this->spanborddet) $arr[16] = $this->spanborddet;
+ if (isset($this->textshadow) && $this->textshadow) $arr[17] = $this->textshadow;
+ if (isset($this->OTLdata) && $this->OTLdata) { $arr[18] = $this->OTLdata; $this->OTLdata = array(); } // mPDF 5.7.1
+ else { $arr[18] = NULL; }
+ // mPDF 6 Lists
+ if ($return) { return ($arr); }
+ if ($this->listitem) {
+ $this->textbuffer[] = $this->listitem;
+ $this->listitem = array();
+ }
+ $this->textbuffer[] = $arr;
+}
+
+function _saveCellTextBuffer($t, $link = '', $intlink = '') {
+ $arr = array();
+ $arr[0] = $t;
+ if (isset($link) && $link) $arr[1] = $link;
+ $arr[2] = $this->currentfontstyle;
+ if (isset($this->colorarray) && $this->colorarray) $arr[3] = $this->colorarray;
+ $arr[4] = $this->currentfontfamily;
+ if (isset($intlink) && $intlink) $arr[7] = $intlink;
+ // mPDF 6
+ // If Kerning set for OTL, and useOTL has positive value, but has not set for this particular script,
+ // set for kerning via kern table
+ // e.g. Latin script when useOTL set as 0x80
+ if (isset($this->OTLtags['Plus']) && strpos($this->OTLtags['Plus'],'kern')!==false && empty($this->OTLdata['GPOSinfo'])) {
+ $this->textvar = ($this->textvar | FC_KERNING);
+ }
+ $arr[8] = $this->textvar; // mPDF 5.7.1
+ if (isset($this->textparam) && $this->textparam) $arr[9] = $this->textparam;
+ if (isset($this->spanbgcolorarray) && $this->spanbgcolorarray) $arr[10] = $this->spanbgcolorarray;
+ $arr[11] = $this->currentfontsize;
+ if (isset($this->ReqFontStyle) && $this->ReqFontStyle) $arr[12] = $this->ReqFontStyle;
+ if (isset($this->lSpacingCSS) && $this->lSpacingCSS) $arr[14] = $this->lSpacingCSS;
+ if (isset($this->wSpacingCSS) && $this->wSpacingCSS) $arr[15] = $this->wSpacingCSS;
+ if (isset($this->spanborddet) && $this->spanborddet) $arr[16] = $this->spanborddet;
+ if (isset($this->textshadow) && $this->textshadow) $arr[17] = $this->textshadow;
+ if (isset($this->OTLdata) && $this->OTLdata) { $arr[18] = $this->OTLdata; $this->OTLdata = array(); } // mPDF 5.7.1
+ else { $arr[18] = NULL; }
+ $this->cell[$this->row][$this->col]['textbuffer'][] = $arr;
+}
+
+
+
+function printbuffer($arrayaux,$blockstate=0,$is_table=false,$table_draft=false,$cell_dir='') {
+// $blockstate = 0; // NO margins/padding
+// $blockstate = 1; // Top margins/padding only
+// $blockstate = 2; // Bottom margins/padding only
+// $blockstate = 3; // Top & bottom margins/padding
+ $this->spanbgcolorarray = '';
+ $this->spanbgcolor = false;
+ $this->spanborder = false;
+ $this->spanborddet = array();
+ $paint_ht_corr = 0;
+/*-- CSS-FLOAT --*/
+ if (count($this->floatDivs)) {
+ list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl);
+ if (($this->blk[$this->blklvl]['inner_width']-$l_width-$r_width) < (2*$this->GetCharWidth('W',false))) {
+ // Too narrow to fit - try to move down past L or R float
+ if ($l_max < $r_max && ($this->blk[$this->blklvl]['inner_width']-$r_width) > (2*$this->GetCharWidth('W',false))) {
+ $this->ClearFloats('LEFT', $this->blklvl);
+ }
+ else if ($r_max < $l_max && ($this->blk[$this->blklvl]['inner_width']-$l_width) > (2*$this->GetCharWidth('W',false))) {
+ $this->ClearFloats('RIGHT', $this->blklvl);
+ }
+ else { $this->ClearFloats('BOTH', $this->blklvl); }
+ }
+ }
+/*-- END CSS-FLOAT --*/
+ $bak_y = $this->y;
+ $bak_x = $this->x;
+ $align = '';
+ if (!$is_table) {
+ if (isset($this->blk[$this->blklvl]['align']) && $this->blk[$this->blklvl]['align']) { $align = $this->blk[$this->blklvl]['align']; }
+ // Block-align is set by e.g. <.. align="center"> Takes priority for this block but not inherited
+ if (isset($this->blk[$this->blklvl]['block-align']) && $this->blk[$this->blklvl]['block-align']) { $align = $this->blk[$this->blklvl]['block-align']; }
+ if (isset($this->blk[$this->blklvl]['direction'])) $blockdir = $this->blk[$this->blklvl]['direction'];
+ else $blockdir = "";
+ $this->divwidth = $this->blk[$this->blklvl]['width'];
+ }
+ else {
+ $align = $this->cellTextAlign;
+ $blockdir = $cell_dir;
+ }
+ $oldpage = $this->page;
+
+ // ADDED for Out of Block now done as Flowing Block
+ if ($this->divwidth == 0) {
+ $this->divwidth = $this->pgwidth;
+ }
+
+ if (!$is_table) { $this->SetLineHeight($this->FontSizePt,$this->blk[$this->blklvl]['line_height']); }
+ $this->divheight = $this->lineheight;
+ $old_height = $this->divheight;
+
+ // As a failsafe - if font has been set but not output to page
+ if (!$table_draft) $this->SetFont($this->default_font,'',$this->default_font_size,true,true); // force output to page
+
+ $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$blockstate,true,$blockdir,$table_draft);
+
+ $array_size = count($arrayaux);
+
+ // Added - Otherwise did not output top margins/padding for 1st/2nd div
+ if ($array_size == 0) { $this->finishFlowingBlock(true); } // true = END of flowing block
+
+ // mPDF 6
+ // ALL the chunks of textbuffer need to have at least basic OTLdata set
+ // First make sure each element/chunk has the OTLdata for Bidi set.
+ for($i=0;$i < $array_size; $i++) {
+ if (empty($arrayaux[$i][18])) {
+ if (substr($arrayaux[$i][0],0,3) == "\xbb\xa4\xac") { // object identifier has been identified!
+ $unicode = array(0xFFFC); // Object replacement character
+ }
+ else { $unicode = $this->UTF8StringToArray($arrayaux[$i][0], false); }
+ $is_strong = false;
+ $this->getBasicOTLdata($arrayaux[$i][18], $unicode, $is_strong);
+ }
+ // Gets messed up if try and use core fonts inside a paragraph of text which needs to be BiDi re-ordered or OTLdata set
+ if (($blockdir == 'rtl' || $this->biDirectional) && isset($arrayaux[$i][4]) && in_array($arrayaux[$i][4],array('ccourier','ctimes','chelvetica','csymbol','czapfdingbats'))) {
+ $this->Error("You cannot use core fonts in a document which contains RTL text.");
+ }
+ }
+ // mPDF 6
+ // Process bidirectional text ready for bidi-re-ordering (which is done after line-breaks are established in WriteFlowingBlock etc.)
+ if (($blockdir == 'rtl' || $this->biDirectional) && !$table_draft) {
+ if (!class_exists('otl', false)) { include(_MPDF_PATH.'classes/otl.php'); }
+ if (empty($this->otl)) { $this->otl = new otl($this); }
+ $this->otl->_bidiPrepare($arrayaux, $blockdir);
+ $array_size = count($arrayaux);
+ }
+
+
+ // Remove empty items // mPDF 6
+ for($i=$array_size-1; $i > 0; $i--) {
+ if (empty($arrayaux[$i][0]) && $arrayaux[$i][16]!=='0' && empty($arrayaux[$i][7])) {
+ unset($arrayaux[$i]);
+ }
+ }
+
+ // Correct adjoining borders for inline elements
+ if (isset($arrayaux[0][16])) { $lastspanborder = $arrayaux[0][16]; }
+ else { $lastspanborder = false; }
+ for($i=1;$i < $array_size; $i++) {
+ if (isset($arrayaux[$i][16]) && $arrayaux[$i][16]==$lastspanborder &&
+ ((!isset($arrayaux[$i][9]['bord-decoration']) && !isset($arrayaux[$i-1][9]['bord-decoration'])) ||
+ (isset($arrayaux[$i][9]['bord-decoration']) && isset($arrayaux[$i-1][9]['bord-decoration']) && $arrayaux[$i][9]['bord-decoration'] == $arrayaux[$i-1][9]['bord-decoration'])
+ )
+ ) {
+ if (isset($arrayaux[$i][16]['R'])) { $lastspanborder = $arrayaux[$i][16]; }
+ else { $lastspanborder = false; }
+ $arrayaux[$i][16]['L']['s'] = 0;
+ $arrayaux[$i][16]['L']['w'] = 0;
+ $arrayaux[$i-1][16]['R']['s'] = 0;
+ $arrayaux[$i-1][16]['R']['w'] = 0;
+ }
+ else {
+ if (isset($arrayaux[$i][16]['R'])) { $lastspanborder = $arrayaux[$i][16]; }
+ else { $lastspanborder = false; }
+ }
+ }
+
+ for($i=0;$i < $array_size; $i++)
+ {
+ // COLS
+ $oldcolumn = $this->CurrCol;
+ $vetor = $arrayaux[$i];
+ if ($i == 0 and $vetor[0] != "\n" and !$this->ispre) {
+ $vetor[0] = ltrim($vetor[0]);
+ if (!empty($vetor[18])) { $this->otl->trimOTLdata($vetor[18], true, false); } // *OTL*
+ }
+
+ // FIXED TO ALLOW IT TO SHOW '0'
+ if (empty($vetor[0]) && !($vetor[0]==='0') && empty($vetor[7])) { //Ignore empty text and not carrying an internal link
+ //Check if it is the last element. If so then finish printing the block
+ if ($i == ($array_size-1)) { $this->finishFlowingBlock(true); } // true = END of flowing block
+ continue;
+ }
+
+
+ //Activating buffer properties
+ if(isset($vetor[11]) and $vetor[11] != '') { // Font Size
+ if ($is_table && $this->shrin_k) {
+ $this->SetFontSize($vetor[11]/$this->shrin_k,false);
+ }
+ else {
+ $this->SetFontSize($vetor[11],false);
+ }
+ }
+
+ if(isset($vetor[17]) && !empty($vetor[17])) { //TextShadow
+ $this->textshadow = $vetor[17];
+ }
+ if(isset($vetor[16]) && !empty($vetor[16])) { //Border
+ $this->spanborddet = $vetor[16];
+ $this->spanborder = true;
+ }
+
+ if(isset($vetor[15])) { // Word spacing
+ $this->wSpacingCSS = $vetor[15];
+ if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
+ $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize)/$this->shrin_k; // mPDF 5.7.3
+ }
+ }
+ if(isset($vetor[14])) { // Letter spacing
+ $this->lSpacingCSS = $vetor[14];
+ if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
+ $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize)/$this->shrin_k; // mPDF 5.7.3
+ }
+ }
+
+
+ if(isset($vetor[10]) and !empty($vetor[10])) //Background color
+ {
+ $this->spanbgcolorarray = $vetor[10];
+ $this->spanbgcolor = true;
+ }
+ if(isset($vetor[9]) and !empty($vetor[9])) // Text parameters - Outline + hyphens
+ {
+ $this->textparam = $vetor[9] ;
+ $this->SetTextOutline($this->textparam);
+ // mPDF 5.7.3 inline text-decoration parameters
+ if ($is_table && $this->shrin_k) {
+ if (isset($this->textparam['text-baseline'])) { $this->textparam['text-baseline'] /= $this->shrin_k; }
+ if (isset($this->textparam['decoration-baseline'])) { $this->textparam['decoration-baseline'] /= $this->shrin_k; }
+ if (isset($this->textparam['decoration-fontsize'])) { $this->textparam['decoration-fontsize'] /= $this->shrin_k; }
+ }
+
+ }
+ if(isset($vetor[8])) // mPDF 5.7.1
+ {
+ $this->textvar = $vetor[8];
+ }
+ if(isset($vetor[7]) and $vetor[7] != '') // internal target:
+ {
+ $ily = $this->y;
+ if ($this->table_rotate) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page, "tbrot"=>true ); }
+ else if ($this->kwt) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page, "kwt"=>true ); }
+ else if ($this->ColActive) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page, "col"=>$this->CurrCol ); }
+ else if (!$this->keep_block_together) { $this->internallink[$vetor[7]] = array("Y"=>$ily,"PAGE"=>$this->page ); }
+ if (empty($vetor[0])) { //Ignore empty text
+ //Check if it is the last element. If so then finish printing the block
+ if ($i == ($array_size-1)) { $this->finishFlowingBlock(true); } // true = END of flowing block
+ continue;
+ }
+ }
+ if(isset($vetor[5]) and $vetor[5] != '') { // Language // mPDF 6
+ $this->currentLang = $vetor[5];
+ }
+ if(isset($vetor[4]) and $vetor[4] != '') { // Font Family
+ $font = $this->SetFont($vetor[4],$this->FontStyle,0,false);
+ }
+ if (!empty($vetor[3])) //Font Color
+ {
+ $cor = $vetor[3];
+ $this->SetTColor($cor);
+ }
+ if(isset($vetor[2]) and $vetor[2] != '') //Bold,Italic styles
+ {
+ $this->SetStyles($vetor[2]);
+ }
+
+ if(isset($vetor[12]) and $vetor[12] != '') { //Requested Bold,Italic
+ $this->ReqFontStyle = $vetor[12];
+ }
+ if(isset($vetor[1]) and $vetor[1] != '') //LINK
+ {
+ if (strpos($vetor[1],".") === false && strpos($vetor[1],"@") !== 0) //assuming every external link has a dot indicating extension (e.g: .html .txt .zip www.somewhere.com etc.)
+ {
+ //Repeated reference to same anchor?
+ while(array_key_exists($vetor[1],$this->internallink)) $vetor[1]="#".$vetor[1];
+ $this->internallink[$vetor[1]] = $this->AddLink();
+ $vetor[1] = $this->internallink[$vetor[1]];
+ }
+ $this->HREF = $vetor[1]; // HREF link style set here ******
+ }
+
+ // SPECIAL CONTENT - IMAGES & FORM OBJECTS
+ //Print-out special content
+
+ if (substr($vetor[0],0,3) == "\xbb\xa4\xac") { //identifier has been identified!
+
+ $objattr = $this->_getObjAttr($vetor[0]);
+
+/*-- TABLES --*/
+ if ($objattr['type'] == 'nestedtable') {
+ if ($objattr['nestedcontent']) {
+ $level = $objattr['level'];
+ $table = &$this->table[$level][$objattr['table']];
+
+ if ($table_draft) {
+ $this->y += $this->table[($level+1)][$objattr['nestedcontent']]['h']; // nested table height
+ $this->finishFlowingBlock(false,'nestedtable');
+ }
+ else {
+
+ $cell = &$table['cells'][$objattr['row']][$objattr['col']];
+ $this->finishFlowingBlock(false,'nestedtable');
+ $save_dw = $this->divwidth ;
+ $save_buffer = $this->cellBorderBuffer;
+ $this->cellBorderBuffer = array();
+ $ncx = $this->x;
+ list($dummyx,$w) = $this->_tableGetWidth($table, $objattr['row'], $objattr['col']);
+ $ntw = $this->table[($level+1)][$objattr['nestedcontent']]['w']; // nested table width
+ if (!$this->simpleTables){
+ if ($this->packTableData) {
+ list($bt,$br,$bb,$bl) = $this->_getBorderWidths($cell['borderbin']);
+ }
+ else {
+ $br = $cell['border_details']['R']['w'];
+ $bl = $cell['border_details']['L']['w'];
+ }
+ if ($table['borders_separate']) {
+ $innerw = $w - $bl - $br - $cell['padding']['L'] - $cell['padding']['R'] - $table['border_spacing_H'];
+ }
+ else {
+ $innerw = $w - $bl/2 - $br/2 - $cell['padding']['L'] - $cell['padding']['R'];
+ }
+ }
+ else if ($this->simpleTables){
+ if ($table['borders_separate']) {
+ $innerw = $w - $table['simple']['border_details']['L']['w'] - $table['simple']['border_details']['R']['w'] - $cell['padding']['L'] - $cell['padding']['R'] - $table['border_spacing_H'];
+ }
+ else {
+ $innerw = $w - $table['simple']['border_details']['L']['w']/2 - $table['simple']['border_details']['R']['w']/2 - $cell['padding']['L'] - $cell['padding']['R'];
+ }
+ }
+ if ($cell['a']=='C' || $this->table[($level+1)][$objattr['nestedcontent']]['a']=='C') {
+ $ncx += ($innerw-$ntw)/2;
+ }
+ elseif ($cell['a']=='R' || $this->table[($level+1)][$objattr['nestedcontent']]['a']=='R') {
+ $ncx += $innerw- $ntw;
+ }
+ $this->x = $ncx ;
+
+ $this->_tableWrite($this->table[($level+1)][$objattr['nestedcontent']]);
+ $this->cellBorderBuffer = $save_buffer;
+ $this->x = $bak_x ;
+ $this->divwidth = $save_dw;
+
+ }
+
+ $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$blockstate,false,$blockdir,$table_draft);
+ }
+ }
+ else {
+/*-- END TABLES --*/
+ if ($is_table) { // *TABLES*
+ $maxWidth = $this->divwidth; // *TABLES*
+ } // *TABLES*
+ else { // *TABLES*
+ $maxWidth = $this->divwidth - ($this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_right'] + $this->blk[$this->blklvl]['border_right']['w']);
+ } // *TABLES*
+
+/*-- CSS-IMAGE-FLOAT --*/
+ // If float (already) exists at this level
+ if (isset($this->floatmargins['R']) && $this->y <= $this->floatmargins['R']['y1'] && $this->y >= $this->floatmargins['R']['y0']) { $maxWidth -= $this->floatmargins['R']['w']; }
+ if (isset($this->floatmargins['L']) && $this->y <= $this->floatmargins['L']['y1'] && $this->y >= $this->floatmargins['L']['y0']) { $maxWidth -= $this->floatmargins['L']['w']; }
+/*-- END CSS-IMAGE-FLOAT --*/
+
+ list($skipln) = $this->inlineObject($objattr['type'], '', $this->y, $objattr,$this->lMargin, ($this->flowingBlockAttr['contentWidth']/_MPDFK), $maxWidth, $this->flowingBlockAttr['height'], false, $is_table);
+ // 1 -> New line needed because of width
+ // -1 -> Will fit width on line but NEW PAGE REQUIRED because of height
+ // -2 -> Will not fit on line therefore needs new line but thus NEW PAGE REQUIRED
+ $iby = $this->y;
+ $oldpage = $this->page;
+ $oldcol = $this->CurrCol;
+ if (($skipln == 1 || $skipln == -2) && !isset($objattr['float'])) {
+ $this->finishFlowingBlock(false,$objattr['type']);
+ $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$blockstate,false,$blockdir,$table_draft);
+ }
+
+ if (!$table_draft) {
+ $thispage = $this->page;
+ if ($this->CurrCol!=$oldcol) { $changedcol = true; }
+ else { $changedcol=false; }
+
+ // the previous lines can already have triggered page break or column change
+ if (!$changedcol && $skipln <0 && $this->AcceptPageBreak() && $thispage==$oldpage) {
+
+ $this->AddPage($this->CurOrientation);
+
+ // Added to correct Images already set on line before page advanced
+ // i.e. if second inline image on line is higher than first and forces new page
+ if (count($this->objectbuffer)) {
+ $yadj = $iby - $this->y;
+ foreach($this->objectbuffer AS $ib=>$val) {
+ if ($this->objectbuffer[$ib]['OUTER-Y'] ) $this->objectbuffer[$ib]['OUTER-Y'] -= $yadj;
+ if ($this->objectbuffer[$ib]['BORDER-Y']) $this->objectbuffer[$ib]['BORDER-Y'] -= $yadj;
+ if ($this->objectbuffer[$ib]['INNER-Y']) $this->objectbuffer[$ib]['INNER-Y'] -= $yadj;
+ }
+ }
+ }
+
+ // Added to correct for OddEven Margins
+ if ($this->page != $oldpage) {
+ if (($this->page-$oldpage) % 2 == 1) {
+ $bak_x += $this->MarginCorrection;
+ }
+ $oldpage = $this->page;
+ $y = $this->tMargin - $paint_ht_corr ;
+ $this->oldy = $this->tMargin - $paint_ht_corr ;
+ $old_height = 0;
+ }
+ $this->x = $bak_x;
+/*-- COLUMNS --*/
+ // COLS
+ // OR COLUMN CHANGE
+ if ($this->CurrCol != $oldcolumn) {
+ if ($this->directionality == 'rtl') { // *OTL*
+ $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *OTL*
+ } // *OTL*
+ else { // *OTL*
+ $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
+ } // *OTL*
+ $this->x = $bak_x;
+ $oldcolumn = $this->CurrCol;
+ $y = $this->y0 - $paint_ht_corr ;
+ $this->oldy = $this->y0 - $paint_ht_corr ;
+ $old_height = 0;
+ }
+/*-- END COLUMNS --*/
+
+ }
+
+/*-- CSS-IMAGE-FLOAT --*/
+ if ($objattr['type'] == 'image' && isset($objattr['float'])) {
+ $fy = $this->y;
+
+ // DIV TOP MARGIN/BORDER/PADDING
+ if ($this->flowingBlockAttr['newblock'] && ($this->flowingBlockAttr['blockstate']==1 || $this->flowingBlockAttr['blockstate']==3) && $this->flowingBlockAttr['lineCount']== 0) {
+ $fy += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w'];
+ }
+
+ if ($objattr['float']=='R') {
+ $fx = $this->w - $this->rMargin - $objattr['width'] - ($this->blk[$this->blklvl]['outer_right_margin'] + $this->blk[$this->blklvl]['border_right']['w'] + $this->blk[$this->blklvl]['padding_right']);
+
+
+ }
+ else if ($objattr['float']=='L') {
+ $fx = $this->lMargin + ($this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_left']);
+ }
+ $w = $objattr['width'];
+ $h = abs($objattr['height']);
+
+ $widthLeft = $maxWidth - ($this->flowingBlockAttr['contentWidth']/_MPDFK);
+ $maxHeight = $this->h - ($this->tMargin + $this->margin_header + $this->bMargin + 10) ;
+ // For Images
+ $extraWidth = ($objattr['border_left']['w'] + $objattr['border_right']['w'] + $objattr['margin_left']+ $objattr['margin_right']);
+ $extraHeight = ($objattr['border_top']['w'] + $objattr['border_bottom']['w'] + $objattr['margin_top']+ $objattr['margin_bottom']);
+
+ if ($objattr['itype'] == 'wmf' || $objattr['itype'] == 'svg') {
+ $file = $objattr['file'];
+ $info=$this->formobjects[$file];
+ }
+ else {
+ $file = $objattr['file'];
+ $info=$this->images[$file];
+ }
+ $img_w = $w - $extraWidth ;
+ $img_h = $h - $extraHeight ;
+ if ($objattr['border_left']['w']) {
+ $objattr['BORDER-WIDTH'] = $img_w + (($objattr['border_left']['w'] + $objattr['border_right']['w'])/2) ;
+ $objattr['BORDER-HEIGHT'] = $img_h + (($objattr['border_top']['w'] + $objattr['border_bottom']['w'])/2) ;
+ $objattr['BORDER-X'] = $fx + $objattr['margin_left'] + (($objattr['border_left']['w'])/2) ;
+ $objattr['BORDER-Y'] = $fy + $objattr['margin_top'] + (($objattr['border_top']['w'])/2) ;
+ }
+ $objattr['INNER-WIDTH'] = $img_w;
+ $objattr['INNER-HEIGHT'] = $img_h;
+ $objattr['INNER-X'] = $fx + $objattr['margin_left'] + ($objattr['border_left']['w']);
+ $objattr['INNER-Y'] = $fy + $objattr['margin_top'] + ($objattr['border_top']['w']) ;
+ $objattr['ID'] = $info['i'];
+ $objattr['OUTER-WIDTH'] = $w;
+ $objattr['OUTER-HEIGHT'] = $h;
+ $objattr['OUTER-X'] = $fx;
+ $objattr['OUTER-Y'] = $fy;
+ if ($objattr['float']=='R') {
+ // If R float already exists at this level
+ $this->floatmargins['R']['skipline'] = false;
+ if (isset($this->floatmargins['R']['y1']) && $this->floatmargins['R']['y1'] > 0 && $fy < $this->floatmargins['R']['y1']) {
+ $this->WriteFlowingBlock($vetor[0],$vetor[18]); // mPDF 5.7.1
+ }
+ // If L float already exists at this level
+ else if (isset($this->floatmargins['L']['y1']) && $this->floatmargins['L']['y1'] > 0 && $fy < $this->floatmargins['L']['y1']) {
+ // Final check distance between floats is not now too narrow to fit text
+ $mw = 2*$this->GetCharWidth('W',false);
+ if (($this->blk[$this->blklvl]['inner_width'] - $w - $this->floatmargins['L']['w']) < $mw) {
+ $this->WriteFlowingBlock($vetor[0],$vetor[18]); // mPDF 5.7.1
+ }
+ else {
+ $this->floatmargins['R']['x'] = $fx;
+ $this->floatmargins['R']['w'] = $w;
+ $this->floatmargins['R']['y0'] = $fy;
+ $this->floatmargins['R']['y1'] = $fy + $h;
+ if ($skipln == 1) {
+ $this->floatmargins['R']['skipline'] = true;
+ $this->floatmargins['R']['id'] = count($this->floatbuffer)+0;
+ $objattr['skipline'] = true;
+ }
+ $this->floatbuffer[] = $objattr;
+ }
+ }
+ else {
+ $this->floatmargins['R']['x'] = $fx;
+ $this->floatmargins['R']['w'] = $w;
+ $this->floatmargins['R']['y0'] = $fy;
+ $this->floatmargins['R']['y1'] = $fy + $h;
+ if ($skipln == 1) {
+ $this->floatmargins['R']['skipline'] = true;
+ $this->floatmargins['R']['id'] = count($this->floatbuffer)+0;
+ $objattr['skipline'] = true;
+ }
+ $this->floatbuffer[] = $objattr;
+ }
+ }
+ else if ($objattr['float']=='L') {
+ // If L float already exists at this level
+ $this->floatmargins['L']['skipline'] = false;
+ if (isset($this->floatmargins['L']['y1']) && $this->floatmargins['L']['y1'] > 0 && $fy < $this->floatmargins['L']['y1']) {
+ $this->floatmargins['L']['skipline'] = false;
+ $this->WriteFlowingBlock($vetor[0],$vetor[18]); // mPDF 5.7.1
+ }
+ // If R float already exists at this level
+ else if (isset($this->floatmargins['R']['y1']) && $this->floatmargins['R']['y1'] > 0 && $fy < $this->floatmargins['R']['y1']) {
+ // Final check distance between floats is not now too narrow to fit text
+ $mw = 2*$this->GetCharWidth('W',false);
+ if (($this->blk[$this->blklvl]['inner_width'] - $w - $this->floatmargins['R']['w']) < $mw) {
+ $this->WriteFlowingBlock($vetor[0],$vetor[18]); // mPDF 5.7.1
+ }
+ else {
+ $this->floatmargins['L']['x'] = $fx + $w;
+ $this->floatmargins['L']['w'] = $w;
+ $this->floatmargins['L']['y0'] = $fy;
+ $this->floatmargins['L']['y1'] = $fy + $h;
+ if ($skipln == 1) {
+ $this->floatmargins['L']['skipline'] = true;
+ $this->floatmargins['L']['id'] = count($this->floatbuffer)+0;
+ $objattr['skipline'] = true;
+ }
+ $this->floatbuffer[] = $objattr;
+ }
+ }
+ else {
+ $this->floatmargins['L']['x'] = $fx + $w;
+ $this->floatmargins['L']['w'] = $w;
+ $this->floatmargins['L']['y0'] = $fy;
+ $this->floatmargins['L']['y1'] = $fy + $h;
+ if ($skipln == 1) {
+ $this->floatmargins['L']['skipline'] = true;
+ $this->floatmargins['L']['id'] = count($this->floatbuffer)+0;
+ $objattr['skipline'] = true;
+ }
+ $this->floatbuffer[] = $objattr;
+ }
+ }
+ }
+ else {
+/*-- END CSS-IMAGE-FLOAT --*/
+ $this->WriteFlowingBlock($vetor[0],(isset($vetor[18]) ? $vetor[18] : NULL)); // mPDF 5.7.1
+/*-- CSS-IMAGE-FLOAT --*/
+ }
+/*-- END CSS-IMAGE-FLOAT --*/
+ } // *TABLES*
+
+ } // END If special content
+ else { //THE text
+ if ($this->tableLevel) { $paint_ht_corr = 0; } // To move the y up when new column/page started if div border needed
+ else { $paint_ht_corr = $this->blk[$this->blklvl]['border_top']['w']; }
+
+ if ($vetor[0] == "\n") { //We are reading a now turned into newline ("\n")
+ if ($this->flowingBlockAttr['content']) {
+ $this->finishFlowingBlock(false,'br');
+ }
+ else if ($is_table) {
+ $this->y+= $this->_computeLineheight($this->cellLineHeight);
+ }
+ else if (!$is_table) {
+ $this->DivLn($this->lineheight);
+ if ($this->ColActive) { $this->breakpoints[$this->CurrCol][] = $this->y; } // *COLUMNS*
+ }
+ // Added to correct for OddEven Margins
+ if ($this->page != $oldpage) {
+ if (($this->page-$oldpage) % 2 == 1) {
+ $bak_x += $this->MarginCorrection;
+ }
+ $oldpage = $this->page;
+ $y = $this->tMargin - $paint_ht_corr ;
+ $this->oldy = $this->tMargin - $paint_ht_corr ;
+ $old_height = 0;
+ }
+ $this->x = $bak_x;
+/*-- COLUMNS --*/
+ // COLS
+ // OR COLUMN CHANGE
+ if ($this->CurrCol != $oldcolumn) {
+ if ($this->directionality == 'rtl') { // *OTL*
+ $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *OTL*
+ } // *OTL*
+ else { // *OTL*
+ $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
+ } // *OTL*
+ $this->x = $bak_x;
+ $oldcolumn = $this->CurrCol;
+ $y = $this->y0 - $paint_ht_corr ;
+ $this->oldy = $this->y0 - $paint_ht_corr ;
+ $old_height = 0;
+ }
+/*-- END COLUMNS --*/
+ $this->newFlowingBlock( $this->divwidth,$this->divheight,$align,$is_table,$blockstate,false,$blockdir,$table_draft);
+ }
+ else {
+ $this->WriteFlowingBlock($vetor[0],$vetor[18]); // mPDF 5.7.1
+
+ // Added to correct for OddEven Margins
+ if ($this->page != $oldpage) {
+ if (($this->page-$oldpage) % 2 == 1) {
+ $bak_x += $this->MarginCorrection;
+ $this->x = $bak_x;
+ }
+ $oldpage = $this->page;
+ $y = $this->tMargin - $paint_ht_corr ;
+ $this->oldy = $this->tMargin - $paint_ht_corr ;
+ $old_height = 0;
+ }
+/*-- COLUMNS --*/
+ // COLS
+ // OR COLUMN CHANGE
+ if ($this->CurrCol != $oldcolumn) {
+ if ($this->directionality == 'rtl') { // *OTL*
+ $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *OTL*
+ } // *OTL*
+ else { // *OTL*
+ $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
+ } // *OTL*
+ $this->x = $bak_x;
+ $oldcolumn = $this->CurrCol;
+ $y = $this->y0 - $paint_ht_corr ;
+ $this->oldy = $this->y0 - $paint_ht_corr ;
+ $old_height = 0;
+ }
+/*-- END COLUMNS --*/
+ }
+
+
+ }
+
+ //Check if it is the last element. If so then finish printing the block
+ if ($i == ($array_size-1)) {
+ $this->finishFlowingBlock(true); // true = END of flowing block
+ // Added to correct for OddEven Margins
+ if ($this->page != $oldpage) {
+ if (($this->page-$oldpage) % 2 == 1) {
+ $bak_x += $this->MarginCorrection;
+ $this->x = $bak_x;
+ }
+ $oldpage = $this->page;
+ $y = $this->tMargin - $paint_ht_corr ;
+ $this->oldy = $this->tMargin - $paint_ht_corr ;
+ $old_height = 0;
+ }
+
+/*-- COLUMNS --*/
+ // COLS
+ // OR COLUMN CHANGE
+ if ($this->CurrCol != $oldcolumn) {
+ if ($this->directionality == 'rtl') { // *OTL*
+ $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap); // *OTL*
+ } // *OTL*
+ else { // *OTL*
+ $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth+$this->ColGap);
+ } // *OTL*
+ $this->x = $bak_x;
+ $oldcolumn = $this->CurrCol;
+ $y = $this->y0 - $paint_ht_corr ;
+ $this->oldy = $this->y0 - $paint_ht_corr ;
+ $old_height = 0;
+ }
+/*-- END COLUMNS --*/
+
+ }
+
+ // RESETTING VALUES
+ $this->SetTColor($this->ConvertColor(0));
+ $this->SetDColor($this->ConvertColor(0));
+ $this->SetFColor($this->ConvertColor(255));
+ $this->colorarray = '';
+ $this->spanbgcolorarray = '';
+ $this->spanbgcolor = false;
+ $this->spanborder = false;
+ $this->spanborddet = array();
+ $this->HREF = '';
+ $this->textparam = array();
+ $this->SetTextOutline();
+
+ $this->textvar = 0x00; // mPDF 5.7.1
+ $this->OTLtags = array();
+ $this->textshadow = '';
+
+ $this->currentfontfamily = '';
+ $this->currentfontsize = '';
+ $this->currentfontstyle = '';
+ $this->currentLang = $this->default_lang; // mPDF 6
+ $this->RestrictUnicodeFonts($this->default_available_fonts ); // mPDF 6
+/*-- TABLES --*/
+ if ($this->tableLevel) {
+ $this->SetLineHeight('',$this->table[1][1]['cellLineHeight']); // *TABLES*
+ }
+ else
+/*-- END TABLES --*/
+ if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
+ $this->SetLineHeight('',$this->blk[$this->blklvl]['line_height']); // sets default line height
+ }
+ $this->ResetStyles();
+ $this->lSpacingCSS = '';
+ $this->wSpacingCSS = '';
+ $this->fixedlSpacing = false;
+ $this->minwSpacing = 0;
+ $this->SetDash();
+ $this->dash_on = false;
+ $this->dotted_on = false;
+
+ }//end of for(i=0;iReset(); // mPDF 6
+
+ // PAINT DIV BORDER // DISABLED IN COLUMNS AS DOESN'T WORK WHEN BROKEN ACROSS COLS??
+ if ((isset($this->blk[$this->blklvl]['border']) || isset($this->blk[$this->blklvl]['bgcolor']) || isset($this->blk[$this->blklvl]['box_shadow'])) && $blockstate && ($this->y != $this->oldy)) {
+ $bottom_y = $this->y; // Does not include Bottom Margin
+ if (isset($this->blk[$this->blklvl]['startpage']) && $this->blk[$this->blklvl]['startpage'] != $this->page && $blockstate != 1) {
+ $this->PaintDivBB('pagetop',$blockstate);
+ }
+
+ else if ($blockstate != 1) {
+ $this->PaintDivBB('',$blockstate);
+ }
+ $this->y = $bottom_y;
+ $this->x = $bak_x;
+ }
+
+ // Reset Font
+ $this->SetFontSize($this->default_font_size,false);
+ if ($table_draft) {
+ $ch = $this->y - $bak_y;
+ $this->y = $bak_y;
+ $this->x = $bak_x;
+ return $ch;
+ }
+
+}
+
+function _setDashBorder($style, $div, $cp, $side) {
+ if ($style == 'dashed' && (($side=='L' || $side=='R') || ($side=='T' && $div != 'pagetop' && !$cp) || ($side=='B' && $div!='pagebottom') )) {
+ $dashsize = 2; // final dash will be this + 1*linewidth
+ $dashsizek = 1.5; // ratio of Dash/Blank
+ $this->SetDash($dashsize,($dashsize/$dashsizek)+($this->LineWidth*2));
+ }
+ else if ($style == 'dotted' || ($side=='T' && ($div == 'pagetop' || $cp)) || ($side=='B' && $div == 'pagebottom')) {
+ //Round join and cap
+ $this->SetLineJoin(1);
+ $this->SetLineCap(1);
+ $this->SetDash(0.001,($this->LineWidth*3));
+ }
+}
+
+function _setBorderLine($b, $k=1) {
+ $this->SetLineWidth($b['w']/$k);
+ $this->SetDColor($b['c']);
+ if ($b['c'][0]==5) { // RGBa
+ $this->SetAlpha(ord($b['c'][4])/100, 'Normal', false, 'S')."\n"; // mPDF 5.7.2
+ }
+ else if ($b['c'][0]==6) { // CMYKa
+ $this->SetAlpha(ord($b['c'][5])/100, 'Normal', false, 'S')."\n"; // mPDF 5.7.2
+ }
+}
+
+function PaintDivBB($divider='',$blockstate=0,$blvl=0) {
+ // Borders & backgrounds are done elsewhere for columns - messes up the repositioning in printcolumnbuffer
+ if ($this->ColActive) { return ; } // *COLUMNS*
+ if ($this->keep_block_together ) { return ; } // mPDF 6
+ $save_y = $this->y;
+ if (!$blvl) { $blvl = $this->blklvl; }
+ $x0 = $x1 = $y0 = $y1 = 0;
+
+ // Added mPDF 3.0 Float DIV
+ if (isset($this->blk[$blvl]['bb_painted'][$this->page]) && $this->blk[$blvl]['bb_painted'][$this->page]) { return; } // *CSS-FLOAT*
+
+ if (isset($this->blk[$blvl]['x0'])) { $x0 = $this->blk[$blvl]['x0']; } // left
+ if (isset($this->blk[$blvl]['y1'])) { $y1 = $this->blk[$blvl]['y1']; } // bottom
+
+ // Added mPDF 3.0 Float DIV - ensures backgrounds/borders are drawn to bottom of page
+ if ($y1==0) {
+ if ($divider=='pagebottom') { $y1 = $this->h-$this->bMargin; }
+ else { $y1 = $this->y; }
+ }
+
+ if (isset($this->blk[$blvl]['startpage']) && $this->blk[$blvl]['startpage'] != $this->page) { $continuingpage = true; } else { $continuingpage = false; }
+
+ if (isset($this->blk[$blvl]['y0'])) { $y0 = $this->blk[$blvl]['y0']; }
+ $h = $y1 - $y0;
+ $w = $this->blk[$blvl]['width'];
+ $x1 = $x0 + $w;
+
+ // Set border-widths as used here
+ $border_top = $this->blk[$blvl]['border_top']['w'];
+ $border_bottom = $this->blk[$blvl]['border_bottom']['w'];
+ $border_left = $this->blk[$blvl]['border_left']['w'];
+ $border_right = $this->blk[$blvl]['border_right']['w'];
+ if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage) {
+ $border_top = 0;
+ }
+ if (!$this->blk[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom') {
+ $border_bottom = 0;
+ }
+
+ $brTL_H = 0;
+ $brTL_V = 0;
+ $brTR_H = 0;
+ $brTR_V = 0;
+ $brBL_H = 0;
+ $brBL_V = 0;
+ $brBR_H = 0;
+ $brBR_V = 0;
+
+ $brset = false;
+/*-- BORDER-RADIUS --*/
+ if (isset($this->blk[$blvl]['border_radius_TL_H'])) { $brTL_H = $this->blk[$blvl]['border_radius_TL_H']; $brset = true; }
+ if (isset($this->blk[$blvl]['border_radius_TL_V'])) { $brTL_V = $this->blk[$blvl]['border_radius_TL_V']; $brset = true; }
+ if (isset($this->blk[$blvl]['border_radius_TR_H'])) { $brTR_H = $this->blk[$blvl]['border_radius_TR_H']; $brset = true; }
+ if (isset($this->blk[$blvl]['border_radius_TR_V'])) { $brTR_V = $this->blk[$blvl]['border_radius_TR_V']; $brset = true; }
+ if (isset($this->blk[$blvl]['border_radius_BR_H'])) { $brBR_H = $this->blk[$blvl]['border_radius_BR_H']; $brset = true; }
+ if (isset($this->blk[$blvl]['border_radius_BR_V'])) { $brBR_V = $this->blk[$blvl]['border_radius_BR_V']; $brset = true; }
+ if (isset($this->blk[$blvl]['border_radius_BL_H'])) { $brBL_H = $this->blk[$blvl]['border_radius_BL_H']; $brset = true; }
+ if (isset($this->blk[$blvl]['border_radius_BL_V'])) { $brBL_V = $this->blk[$blvl]['border_radius_BL_V']; $brset = true; }
+
+ if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage) {
+ $brTL_H = 0;
+ $brTL_V = 0;
+ $brTR_H = 0;
+ $brTR_V = 0;
+ }
+ if (!$this->blk[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom') {
+ $brBL_H = 0;
+ $brBL_V = 0;
+ $brBR_H = 0;
+ $brBR_V = 0;
+ }
+
+ // Disallow border-radius if it is smaller than the border width.
+ if ($brTL_H < min($border_left, $border_top)) { $brTL_H = $brTL_V = 0; }
+ if ($brTL_V < min($border_left, $border_top)) { $brTL_V = $brTL_H = 0; }
+ if ($brTR_H < min($border_right, $border_top)) { $brTR_H = $brTR_V = 0; }
+ if ($brTR_V < min($border_right, $border_top)) { $brTR_V = $brTR_H = 0; }
+ if ($brBL_H < min($border_left, $border_bottom)) { $brBL_H = $brBL_V = 0; }
+ if ($brBL_V < min($border_left, $border_bottom)) { $brBL_V = $brBL_H = 0; }
+ if ($brBR_H < min($border_right, $border_bottom)) { $brBR_H = $brBR_V = 0; }
+ if ($brBR_V < min($border_right, $border_bottom)) { $brBR_V = $brBR_H = 0; }
+
+ // CHECK FOR radii that sum to > width or height of div ********
+ $f = min($h/($brTL_V + $brBL_V + 0.001), $h/($brTR_V + $brBR_V + 0.001), $w/($brTL_H + $brTR_H + 0.001), $w/($brBL_H + $brBR_H + 0.001));
+ if ($f < 1) {
+ $brTL_H *= $f;
+ $brTL_V *= $f;
+ $brTR_H *= $f;
+ $brTR_V *= $f;
+ $brBL_H *= $f;
+ $brBL_V *= $f;
+ $brBR_H *= $f;
+ $brBR_V *= $f;
+ }
+/*-- END BORDER-RADIUS --*/
+
+ $tbcol = $this->ConvertColor(255);
+ for($l=0; $l <= $blvl; $l++) {
+ if ($this->blk[$l]['bgcolor']) {
+ $tbcol = $this->blk[$l]['bgcolorarray'];
+ }
+ }
+
+ // BORDERS
+ if (isset($this->blk[$blvl]['y0']) && $this->blk[$blvl]['y0']) { $y0 = $this->blk[$blvl]['y0']; }
+ $h = $y1 - $y0;
+ $w = $this->blk[$blvl]['width'];
+
+ if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
+ $tbd = $this->blk[$blvl]['border_top'];
+
+ $legend = '';
+ $legbreakL = 0;
+ $legbreakR = 0;
+ // BORDER LEGEND
+ if (isset($this->blk[$blvl]['border_legend']) && $this->blk[$blvl]['border_legend']) {
+ $legend = $this->blk[$blvl]['border_legend']; // Same structure array as textbuffer
+ $txt = $legend[0] = ltrim($legend[0]);
+ if (!empty($legend[18])) { $this->otl->trimOTLdata($legend[18], true, false); } // *OTL*
+
+ //Set font, size, style, color
+ $this->SetFont($legend[4],$legend[2],$legend[11]);
+ if (isset($legend[3]) && $legend[3]) {
+ $cor = $legend[3];
+ $this->SetTColor($cor);
+
+ }
+ $stringWidth = $this->GetStringWidth($txt, true, $legend[18], $legend[8]);
+ $save_x = $this->x;
+ $save_y = $this->y;
+ $save_currentfontfamily = $this->FontFamily;
+ $save_currentfontsize = $this->FontSizePt;
+ $save_currentfontstyle = $this->FontStyle;
+ $this->y = $y0 - $this->FontSize/2 + $this->blk[$blvl]['border_top']['w']/2;
+ $this->x = $x0 + $this->blk[$blvl]['padding_left'] + $this->blk[$blvl]['border_left']['w'];
+
+ // Set the distance from the border line to the text ? make configurable variable
+ $gap = 0.2 * $this->FontSize;
+ $legbreakL = $this->x - $gap;
+ $legbreakR = $this->x + $stringWidth + $gap;
+ $this->magic_reverse_dir($txt, $this->blk[$blvl]['direction'], $legend[18]);
+ $fill = '';
+ $this->Cell( $stringWidth, $this->FontSize, $txt , '', 0, 'C', $fill, '', 0, 0,0,'M', $fill, false, $legend[18], $legend[8]);
+ // Reset
+ $this->x = $save_x;
+ $this->y = $save_y;
+ $this->SetFont($save_currentfontfamily,$save_currentfontstyle,$save_currentfontsize);
+ $this->SetTColor($this->ConvertColor(0));
+ }
+
+ if (isset($tbd['s']) && $tbd['s']) {
+ if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
+ $this->_out('q');
+ $this->SetLineWidth(0);
+ $this->_out(sprintf('%.3F %.3F m ',($x0)*_MPDFK, ($this->h-($y0))*_MPDFK));
+ $this->_out(sprintf('%.3F %.3F l ',($x0 + $border_left)*_MPDFK, ($this->h-($y0 + $border_top))*_MPDFK));
+ $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - $border_right)*_MPDFK, ($this->h-($y0 + $border_top))*_MPDFK));
+ $this->_out(sprintf('%.3F %.3F l ',($x0 + $w)*_MPDFK, ($this->h-($y0))*_MPDFK));
+ $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
+ }
+
+ $this->_setBorderLine($tbd);
+ if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
+ $legbreakL -= $border_top/2; // because line cap different
+ $legbreakR += $border_top/2;
+ $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'T');
+ }
+/*-- BORDER-RADIUS --*/
+ else if (($brTL_V && $brTL_H) || ($brTR_V && $brTR_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) {
+ $this->SetLineJoin(0);
+ $this->SetLineCap(0);
+ }
+ $s = '';
+ if ($brTR_H && $brTR_V) {
+ $s .= ($this->_EllipseArc($x0 + $w - $brTR_H, $y0 + $brTR_V, $brTR_H - $border_top/2 , $brTR_V - $border_top/2 , 1, 2, true))."\n";
+ }
+ else
+/*-- END BORDER-RADIUS --*/
+ if ($tbd['style']=='solid' || $tbd['style']=='double') {
+ $s .= (sprintf('%.3F %.3F m ',($x0 + $w)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
+ }
+ else {
+ $s .= (sprintf('%.3F %.3F m ',($x0 + $w - ($border_top/2))*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
+ }
+/*-- BORDER-RADIUS --*/
+ if ($brTL_H && $brTL_V ) {
+ if ($legend) {
+ if ($legbreakR < ($x0 + $w - $brTR_H)) {
+ $s .= (sprintf('%.3F %.3F l ', $legbreakR*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
+ }
+ if ($legbreakL > ($x0 + $brTL_H )) {
+ $s .= (sprintf('%.3F %.3F m ',$legbreakL*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
+ $s .= (sprintf('%.3F %.3F l ',($x0 + $brTL_H )*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK)."\n");
+ }
+ else {
+ $s .= (sprintf('%.3F %.3F m ',($x0 + $brTL_H )*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
+ }
+ }
+ else {
+ $s .= (sprintf('%.3F %.3F l ',($x0 + $brTL_H )*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
+ }
+ $s .= ($this->_EllipseArc($x0 + $brTL_H, $y0 + $brTL_V, $brTL_H - $border_top/2 , $brTL_V - $border_top/2 , 2, 1))."\n";
+ }
+ else {
+/*-- END BORDER-RADIUS --*/
+ if ($legend) {
+ if ($legbreakR < ($x0 + $w)) {
+ $s .= (sprintf('%.3F %.3F l ',$legbreakR*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
+ }
+ if ($legbreakL > ($x0)) {
+ $s .= (sprintf('%.3F %.3F m ',$legbreakL*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
+ if ($tbd['style']=='solid' || $tbd['style']=='double') {
+ $s .= (sprintf('%.3F %.3F l ',($x0)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
+ }
+ else {
+ $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_top/2))*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
+ }
+ }
+ else if ($tbd['style']=='solid' || $tbd['style']=='double') {
+ $s .= (sprintf('%.3F %.3F m ', ($x0)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
+ }
+ else {
+ $s .= (sprintf('%.3F %.3F m ', ($x0 + $border_top/2)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
+ }
+ }
+ else if ($tbd['style']=='solid' || $tbd['style']=='double') {
+ $s .= (sprintf('%.3F %.3F l ',($x0)*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
+ }
+ else {
+ $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_top/2))*_MPDFK, ($this->h-($y0 + ($border_top/2)))*_MPDFK))."\n";
+ }
+/*-- BORDER-RADIUS --*/
+ }
+/*-- END BORDER-RADIUS --*/
+ $s .= 'S'."\n";
+ $this->_out($s);
+
+ if ($tbd['style']=='double') {
+ $this->SetLineWidth($tbd['w']/3);
+ $this->SetDColor($tbcol);
+ $this->_out($s);
+ }
+ if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this->_out('Q'); }
+
+ // Reset Corners and Dash off
+ $this->SetLineWidth(0.1);
+ $this->SetDColor($this->ConvertColor(0));
+ $this->SetLineJoin(2);
+ $this->SetLineCap(2);
+ $this->SetDash();
+ }
+ }
+ // Reinstate line above for dotted line divider when block border crosses a page
+ //else if ($divider == 'pagetop' || $continuingpage) {
+
+ if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
+ $tbd = $this->blk[$blvl]['border_bottom'];
+ if (isset($tbd['s']) && $tbd['s']) {
+ if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
+ $this->_out('q');
+ $this->SetLineWidth(0);
+ $this->_out(sprintf('%.3F %.3F m ',($x0)*_MPDFK, ($this->h-($y0 + $h))*_MPDFK));
+ $this->_out(sprintf('%.3F %.3F l ',($x0 + $border_left)*_MPDFK, ($this->h-($y0 + $h - $border_bottom))*_MPDFK));
+ $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - $border_right)*_MPDFK, ($this->h-($y0 + $h - $border_bottom))*_MPDFK));
+ $this->_out(sprintf('%.3F %.3F l ',($x0 + $w)*_MPDFK, ($this->h-($y0 + $h))*_MPDFK));
+ $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
+ }
+
+ $this->_setBorderLine($tbd);
+ if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'B'); }
+/*-- BORDER-RADIUS --*/
+ else if (($brBL_V && $brBL_H) || ($brBR_V && $brBR_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) {
+ $this->SetLineJoin(0);
+ $this->SetLineCap(0);
+ }
+ $s = '';
+ if ($brBL_H && $brBL_V) {
+ $s .= ($this->_EllipseArc($x0 + $brBL_H, $y0 + $h - $brBL_V, $brBL_H - $border_bottom/2 , $brBL_V - $border_bottom/2 , 3, 2, true))."\n";
+ }
+ else
+/*-- END BORDER-RADIUS --*/
+ if ($tbd['style']=='solid' || $tbd['style']=='double') {
+ $s .= (sprintf('%.3F %.3F m ',($x0)*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
+ }
+ else {
+ $s .= (sprintf('%.3F %.3F m ',($x0 + ($border_bottom/2))*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
+ }
+/*-- BORDER-RADIUS --*/
+ if ($brBR_H && $brBR_V ) {
+ $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_bottom/2) - $brBR_H )*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
+ $s .= ($this->_EllipseArc($x0 + $w - $brBR_H, $y0 + $h - $brBR_V, $brBR_H - $border_bottom/2 , $brBR_V - $border_bottom/2 , 4, 1))."\n";
+ }
+ else
+/*-- END BORDER-RADIUS --*/
+ if ($tbd['style']=='solid' || $tbd['style']=='double') {
+ $s .= (sprintf('%.3F %.3F l ',($x0 + $w)*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
+ }
+ else {
+ $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_bottom/2))*_MPDFK, ($this->h-($y0 + $h - ($border_bottom/2)))*_MPDFK))."\n";
+ }
+ $s .= 'S'."\n";
+ $this->_out($s);
+
+ if ($tbd['style']=='double') {
+ $this->SetLineWidth($tbd['w']/3);
+ $this->SetDColor($tbcol);
+ $this->_out($s);
+ }
+ if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this->_out('Q'); }
+
+
+ // Reset Corners and Dash off
+ $this->SetLineWidth(0.1);
+ $this->SetDColor($this->ConvertColor(0));
+ $this->SetLineJoin(2);
+ $this->SetLineCap(2);
+ $this->SetDash();
+ }
+ }
+ // Reinstate line below for dotted line divider when block border crosses a page
+ //else if ($blockstate == 1 || $divider == 'pagebottom') {
+
+ if ($this->blk[$blvl]['border_left']) {
+ $tbd = $this->blk[$blvl]['border_left'];
+ if (isset($tbd['s']) && $tbd['s']) {
+ if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
+ $this->_out('q');
+ $this->SetLineWidth(0);
+ $this->_out(sprintf('%.3F %.3F m ',($x0)*_MPDFK, ($this->h-($y0))*_MPDFK));
+ $this->_out(sprintf('%.3F %.3F l ',($x0 + $border_left)*_MPDFK, ($this->h-($y0+$border_top))*_MPDFK));
+ $this->_out(sprintf('%.3F %.3F l ',($x0 + $border_left)*_MPDFK, ($this->h-($y0 + $h - $border_bottom))*_MPDFK));
+ $this->_out(sprintf('%.3F %.3F l ',($x0)*_MPDFK, ($this->h-($y0 + $h))*_MPDFK));
+ $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
+ }
+
+ $this->_setBorderLine($tbd);
+ if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'L'); }
+/*-- BORDER-RADIUS --*/
+ else if (($brTL_V && $brTL_H) || ($brBL_V && $brBL_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) {
+ $this->SetLineJoin(0);
+ $this->SetLineCap(0);
+ }
+ $s = '';
+ if ($brTL_V && $brTL_H) {
+ $s .= ($this->_EllipseArc($x0 + $brTL_H, $y0 + $brTL_V, $brTL_H - $border_left/2 , $brTL_V - $border_left/2, 2, 2, true))."\n";
+ }
+ else
+/*-- END BORDER-RADIUS --*/
+ if ($tbd['style']=='solid' || $tbd['style']=='double') {
+ $s .= (sprintf('%.3F %.3F m ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0))*_MPDFK))."\n";
+ }
+ else {
+ $s .= (sprintf('%.3F %.3F m ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + ($border_left/2)))*_MPDFK))."\n";
+ }
+/*-- BORDER-RADIUS --*/
+ if ($brBL_V && $brBL_H ) {
+ $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + $h - ($border_left/2)- $brBL_V) )*_MPDFK))."\n";
+ $s .= ($this->_EllipseArc($x0 + $brBL_H, $y0 + $h - $brBL_V, $brBL_H - $border_left/2 , $brBL_V - $border_left/2, 3, 1))."\n";
+ }
+ else
+/*-- END BORDER-RADIUS --*/
+ if ($tbd['style']=='solid' || $tbd['style']=='double') {
+ $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + $h) )*_MPDFK))."\n";
+ }
+ else {
+ $s .= (sprintf('%.3F %.3F l ',($x0 + ($border_left/2))*_MPDFK, ($this->h-($y0 + $h - ($border_left/2)) )*_MPDFK))."\n";
+ }
+ $s .= 'S'."\n";
+ $this->_out($s);
+
+ if ($tbd['style']=='double') {
+ $this->SetLineWidth($tbd['w']/3);
+ $this->SetDColor($tbcol);
+ $this->_out($s);
+ }
+ if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this->_out('Q'); }
+
+ // Reset Corners and Dash off
+ $this->SetLineWidth(0.1);
+ $this->SetDColor($this->ConvertColor(0));
+ $this->SetLineJoin(2);
+ $this->SetLineCap(2);
+ $this->SetDash();
+ }
+ }
+ if ($this->blk[$blvl]['border_right']) {
+ $tbd = $this->blk[$blvl]['border_right'];
+ if (isset($tbd['s']) && $tbd['s']) {
+ if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') {
+ $this->_out('q');
+ $this->SetLineWidth(0);
+ $this->_out(sprintf('%.3F %.3F m ',($x0 + $w)*_MPDFK, ($this->h-($y0))*_MPDFK));
+ $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - $border_right)*_MPDFK, ($this->h-($y0+$border_top))*_MPDFK));
+ $this->_out(sprintf('%.3F %.3F l ',($x0 + $w - $border_right)*_MPDFK, ($this->h-($y0 + $h - $border_bottom))*_MPDFK));
+ $this->_out(sprintf('%.3F %.3F l ',($x0 + $w)*_MPDFK, ($this->h-($y0 + $h))*_MPDFK));
+ $this->_out(' h W n '); // Ends path no-op & Sets the clipping path
+ }
+
+ $this->_setBorderLine($tbd);
+ if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],$divider,$continuingpage,'R'); }
+/*-- BORDER-RADIUS --*/
+ else if (($brTR_V && $brTR_H) || ($brBR_V && $brBR_H) || $tbd['style']=='solid' || $tbd['style']=='double' ) {
+ $this->SetLineJoin(0);
+ $this->SetLineCap(0);
+ }
+ $s = '';
+ if ($brBR_V && $brBR_H) {
+ $s .= ($this->_EllipseArc($x0 + $w - $brBR_H, $y0 + $h - $brBR_V, $brBR_H - $border_right/2 , $brBR_V - $border_right/2, 4, 2, true))."\n";
+ }
+ else
+/*-- END BORDER-RADIUS --*/
+ if ($tbd['style']=='solid' || $tbd['style']=='double') {
+ $s .= (sprintf('%.3F %.3F m ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + $h))*_MPDFK))."\n";
+ }
+ else {
+ $s .= (sprintf('%.3F %.3F m ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + $h - ($border_right/2)))*_MPDFK))."\n";
+ }
+/*-- BORDER-RADIUS --*/
+ if ($brTR_V && $brTR_H ) {
+ $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + ($border_right/2) + $brTR_V) )*_MPDFK))."\n";
+ $s .= ($this->_EllipseArc($x0 + $w - $brTR_H, $y0 + $brTR_V, $brTR_H - $border_right/2 , $brTR_V - $border_right/2, 1, 1))."\n";
+ }
+ else
+/*-- END BORDER-RADIUS --*/
+ if ($tbd['style']=='solid' || $tbd['style']=='double') {
+ $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0) )*_MPDFK))."\n";
+ }
+ else {
+ $s .= (sprintf('%.3F %.3F l ',($x0 + $w - ($border_right/2))*_MPDFK, ($this->h-($y0 + ($border_right/2)) )*_MPDFK))."\n";
+ }
+ $s .= 'S'."\n";
+ $this->_out($s);
+
+ if ($tbd['style']=='double') {
+ $this->SetLineWidth($tbd['w']/3);
+ $this->SetDColor($tbcol);
+ $this->_out($s);
+ }
+ if (!$brset && $tbd['style']!='dotted' && $tbd['style']!='dashed') { $this->_out('Q'); }
+
+ // Reset Corners and Dash off
+ $this->SetLineWidth(0.1);
+ $this->SetDColor($this->ConvertColor(0));
+ $this->SetLineJoin(2);
+ $this->SetLineCap(2);
+ $this->SetDash();
+ }
+ }
+
+
+ $this->SetDash();
+ $this->y = $save_y;
+
+
+ // BACKGROUNDS are disabled in columns/kbt/headers - messes up the repositioning in printcolumnbuffer
+ if ($this->ColActive || $this->kwt || $this->keep_block_together) { return ; }
+
+
+ $bgx0 = $x0;
+ $bgx1 = $x1;
+ $bgy0 = $y0;
+ $bgy1 = $y1;
+
+ // Defined br values represent the radius of the outer curve - need to take border-width/2 from each radius for drawing the borders
+ if (isset($this->blk[$blvl]['background_clip']) && $this->blk[$blvl]['background_clip'] == 'padding-box') {
+ $brbgTL_H = max(0, $brTL_H - $this->blk[$blvl]['border_left']['w']);
+ $brbgTL_V = max(0, $brTL_V - $this->blk[$blvl]['border_top']['w']);
+ $brbgTR_H = max(0, $brTR_H - $this->blk[$blvl]['border_right']['w']);
+ $brbgTR_V = max(0, $brTR_V - $this->blk[$blvl]['border_top']['w']);
+ $brbgBL_H = max(0, $brBL_H - $this->blk[$blvl]['border_left']['w']);
+ $brbgBL_V = max(0, $brBL_V - $this->blk[$blvl]['border_bottom']['w']);
+ $brbgBR_H = max(0, $brBR_H - $this->blk[$blvl]['border_right']['w']);
+ $brbgBR_V = max(0, $brBR_V - $this->blk[$blvl]['border_bottom']['w']);
+ $bgx0 += $this->blk[$blvl]['border_left']['w'];
+ $bgx1 -= $this->blk[$blvl]['border_right']['w'];
+ if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
+ $bgy0 += $this->blk[$blvl]['border_top']['w'];
+ }
+ if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
+ $bgy1 -= $this->blk[$blvl]['border_bottom']['w'];
+ }
+ }
+ else if (isset($this->blk[$blvl]['background_clip']) && $this->blk[$blvl]['background_clip'] == 'content-box') {
+ $brbgTL_H = max(0, $brTL_H - $this->blk[$blvl]['border_left']['w'] - $this->blk[$blvl]['padding_left']);
+ $brbgTL_V = max(0, $brTL_V - $this->blk[$blvl]['border_top']['w'] - $this->blk[$blvl]['padding_top']);
+ $brbgTR_H = max(0, $brTR_H - $this->blk[$blvl]['border_right']['w'] - $this->blk[$blvl]['padding_right']);
+ $brbgTR_V = max(0, $brTR_V - $this->blk[$blvl]['border_top']['w'] - $this->blk[$blvl]['padding_top']);
+ $brbgBL_H = max(0, $brBL_H - $this->blk[$blvl]['border_left']['w'] - $this->blk[$blvl]['padding_left']);
+ $brbgBL_V = max(0, $brBL_V - $this->blk[$blvl]['border_bottom']['w'] - $this->blk[$blvl]['padding_bottom']);
+ $brbgBR_H = max(0, $brBR_H - $this->blk[$blvl]['border_right']['w'] - $this->blk[$blvl]['padding_right']);
+ $brbgBR_V = max(0, $brBR_V - $this->blk[$blvl]['border_bottom']['w'] - $this->blk[$blvl]['padding_bottom']);
+ $bgx0 += $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'];
+ $bgx1 -= $this->blk[$blvl]['border_right']['w'] + $this->blk[$blvl]['padding_right'];
+ if (($this->blk[$blvl]['border_top']['w'] || $this->blk[$blvl]['padding_top']) && $divider != 'pagetop' && !$continuingpage) {
+ $bgy0 += $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top'];
+ }
+ if (($this->blk[$blvl]['border_bottom']['w'] || $this->blk[$blvl]['padding_bottom']) && $blockstate != 1 && $divider != 'pagebottom') {
+ $bgy1 -= $this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom'];
+ }
+ }
+ else {
+ $brbgTL_H = $brTL_H;
+ $brbgTL_V = $brTL_V;
+ $brbgTR_H = $brTR_H;
+ $brbgTR_V = $brTR_V;
+ $brbgBL_H = $brBL_H;
+ $brbgBL_V = $brBL_V;
+ $brbgBR_H = $brBR_H;
+ $brbgBR_V = $brBR_V;
+ }
+
+ // Set clipping path
+ $s = ' q 0 w '; // Line width=0
+ $s .= sprintf('%.3F %.3F m ', ($bgx0+$brbgTL_H )*_MPDFK, ($this->h-$bgy0)*_MPDFK); // start point TL before the arc
+/*-- BORDER-RADIUS --*/
+ if ($brbgTL_H || $brbgTL_V) {
+ $s .= $this->_EllipseArc($bgx0+$brbgTL_H, $bgy0+$brbgTL_V, $brbgTL_H , $brbgTL_V , 2); // segment 2 TL
+ }
+/*-- END BORDER-RADIUS --*/
+ $s .= sprintf('%.3F %.3F l ', ($bgx0)*_MPDFK, ($this->h-($bgy1-$brbgBL_V ))*_MPDFK); // line to BL
+/*-- BORDER-RADIUS --*/
+ if ($brbgBL_H || $brbgBL_V) {
+ $s .= $this->_EllipseArc($bgx0+$brbgBL_H, $bgy1-$brbgBL_V, $brbgBL_H , $brbgBL_V , 3); // segment 3 BL
+ }
+/*-- END BORDER-RADIUS --*/
+ $s .= sprintf('%.3F %.3F l ', ($bgx1-$brbgBR_H )*_MPDFK, ($this->h-($bgy1))*_MPDFK); // line to BR
+/*-- BORDER-RADIUS --*/
+ if ($brbgBR_H || $brbgBR_V) {
+ $s .= $this->_EllipseArc($bgx1-$brbgBR_H, $bgy1-$brbgBR_V, $brbgBR_H , $brbgBR_V , 4); // segment 4 BR
+ }
+/*-- END BORDER-RADIUS --*/
+ $s .= sprintf('%.3F %.3F l ', ($bgx1)*_MPDFK, ($this->h-($bgy0+$brbgTR_V))*_MPDFK); // line to TR
+/*-- BORDER-RADIUS --*/
+ if ($brbgTR_H || $brbgTR_V) {
+ $s .= $this->_EllipseArc($bgx1-$brbgTR_H, $bgy0+$brbgTR_V, $brbgTR_H , $brbgTR_V , 1); // segment 1 TR
+ }
+/*-- END BORDER-RADIUS --*/
+ $s .= sprintf('%.3F %.3F l ', ($bgx0+$brbgTL_H )*_MPDFK, ($this->h-$bgy0)*_MPDFK); // line to TL
+
+
+ // Box Shadow
+ $shadow = '';
+ if (isset($this->blk[$blvl]['box_shadow']) && $this->blk[$blvl]['box_shadow'] && $h > 0) {
+ foreach($this->blk[$blvl]['box_shadow'] AS $sh) {
+ // Colors
+ if ($sh['col']{0}==1) {
+ $colspace = 'Gray';
+ if ($sh['col']{2}==1) { $col1 = '1'.$sh['col'][1].'1'.$sh['col'][3]; }
+ else { $col1 = '1'.$sh['col'][1].'1'.chr(100); }
+ $col2 = '1'.$sh['col'][1].'1'.chr(0);
+ }
+ else if ($sh['col']{0}==4) { // CMYK
+ $colspace = 'CMYK';
+ $col1 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].chr(100);
+ $col2 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].chr(0);
+ }
+ else if ($sh['col']{0}==5) { // RGBa
+ $colspace = 'RGB';
+ $col1 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4];
+ $col2 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].chr(0);
+ }
+ else if ($sh['col']{0}==6) { // CMYKa
+ $colspace = 'CMYK';
+ $col1 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].$sh['col'][5];
+ $col2 = '6'.$sh['col'][1].$sh['col'][2].$sh['col'][3].$sh['col'][4].chr(0);
+ }
+ else {
+ $colspace = 'RGB';
+ $col1 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].chr(100);
+ $col2 = '5'.$sh['col'][1].$sh['col'][2].$sh['col'][3].chr(0);
+ }
+
+ // Use clipping path as set above (and rectangle around page) to clip area outside box
+ $shadow .= $s; // Use the clipping path with W*
+ $shadow .= sprintf('0 %.3F m %.3F %.3F l ', $this->h*_MPDFK, $this->w*_MPDFK, $this->h*_MPDFK);
+ $shadow .= sprintf('%.3F 0 l 0 0 l 0 %.3F l ', $this->w*_MPDFK, $this->h*_MPDFK);
+ $shadow .= 'W n'."\n";
+
+ $sh['blur'] = abs($sh['blur']); // cannot have negative blur value
+ // Ensure spread/blur do not make effective shadow width/height < 0
+ // Could do more complex things but this just adjusts spread value
+ if (-$sh['spread'] + $sh['blur']/2 > min($w/2, $h/2)) {
+ $sh['spread'] = $sh['blur']/2 - min($w/2, $h/2) + 0.01;
+ }
+ // Shadow Offset
+ if ($sh['x'] || $sh['y']) $shadow .= sprintf(' q 1 0 0 1 %.4F %.4F cm', $sh['x']*_MPDFK, -$sh['y']*_MPDFK)."\n";
+
+ // Set path for INNER shadow
+ $shadow .= ' q 0 w ';
+ $shadow .= $this->SetFColor($col1, true)."\n";
+ if ($col1{0}==5 && ord($col1{4})<100) { // RGBa
+ $shadow .= $this->SetAlpha(ord($col1{4})/100, 'Normal', true, 'F')."\n";
+ }
+ else if ($col1{0}==6 && ord($col1{5})<100) { // CMYKa
+ $shadow .= $this->SetAlpha(ord($col1{5})/100, 'Normal', true, 'F')."\n";
+ }
+ else if ($col1{0}==1 && $col1{2}==1 && ord($col1{3})<100) { // Gray
+ $shadow .= $this->SetAlpha(ord($col1{3})/100, 'Normal', true, 'F')."\n";
+ }
+
+ // Blur edges
+ $mag = 0.551784; // Bezier Control magic number for 4-part spline for circle/ellipse
+ $mag2 = 0.551784; // Bezier Control magic number to fill in edge of blurred rectangle
+ $d1 = $sh['spread']+$sh['blur']/2;
+ $d2 = $sh['spread']-$sh['blur']/2;
+ $bl = $sh['blur'];
+ $x00 = $x0 - $d1;
+ $y00 = $y0 - $d1;
+ $w00 = $w + $d1*2;
+ $h00 = $h + $d1*2;
+
+ // If any border-radius is greater width-negative spread(inner edge), ignore radii for shadow or screws up
+ $flatten = false;
+ if (max($brbgTR_H, $brbgTL_H, $brbgBR_H, $brbgBL_H) >= $w+$d2) { $flatten = true; }
+ if (max($brbgTR_V, $brbgTL_V, $brbgBR_V, $brbgBL_V) >= $h+$d2) { $flatten = true; }
+
+
+ // TOP RIGHT corner
+ $p1x = $x00+$w00-$d1-$brbgTR_H; $p1c2x = $p1x +($d2+$brbgTR_H)*$mag;
+ $p1y = $y00+$bl;
+ $p2x = $x00+$w00-$d1-$brbgTR_H; $p2c2x = $p2x + ($d1+$brbgTR_H)*$mag;
+ $p2y = $y00; $p2c1y = $p2y + $bl/2;
+ $p3x = $x00+$w00; $p3c2x = $p3x - $bl/2;
+ $p3y = $y00+$d1+$brbgTR_V; $p3c1y = $p3y - ($d1+$brbgTR_V)*$mag;
+ $p4x = $x00+$w00-$bl;
+ $p4y = $y00+$d1+$brbgTR_V; $p4c2y = $p4y - ($d2+$brbgTR_V)*$mag;
+ if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
+ $p1x = $x00+$w00-$bl; $p1c2x = $p1x;
+ $p2x = $x00+$w00-$bl; $p2c2x = $p2x + $bl*$mag2;
+ $p3y = $y00+$bl; $p3c1y = $p3y - $bl*$mag2;
+ $p4y = $y00+$bl; $p4c2y = $p4y ;
+ }
+
+ $shadow .= sprintf('%.3F %.3F m ', ($p1x )*_MPDFK, ($this->h-($p1y ))*_MPDFK);
+ $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1c2x)*_MPDFK, ($this->h-($p1y))*_MPDFK, ($p4x)*_MPDFK, ($this->h-($p4c2y))*_MPDFK, ($p4x)*_MPDFK, ($this->h-($p4y))*_MPDFK);
+ $patch_array[0]['f']=0;
+ $patch_array[0]['points']=array($p1x,$p1y, $p1x,$p1y,
+ $p2x,$p2c1y, $p2x,$p2y, $p2c2x,$p2y,
+ $p3x,$p3c1y, $p3x,$p3y, $p3c2x,$p3y,
+ $p4x,$p4y, $p4x,$p4y, $p4x,$p4c2y,
+ $p1c2x,$p1y);
+ $patch_array[0]['colors'] = array($col1,$col2,$col2,$col1);
+
+
+ // RIGHT
+ $p1x = $x00+$w00; // control point only matches p3 preceding
+ $p1y = $y00+$d1+$brbgTR_V;
+ $p2x = $x00+$w00-$bl; // control point only matches p4 preceding
+ $p2y = $y00+$d1+$brbgTR_V;
+ $p3x = $x00+$w00-$bl;
+ $p3y = $y00+$h00-$d1-$brbgBR_V;
+ $p4x = $x00+$w00; $p4c1x = $p4x-$bl/2;
+ $p4y = $y00+$h00-$d1-$brbgBR_V;
+ if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
+ $p1y = $y00+$bl;
+ $p2y = $y00+$bl;
+ }
+ if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
+ $p3y = $y00+$h00-$bl;
+ $p4y = $y00+$h00-$bl;
+ }
+
+ $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
+ $patch_array[1]['f']=2;
+ $patch_array[1]['points']=array($p2x,$p2y,
+ $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
+ $p4c1x,$p4y, $p4x,$p4y, $p4x,$p4y,
+ $p1x,$p1y);
+ $patch_array[1]['colors'] = array($col1,$col2);
+
+
+ // BOTTOM RIGHT corner
+ $p1x = $x00+$w00-$bl; // control points only matches p3 preceding
+ $p1y = $y00+$h00-$d1-$brbgBR_V; $p1c2y = $p1y + ($d2+$brbgBR_V)*$mag;
+ $p2x = $x00+$w00; // control point only matches p4 preceding
+ $p2y = $y00+$h00-$d1-$brbgBR_V; $p2c2y = $p2y + ($d1+$brbgBR_V)*$mag;
+ $p3x = $x00+$w00-$d1-$brbgBR_H; $p3c1x = $p3x + ($d1+$brbgBR_H)*$mag;
+ $p3y = $y00+$h00; $p3c2y = $p3y - $bl/2;
+ $p4x = $x00+$w00-$d1-$brbgBR_H; $p4c2x = $p4x + ($d2+$brbgBR_H)*$mag;
+ $p4y = $y00+$h00-$bl;
+
+ if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
+ $p1y = $y00+$h00-$bl; $p1c2y = $p1y;
+ $p2y = $y00+$h00-$bl; $p2c2y = $p2y + $bl*$mag2;
+ $p3x = $x00+$w00-$bl; $p3c1x = $p3x + $bl*$mag2;
+ $p4x = $x00+$w00-$bl; $p4c2x = $p4x;
+ }
+
+ $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1x)*_MPDFK, ($this->h-($p1c2y))*_MPDFK, ($p4c2x)*_MPDFK, ($this->h-($p4y))*_MPDFK, ($p4x)*_MPDFK, ($this->h-($p4y))*_MPDFK);
+ $patch_array[2]['f']=2;
+ $patch_array[2]['points']=array($p2x,$p2c2y,
+ $p3c1x,$p3y, $p3x,$p3y, $p3x,$p3c2y,
+ $p4x,$p4y, $p4x,$p4y, $p4c2x,$p4y,
+ $p1x,$p1c2y);
+ $patch_array[2]['colors'] = array($col2,$col1);
+
+
+
+ // BOTTOM
+ $p1x = $x00+$w00-$d1-$brbgBR_H; // control point only matches p3 preceding
+ $p1y = $y00+$h00;
+ $p2x = $x00+$w00-$d1-$brbgBR_H; // control point only matches p4 preceding
+ $p2y = $y00+$h00-$bl;
+ $p3x = $x00+$d1+$brbgBL_H;
+ $p3y = $y00+$h00-$bl;
+ $p4x = $x00+$d1+$brbgBL_H;
+ $p4y = $y00+$h00; $p4c1y = $p4y - $bl/2;
+
+ if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) {
+ $p1x = $x00+$w00-$bl;
+ $p2x = $x00+$w00-$bl;
+ }
+ if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
+ $p3x = $x00+$bl;
+ $p4x = $x00+$bl;
+ }
+
+ $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
+ $patch_array[3]['f']=2;
+ $patch_array[3]['points']=array($p2x,$p2y,
+ $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
+ $p4x,$p4c1y, $p4x,$p4y, $p4x,$p4y,
+ $p1x,$p1y);
+ $patch_array[3]['colors'] = array($col1,$col2);
+
+ // BOTTOM LEFT corner
+ $p1x = $x00+$d1+$brbgBL_H; $p1c2x = $p1x - ($d2+$brbgBL_H)*$mag; // control points only matches p3 preceding
+ $p1y = $y00+$h00-$bl;
+ $p2x = $x00+$d1+$brbgBL_H; $p2c2x = $p2x - ($d1+$brbgBL_H)*$mag; // control point only matches p4 preceding
+ $p2y = $y00+$h00;
+ $p3x = $x00; $p3c2x = $p3x + $bl/2;
+ $p3y = $y00+$h00-$d1-$brbgBL_V; $p3c1y = $p3y + ($d1+$brbgBL_V)*$mag;
+ $p4x = $x00+$bl;
+ $p4y = $y00+$h00-$d1-$brbgBL_V; $p4c2y = $p4y + ($d2+$brbgBL_V)*$mag;
+ if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
+ $p1x = $x00+$bl; $p1c2x = $p1x;
+ $p2x = $x00+$bl; $p2c2x = $p2x - $bl*$mag2;
+ $p3y = $y00+$h00-$bl; $p3c1y = $p3y + $bl*$mag2;
+ $p4y = $y00+$h00-$bl; $p4c2y = $p4y;
+ }
+
+ $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1c2x)*_MPDFK, ($this->h-($p1y))*_MPDFK, ($p4x)*_MPDFK, ($this->h-($p4c2y))*_MPDFK, ($p4x)*_MPDFK, ($this->h-($p4y))*_MPDFK);
+ $patch_array[4]['f']=2;
+ $patch_array[4]['points']=array($p2c2x,$p2y,
+ $p3x,$p3c1y, $p3x,$p3y, $p3c2x,$p3y,
+ $p4x,$p4y, $p4x,$p4y, $p4x,$p4c2y,
+ $p1c2x,$p1y);
+ $patch_array[4]['colors'] = array($col2,$col1);
+
+
+ // LEFT - joins on the right (C3-C4 of previous): f = 2
+ $p1x = $x00; // control point only matches p3 preceding
+ $p1y = $y00+$h00-$d1-$brbgBL_V;
+ $p2x = $x00+$bl; // control point only matches p4 preceding
+ $p2y = $y00+$h00-$d1-$brbgBL_V;
+ $p3x = $x00+$bl;
+ $p3y = $y00+$d1+$brbgTL_V;
+ $p4x = $x00; $p4c1x = $p4x + $bl/2;
+ $p4y = $y00+$d1+$brbgTL_V;
+ if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) {
+ $p1y = $y00+$h00-$bl;
+ $p2y = $y00+$h00-$bl;
+ }
+ if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
+ $p3y = $y00+$bl;
+ $p4y = $y00+$bl;
+ }
+
+ $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
+ $patch_array[5]['f']=2;
+ $patch_array[5]['points']=array($p2x,$p2y,
+ $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
+ $p4c1x,$p4y, $p4x,$p4y, $p4x,$p4y,
+ $p1x,$p1y);
+ $patch_array[5]['colors'] = array($col1,$col2);
+
+ // TOP LEFT corner
+ $p1x = $x00+$bl; // control points only matches p3 preceding
+ $p1y = $y00+$d1+$brbgTL_V; $p1c2y = $p1y - ($d2+$brbgTL_V)*$mag;
+ $p2x = $x00; // control point only matches p4 preceding
+ $p2y = $y00+$d1+$brbgTL_V; $p2c2y = $p2y - ($d1+$brbgTL_V)*$mag;
+ $p3x = $x00+$d1+$brbgTL_H; $p3c1x = $p3x - ($d1+$brbgTL_H)*$mag;
+ $p3y = $y00; $p3c2y = $p3y + $bl/2;
+ $p4x = $x00+$d1+$brbgTL_H; $p4c2x = $p4x - ($d2+$brbgTL_H)*$mag;
+ $p4y = $y00+$bl;
+
+ if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
+ $p1y = $y00+$bl; $p1c2y = $p1y;
+ $p2y = $y00+$bl; $p2c2y = $p2y - $bl*$mag2;
+ $p3x = $x00+$bl; $p3c1x = $p3x - $bl*$mag2;
+ $p4x = $x00+$bl; $p4c2x = $p4x ;
+ }
+
+ $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1x)*_MPDFK, ($this->h-($p1c2y))*_MPDFK, ($p4c2x)*_MPDFK, ($this->h-($p4y))*_MPDFK, ($p4x)*_MPDFK, ($this->h-($p4y))*_MPDFK);
+ $patch_array[6]['f']=2;
+ $patch_array[6]['points']=array($p2x,$p2c2y,
+ $p3c1x,$p3y, $p3x,$p3y, $p3x,$p3c2y,
+ $p4x,$p4y, $p4x,$p4y, $p4c2x,$p4y,
+ $p1x,$p1c2y);
+ $patch_array[6]['colors'] = array($col2,$col1);
+
+
+ // TOP - joins on the right (C3-C4 of previous): f = 2
+ $p1x = $x00+$d1+$brbgTL_H; // control point only matches p3 preceding
+ $p1y = $y00;
+ $p2x = $x00+$d1+$brbgTL_H; // control point only matches p4 preceding
+ $p2y = $y00+$bl;
+ $p3x = $x00+$w00-$d1-$brbgTR_H;
+ $p3y = $y00+$bl;
+ $p4x = $x00+$w00-$d1-$brbgTR_H;
+ $p4y = $y00; $p4c1y = $p4y + $bl/2;
+ if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) {
+ $p1x = $x00+$bl;
+ $p2x = $x00+$bl;
+ }
+ if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) {
+ $p3x = $x00+$w00-$bl;
+ $p4x = $x00+$w00-$bl;
+ }
+
+ $shadow .= sprintf('%.3F %.3F l ', ($p3x )*_MPDFK, ($this->h-($p3y ))*_MPDFK);
+ $patch_array[7]['f']=2;
+ $patch_array[7]['points']=array($p2x,$p2y,
+ $p3x,$p3y, $p3x,$p3y, $p3x,$p3y,
+ $p4x,$p4c1y, $p4x,$p4y, $p4x,$p4y,
+ $p1x,$p1y);
+ $patch_array[7]['colors'] = array($col1,$col2);
+
+ $shadow .= ' h f Q '."\n"; // Close path and Fill the inner solid shadow
+
+ if ($bl) $shadow .= $this->grad->CoonsPatchMesh($x00,$y00,$w00,$h00,$patch_array,$x00,$x00+$w00,$y00,$y00+$h00, $colspace, true);
+
+ if ($sh['x'] || $sh['y']) $shadow .= ' Q'."\n"; // Shadow Offset
+ $shadow .= ' Q'."\n"; // Ends path no-op & Sets the clipping path
+
+ }
+ }
+
+ $s .= ' W n '; // Ends path no-op & Sets the clipping path
+
+ if ($this->blk[$blvl]['bgcolor']) {
+ $this->pageBackgrounds[$blvl][] = array('x'=>$x0, 'y'=>$y0, 'w'=>$w, 'h'=>$h, 'col'=>$this->blk[$blvl]['bgcolorarray'], 'clippath'=>$s, 'visibility'=>$this->visibility, 'shadow'=>$shadow, 'z-index'=>$this->current_layer);
+ }
+ else if ($shadow) {
+ $this->pageBackgrounds[$blvl][] = array('shadowonly'=>true, 'col'=>'', 'clippath'=>'', 'visibility'=>$this->visibility, 'shadow'=>$shadow, 'z-index'=>$this->current_layer);
+ }
+
+/*-- BACKGROUNDS --*/
+ if (isset($this->blk[$blvl]['gradient'])) {
+ $g = $this->grad->parseBackgroundGradient($this->blk[$blvl]['gradient']);
+ if ($g) {
+ $gx = $x0;
+ $gy = $y0;
+ $this->pageBackgrounds[$blvl][] = array('gradient'=>true, 'x'=>$gx, 'y'=>$gy, 'w'=>$w, 'h'=>$h, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>$s, 'visibility'=>$this->visibility, 'z-index'=>$this->current_layer);
+ }
+ }
+ if (isset($this->blk[$blvl]['background-image'])) {
+ if (isset($this->blk[$blvl]['background-image']['gradient']) && $this->blk[$blvl]['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $this->blk[$blvl]['background-image']['gradient'] )) {
+ $g = $this->grad->parseMozGradient( $this->blk[$blvl]['background-image']['gradient'] );
+ if ($g) {
+ $gx = $x0;
+ $gy = $y0;
+ // origin specifies the background-positioning-area (bpa)
+ if ($this->blk[$blvl]['background-image']['origin'] == 'padding-box') {
+ $gx += $this->blk[$blvl]['border_left']['w'];
+ $w -= ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['border_right']['w']);
+ if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
+ $gy += $this->blk[$blvl]['border_top']['w'];
+ }
+ if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
+ $gy1 = $y1 - $this->blk[$blvl]['border_bottom']['w'];
+ }
+ else { $gy1 = $y1; }
+ $h = $gy1 - $gy;
+ }
+ else if ($this->blk[$blvl]['background-image']['origin'] == 'content-box') {
+ $gx += $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'];
+ $w -= ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'] + $this->blk[$blvl]['border_right']['w'] + $this->blk[$blvl]['padding_right']);
+ if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
+ $gy += $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top'];
+ }
+ if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
+ $gy1 = $y1 - ($this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom']);
+ }
+ else { $gy1 = $y1 - $this->blk[$blvl]['padding_bottom']; }
+ $h = $gy1 - $gy;
+ }
+
+ if (isset($this->blk[$blvl]['background-image']['size']['w']) && $this->blk[$blvl]['background-image']['size']['w']) {
+ $size = $this->blk[$blvl]['background-image']['size'];
+ if ($size['w']!='contain' && $size['w']!='cover') {
+ if (stristr($size['w'] ,'%')) {
+ $size['w'] += 0;
+ $size['w'] /= 100;
+ $w *= $size['w'];
+ }
+ else if ($size['w']!='auto') {
+ $w = $size['w'];
+ }
+ if (stristr($size['h'] ,'%')) {
+ $size['h'] += 0;
+ $size['h'] /= 100;
+ $h *= $size['h'];
+ }
+ else if ($size['h']!='auto') {
+ $h = $size['h'];
+ }
+ }
+ }
+ $this->pageBackgrounds[$blvl][] = array('gradient'=>true, 'x'=>$gx, 'y'=>$gy, 'w'=>$w, 'h'=>$h, 'gradtype'=>$g['type'], 'stops'=>$g['stops'], 'colorspace'=>$g['colorspace'], 'coords'=>$g['coords'], 'extend'=>$g['extend'], 'clippath'=>$s, 'visibility'=>$this->visibility, 'z-index'=>$this->current_layer);
+ }
+ }
+ else {
+ $image_id = $this->blk[$blvl]['background-image']['image_id'];
+ $orig_w = $this->blk[$blvl]['background-image']['orig_w'];
+ $orig_h = $this->blk[$blvl]['background-image']['orig_h'];
+ $x_pos = $this->blk[$blvl]['background-image']['x_pos'];
+ $y_pos = $this->blk[$blvl]['background-image']['y_pos'];
+ $x_repeat = $this->blk[$blvl]['background-image']['x_repeat'];
+ $y_repeat = $this->blk[$blvl]['background-image']['y_repeat'];
+ $resize = $this->blk[$blvl]['background-image']['resize'];
+ $opacity = $this->blk[$blvl]['background-image']['opacity'];
+ $itype = $this->blk[$blvl]['background-image']['itype'];
+ $size = $this->blk[$blvl]['background-image']['size'];
+ // origin specifies the background-positioning-area (bpa)
+ $bpa = array('x'=>$x0, 'y'=>$y0, 'w'=>$w, 'h'=>$h);
+ if ($this->blk[$blvl]['background-image']['origin'] == 'padding-box') {
+ $bpa['x'] = $x0 + $this->blk[$blvl]['border_left']['w'];
+ $bpa['w'] = $w - ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['border_right']['w']);
+ if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
+ $bpa['y'] = $y0 + $this->blk[$blvl]['border_top']['w'];
+ }
+ else { $bpa['y'] = $y0; }
+ if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
+ $bpay = $y1 - $this->blk[$blvl]['border_bottom']['w'];
+ }
+ else { $bpay = $y1; }
+ $bpa['h'] = $bpay - $bpa['y'];
+ }
+ else if ($this->blk[$blvl]['background-image']['origin'] == 'content-box') {
+ $bpa['x'] = $x0 + $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'];
+ $bpa['w'] = $w - ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'] + $this->blk[$blvl]['border_right']['w'] + $this->blk[$blvl]['padding_right']);
+ if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) {
+ $bpa['y'] = $y0 + $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top'];
+ }
+ else { $bpa['y'] = $y0 + $this->blk[$blvl]['padding_top']; }
+ if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') {
+ $bpay = $y1 - ($this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom']);
+ }
+ else { $bpay = $y1 - $this->blk[$blvl]['padding_bottom']; }
+ $bpa['h'] = $bpay - $bpa['y'];
+ }
+ $this->pageBackgrounds[$blvl][] = array('x'=>$x0, 'y'=>$y0, 'w'=>$w, 'h'=>$h, 'image_id'=>$image_id, 'orig_w'=>$orig_w, 'orig_h'=>$orig_h, 'x_pos'=>$x_pos, 'y_pos'=>$y_pos, 'x_repeat'=>$x_repeat, 'y_repeat'=>$y_repeat, 'clippath'=>$s, 'resize'=>$resize, 'opacity'=>$opacity, 'itype'=>$itype, 'visibility'=>$this->visibility, 'z-index'=>$this->current_layer, 'size'=>$size, 'bpa'=>$bpa );
+ }
+ }
+/*-- END BACKGROUNDS --*/
+
+ // Float DIV
+ $this->blk[$blvl]['bb_painted'][$this->page] = true;
+
+}
+
+/*-- BORDER-RADIUS --*/
+
+function _EllipseArc($x0, $y0, $rx, $ry, $seg = 1, $part=false, $start=false) { // Anticlockwise segment 1-4 TR-TL-BL-BR (part=1 or 2)
+ $s = '';
+ if ($rx<0) { $rx = 0; }
+ if ($ry<0) { $ry = 0; }
+ $rx *= _MPDFK;
+ $ry *= _MPDFK;
+ $astart = 0;
+ if ($seg == 1) { // Top Right
+ $afinish = 90;
+ $nSeg = 4;
+ }
+ else if ($seg == 2) { // Top Left
+ $afinish = 180;
+ $nSeg = 8;
+ }
+ else if ($seg == 3) { // Bottom Left
+ $afinish = 270;
+ $nSeg = 12;
+ }
+ else { // Bottom Right
+ $afinish = 360;
+ $nSeg = 16;
+ }
+ $astart = deg2rad((float) $astart);
+ $afinish = deg2rad((float) $afinish);
+ $totalAngle = $afinish - $astart;
+ $dt = $totalAngle / $nSeg; // segment angle
+ $dtm = $dt/3;
+ $x0 *= _MPDFK;
+ $y0 = ($this->h - $y0) * _MPDFK;
+ $t1 = $astart;
+ $a0 = $x0 + ($rx * cos($t1));
+ $b0 = $y0 + ($ry * sin($t1));
+ $c0 = -$rx * sin($t1);
+ $d0 = $ry * cos($t1);
+ $op = false;
+ for ($i = 1; $i <= $nSeg; $i++) {
+ // Draw this bit of the total curve
+ $t1 = ($i * $dt) + $astart;
+ $a1 = $x0 + ($rx * cos($t1));
+ $b1 = $y0 + ($ry * sin($t1));
+ $c1 = -$rx * sin($t1);
+ $d1 = $ry * cos($t1);
+ if ($i>($nSeg-4) && (!$part || ($part == 1 && $i<=$nSeg-2) || ($part == 2 && $i>$nSeg-2))) {
+ if ($start && !$op) {
+ $s .= sprintf('%.3F %.3F m ', $a0, $b0);
+ }
+ $s .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($a0 + ($c0 * $dtm)), ($b0 + ($d0 * $dtm)), ($a1 - ($c1 * $dtm)) , ($b1 - ($d1 * $dtm)), $a1 , $b1 );
+ $op = true;
+ }
+ $a0 = $a1;
+ $b0 = $b1;
+ $c0 = $c1;
+ $d0 = $d1;
+ }
+ return $s;
+}
+/*-- END BORDER-RADIUS --*/
+
+
+
+function PaintDivLnBorder($state=0,$blvl=0,$h) {
+ // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom
+ $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y + $h;
+
+ $save_y = $this->y;
+
+ $w = $this->blk[$blvl]['width'];
+ $x0 = $this->x; // left
+ $y0 = $this->y; // top
+ $x1 = $this->x + $w; // bottom
+ $y1 = $this->y + $h; // bottom
+
+ if ($this->blk[$blvl]['border_top'] && ($state==1 || $state==3)) {
+ $tbd = $this->blk[$blvl]['border_top'];
+ if (isset($tbd['s']) && $tbd['s']) {
+ $this->_setBorderLine($tbd);
+ $this->y = $y0 + ($tbd['w']/2);
+ if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
+ $this->_setDashBorder($tbd['style'],'',$continuingpage,'T');
+ $this->Line($x0 + ($tbd['w']/2) , $this->y , $x0 + $w - ($tbd['w']/2), $this->y);
+ }
+ else {
+ $this->SetLineJoin(0);
+ $this->SetLineCap(0);
+ $this->Line($x0, $this->y , $x0 + $w, $this->y);
+ }
+ $this->y += $tbd['w'];
+ // Reset Corners and Dash off
+ $this->SetLineJoin(2);
+ $this->SetLineCap(2);
+ $this->SetDash();
+ }
+ }
+ if ($this->blk[$blvl]['border_left']) {
+ $tbd = $this->blk[$blvl]['border_left'];
+ if (isset($tbd['s']) && $tbd['s']) {
+ $this->_setBorderLine($tbd);
+ if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
+ $this->y = $y0 + ($tbd['w']/2);
+ $this->_setDashBorder($tbd['style'],'',$continuingpage,'L');
+ $this->Line($x0 + ($tbd['w']/2), $this->y, $x0 + ($tbd['w']/2), $y0 + $h -($tbd['w']/2));
+ }
+ else {
+ $this->y = $y0;
+ $this->SetLineJoin(0);
+ $this->SetLineCap(0);
+ $this->Line($x0 + ($tbd['w']/2), $this->y, $x0 + ($tbd['w']/2), $y0 + $h);
+ }
+ $this->y += $tbd['w'];
+ // Reset Corners and Dash off
+ $this->SetLineJoin(2);
+ $this->SetLineCap(2);
+ $this->SetDash();
+ }
+ }
+ if ($this->blk[$blvl]['border_right']) {
+ $tbd = $this->blk[$blvl]['border_right'];
+ if (isset($tbd['s']) && $tbd['s']) {
+ $this->_setBorderLine($tbd);
+ if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
+ $this->y = $y0 + ($tbd['w']/2);
+ $this->_setDashBorder($tbd['style'],'',$continuingpage,'R');
+ $this->Line($x0 + $w - ($tbd['w']/2), $this->y, $x0 + $w - ($tbd['w']/2), $y0 + $h - ($tbd['w']/2));
+ }
+ else {
+ $this->y = $y0;
+ $this->SetLineJoin(0);
+ $this->SetLineCap(0);
+ $this->Line($x0 + $w - ($tbd['w']/2), $this->y, $x0 + $w - ($tbd['w']/2), $y0 + $h);
+ }
+ $this->y += $tbd['w'];
+ // Reset Corners and Dash off
+ $this->SetLineJoin(2);
+ $this->SetLineCap(2);
+ $this->SetDash();
+ }
+ }
+ if ($this->blk[$blvl]['border_bottom'] && $state > 1) {
+ $tbd = $this->blk[$blvl]['border_bottom'];
+ if (isset($tbd['s']) && $tbd['s']) {
+ $this->_setBorderLine($tbd);
+ $this->y = $y0 + $h - ($tbd['w']/2);
+ if ($tbd['style']=='dotted' || $tbd['style']=='dashed') {
+ $this->_setDashBorder($tbd['style'],'',$continuingpage,'B');
+ $this->Line($x0 + ($tbd['w']/2) , $this->y, $x0 + $w - ($tbd['w']/2), $this->y);
+ }
+ else {
+ $this->SetLineJoin(0);
+ $this->SetLineCap(0);
+ $this->Line($x0, $this->y, $x0 + $w, $this->y);
+ }
+ $this->y += $tbd['w'];
+ // Reset Corners and Dash off
+ $this->SetLineJoin(2);
+ $this->SetLineCap(2);
+ $this->SetDash();
+ }
+ }
+ $this->SetDash();
+ $this->y = $save_y;
+}
+
+
+function PaintImgBorder($objattr,$is_table) {
+ // Borders are disabled in columns - messes up the repositioning in printcolumnbuffer
+ if ($this->ColActive) { return ; } // *COLUMNS*
+ if ($is_table) { $k = $this->shrin_k; } else { $k = 1; }
+ $h = (isset($objattr['BORDER-HEIGHT']) ? $objattr['BORDER-HEIGHT'] : 0);
+ $w = (isset($objattr['BORDER-WIDTH']) ? $objattr['BORDER-WIDTH'] : 0);
+ $x0 = (isset($objattr['BORDER-X']) ? $objattr['BORDER-X'] : 0);
+ $y0 = (isset($objattr['BORDER-Y']) ? $objattr['BORDER-Y'] : 0);
+
+ // BORDERS
+ if ($objattr['border_top']) {
+ $tbd = $objattr['border_top'];
+ if (!empty($tbd['s'])) {
+ $this->_setBorderLine($tbd,$k);
+ if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','T'); }
+ $this->Line($x0, $y0, $x0 + $w, $y0);
+ // Reset Corners and Dash off
+ $this->SetLineJoin(2);
+ $this->SetLineCap(2);
+ $this->SetDash();
+ }
+ }
+ if ($objattr['border_left']) {
+ $tbd = $objattr['border_left'];
+ if (!empty($tbd['s'])) {
+ $this->_setBorderLine($tbd,$k);
+ if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','L'); }
+ $this->Line($x0, $y0, $x0, $y0 + $h);
+ // Reset Corners and Dash off
+ $this->SetLineJoin(2);
+ $this->SetLineCap(2);
+ $this->SetDash();
+ }
+ }
+ if ($objattr['border_right']) {
+ $tbd = $objattr['border_right'];
+ if (!empty($tbd['s'])) {
+ $this->_setBorderLine($tbd,$k);
+ if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','R'); }
+ $this->Line($x0 + $w, $y0, $x0 + $w, $y0 + $h);
+ // Reset Corners and Dash off
+ $this->SetLineJoin(2);
+ $this->SetLineCap(2);
+ $this->SetDash();
+ }
+ }
+ if ($objattr['border_bottom']) {
+ $tbd = $objattr['border_bottom'];
+ if (!empty($tbd['s'])) {
+ $this->_setBorderLine($tbd,$k);
+ if ($tbd['style']=='dotted' || $tbd['style']=='dashed') { $this->_setDashBorder($tbd['style'],'','','B'); }
+ $this->Line($x0, $y0 + $h, $x0 + $w, $y0 + $h);
+ // Reset Corners and Dash off
+ $this->SetLineJoin(2);
+ $this->SetLineCap(2);
+ $this->SetDash();
+ }
+ }
+ $this->SetDash();
+ $this->SetAlpha(1);
+}
+
+/*-- END HTML-CSS --*/
+
+
+
+
+function Reset() {
+ $this->SetTColor($this->ConvertColor(0));
+ $this->SetDColor($this->ConvertColor(0));
+ $this->SetFColor($this->ConvertColor(255));
+ $this->SetAlpha(1);
+ $this->colorarray = '';
+
+ $this->spanbgcolorarray = '';
+ $this->spanbgcolor = false;
+ $this->spanborder = false;
+ $this->spanborddet = array();
+
+ $this->ResetStyles();
+
+ $this->HREF = '';
+ $this->textparam = array();
+ $this->SetTextOutline();
+
+ $this->textvar = 0x00; // mPDF 5.7.1
+ $this->OTLtags = array();
+ $this->textshadow = '';
+
+ $this->currentLang = $this->default_lang; // mPDF 6
+ $this->RestrictUnicodeFonts($this->default_available_fonts ); // mPDF 6
+ $this->SetFont($this->default_font,'',0,false);
+ $this->SetFontSize($this->default_font_size,false);
+
+ $this->currentfontfamily = '';
+ $this->currentfontsize = '';
+ $this->currentfontstyle = '';
+
+/*-- TABLES --*/
+ if ($this->tableLevel && isset($this->table[1][1]['cellLineHeight'])) {
+ $this->SetLineHeight('',$this->table[1][1]['cellLineHeight']); // *TABLES*
+ }
+ else
+/*-- END TABLES --*/
+ if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) {
+ $this->SetLineHeight('',$this->blk[$this->blklvl]['line_height']); // sets default line height
+ }
+
+ $this->lSpacingCSS = '';
+ $this->wSpacingCSS = '';
+ $this->fixedlSpacing = false;
+ $this->minwSpacing = 0;
+ $this->SetDash(); //restore to no dash
+ $this->dash_on = false;
+ $this->dotted_on = false;
+ $this->divwidth = 0;
+ $this->divheight = 0;
+ $this->cellTextAlign = '';
+ $this->cellLineHeight = '';
+ $this->cellLineStackingStrategy = '';
+ $this->cellLineStackingShift = '';
+ $this->oldy = -1;
+
+ $bodystyle = array();
+ if (isset($this->cssmgr->CSS['BODY']['FONT-STYLE'])) { $bodystyle['FONT-STYLE'] = $this->cssmgr->CSS['BODY']['FONT-STYLE']; }
+ if (isset($this->cssmgr->CSS['BODY']['FONT-WEIGHT'])) { $bodystyle['FONT-WEIGHT'] = $this->cssmgr->CSS['BODY']['FONT-WEIGHT']; }
+ if (isset($this->cssmgr->CSS['BODY']['COLOR'])) { $bodystyle['COLOR'] = $this->cssmgr->CSS['BODY']['COLOR']; }
+ if (isset($bodystyle)) { $this->setCSS($bodystyle,'BLOCK','BODY'); }
+
+}
+
+/*-- HTML-CSS --*/
+function ReadMetaTags($html) {
+ // changes anykey=anyvalue to anykey="anyvalue" (only do this when this happens inside tags)
+ $regexp = '/ (\\w+?)=([^\\s>"]+)/si';
+ $html = preg_replace($regexp," \$1=\"\$2\"",$html);
+ if (preg_match('/(.*?)<\/title>/si',$html,$m)) {
+ $this->SetTitle($m[1]);
+ }
+ preg_match_all('/]*?(name|content)="([^>]*?)" [^>]*?(name|content)="([^>]*?)".*?>/si',$html,$aux);
+ $firstattr = $aux[1];
+ $secondattr = $aux[3];
+ for( $i = 0 ; $i < count($aux[0]) ; $i++) {
+
+ $name = ( strtoupper($firstattr[$i]) == "NAME" )? strtoupper($aux[2][$i]) : strtoupper($aux[4][$i]);
+ $content = ( strtoupper($firstattr[$i]) == "CONTENT" )? $aux[2][$i] : $aux[4][$i];
+ switch($name) {
+ case "KEYWORDS": $this->SetKeywords($content); break;
+ case "AUTHOR": $this->SetAuthor($content); break;
+ case "DESCRIPTION": $this->SetSubject($content); break;
+ }
+ }
+}
+
+
+function ReadCharset($html) {
+ // Charset conversion
+ if ($this->allow_charset_conversion) {
+ if (preg_match('//si',$html,$m)) {
+ if (strtoupper($m[1]) != 'UTF-8') {
+ $this->charset_in = strtoupper($m[1]);
+ }
+ }
+ }
+}
+
+function setCSS($arrayaux,$type='',$tag='') { // type= INLINE | BLOCK | TABLECELL // tag= BODY
+ if (!is_array($arrayaux)) return; //Removes PHP Warning
+
+ // mPDF 5.7.3 inline text-decoration parameters
+ $preceeding_fontkey = $this->FontFamily . $this->FontStyle;
+ $preceeding_fontsize = $this->FontSize;
+ $spanbordset = false;
+ $spanbgset = false;
+ // mPDF 6
+ $prevlevel = (($this->blklvl == 0) ? 0 : $this->blklvl-1);
+
+ // Set font size first so that e.g. MARGIN 0.83em works on font size for this element
+ if (isset($arrayaux['FONT-SIZE'])) {
+ $v = $arrayaux['FONT-SIZE'];
+ if(is_numeric($v[0])) {
+ if ($type == 'BLOCK' && $this->blklvl>0 && isset($this->blk[$this->blklvl-1]['InlineProperties']) && isset($this->blk[$this->blklvl-1]['InlineProperties']['size'])) {
+ $mmsize = $this->ConvertSize($v,$this->blk[$this->blklvl-1]['InlineProperties']['size']);
+ }
+ else if ($type=='TABLECELL') {
+ $mmsize = $this->ConvertSize($v,$this->default_font_size/_MPDFK);
+ }
+ else {
+ $mmsize = $this->ConvertSize($v,$this->FontSize);
+ }
+ $this->SetFontSize( $mmsize*(_MPDFK),false ); //Get size in points (pt)
+ }
+ else{
+ $v = strtoupper($v);
+ if (isset($this->fontsizes[$v])) {
+ $this->SetFontSize( $this->fontsizes[$v]* $this->default_font_size,false);
+ }
+ }
+ if ($tag == 'BODY') { $this->SetDefaultFontSize($this->FontSizePt); }
+ }
+
+ // mPDF 6
+ if (isset($arrayaux['LANG']) && $arrayaux['LANG']) {
+ if ($this->autoLangToFont && !$this->usingCoreFont) {
+ if ($arrayaux['LANG'] != $this->default_lang && $arrayaux['LANG'] != 'UTF-8') {
+ list ($coreSuitable,$mpdf_pdf_unifont) = GetLangOpts($arrayaux['LANG'], $this->useAdobeCJK, $this->fontdata);
+ if ($mpdf_pdf_unifont) { $arrayaux['FONT-FAMILY'] = $mpdf_pdf_unifont; }
+ if ($tag == 'BODY') { $this->default_lang = $arrayaux['LANG']; }
+ }
+ }
+ $this->currentLang = $arrayaux['LANG'];
+ }
+
+ // FOR INLINE and BLOCK OR 'BODY'
+ if (isset($arrayaux['FONT-FAMILY'])) {
+ $v = $arrayaux['FONT-FAMILY'];
+ //If it is a font list, get all font types
+ $aux_fontlist = explode(",",$v);
+ $found = 0;
+ foreach($aux_fontlist AS $f) {
+ $fonttype = trim($f);
+ $fonttype = preg_replace('/["\']*(.*?)["\']*/','\\1',$fonttype);
+ $fonttype = preg_replace('/ /','',$fonttype);
+ $v = strtolower(trim($fonttype));
+ if (isset($this->fonttrans[$v]) && $this->fonttrans[$v]) { $v = $this->fonttrans[$v]; }
+ if ((!$this->onlyCoreFonts && in_array($v,$this->available_unifonts)) ||
+ in_array($v,array('ccourier','ctimes','chelvetica')) ||
+ ($this->onlyCoreFonts && in_array($v,array('courier','times','helvetica','arial'))) ||
+ in_array($v, array('sjis','uhc','big5','gb'))) {
+ $fonttype = $v;
+ $found = 1;
+ break;
+ }
+ }
+ if (!$found) {
+ foreach($aux_fontlist AS $f) {
+ $fonttype = trim($f);
+ $fonttype = preg_replace('/["\']*(.*?)["\']*/','\\1',$fonttype);
+ $fonttype = preg_replace('/ /','',$fonttype);
+ $v = strtolower(trim($fonttype));
+ if (isset($this->fonttrans[$v]) && $this->fonttrans[$v]) { $v = $this->fonttrans[$v]; }
+ if (in_array($v,$this->sans_fonts) || in_array($v,$this->serif_fonts) || in_array($v,$this->mono_fonts) ) {
+ $fonttype = $v;
+ break;
+ }
+ }
+ }
+
+ if ($tag == 'BODY') {
+ $this->SetDefaultFont($fonttype);
+ }
+ $this->SetFont($fonttype,$this->currentfontstyle,0,false);
+ }
+ else {
+ $this->SetFont($this->currentfontfamily,$this->currentfontstyle,0,false);
+ }
+
+ foreach($arrayaux as $k => $v) {
+ if ($type != 'INLINE' && $tag != 'BODY' && $type != 'TABLECELL') {
+ switch($k){
+ // BORDERS
+ case 'BORDER-TOP':
+ $this->blk[$this->blklvl]['border_top'] = $this->border_details($v);
+ if ($this->blk[$this->blklvl]['border_top']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
+ break;
+ case 'BORDER-BOTTOM':
+ $this->blk[$this->blklvl]['border_bottom'] = $this->border_details($v);
+ if ($this->blk[$this->blklvl]['border_bottom']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
+ break;
+ case 'BORDER-LEFT':
+ $this->blk[$this->blklvl]['border_left'] = $this->border_details($v);
+ if ($this->blk[$this->blklvl]['border_left']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
+ break;
+ case 'BORDER-RIGHT':
+ $this->blk[$this->blklvl]['border_right'] = $this->border_details($v);
+ if ($this->blk[$this->blklvl]['border_right']['s']) { $this->blk[$this->blklvl]['border'] = 1; }
+ break;
+
+ // PADDING
+ case 'PADDING-TOP':
+ $this->blk[$this->blklvl]['padding_top'] = $this->ConvertSize($v,$this->blk[$prevlevel]['inner_width'],$this->FontSize,false);
+ break;
+ case 'PADDING-BOTTOM':
+ $this->blk[$this->blklvl]['padding_bottom'] = $this->ConvertSize($v,$this->blk[$prevlevel]['inner_width'],$this->FontSize,false);
+ break;
+ case 'PADDING-LEFT':
+ if (($tag=='UL' || $tag=='OL') && $v == 'auto') {
+ $this->blk[$this->blklvl]['padding_left'] = 'auto';
+ break;
+ }
+ $this->blk[$this->blklvl]['padding_left'] = $this->ConvertSize($v,$this->blk[$prevlevel]['inner_width'],$this->FontSize,false);
+ break;
+ case 'PADDING-RIGHT':
+ if (($tag=='UL' || $tag=='OL') && $v == 'auto') {
+ $this->blk[$this->blklvl]['padding_right'] = 'auto';
+ break;
+ }
+ $this->blk[$this->blklvl]['padding_right'] = $this->ConvertSize($v,$this->blk[$prevlevel]['inner_width'],$this->FontSize,false);
+ break;
+
+ // MARGINS
+ case 'MARGIN-TOP':
+ $tmp = $this->ConvertSize($v,$this->blk[$prevlevel]['inner_width'],$this->FontSize,false);
+ if (isset($this->blk[$this->blklvl]['lastbottommargin'])) {
+ if ($tmp > $this->blk[$this->blklvl]['lastbottommargin']) {
+ $tmp -= $this->blk[$this->blklvl]['lastbottommargin'];
+ }
+ else {
+ $tmp = 0;
+ }
+ }
+ $this->blk[$this->blklvl]['margin_top'] = $tmp;
+ break;
+ case 'MARGIN-BOTTOM':
+ $this->blk[$this->blklvl]['margin_bottom'] = $this->ConvertSize($v,$this->blk[$prevlevel]['inner_width'],$this->FontSize,false);
+ break;
+ case 'MARGIN-LEFT':
+ $this->blk[$this->blklvl]['margin_left'] = $this->ConvertSize($v,$this->blk[$prevlevel]['inner_width'],$this->FontSize,false);
+ break;
+ case 'MARGIN-RIGHT':
+ $this->blk[$this->blklvl]['margin_right'] = $this->ConvertSize($v,$this->blk[$prevlevel]['inner_width'],$this->FontSize,false);
+ break;
+
+/*-- BORDER-RADIUS --*/
+ case 'BORDER-TOP-LEFT-RADIUS-H':
+ $this->blk[$this->blklvl]['border_radius_TL_H'] = $this->ConvertSize($v,$this->blk[$prevlevel]['inner_width'],$this->FontSize,false);
+ break;
+ case 'BORDER-TOP-LEFT-RADIUS-V':
+ $this->blk[$this->blklvl]['border_radius_TL_V'] = $this->ConvertSize($v,$this->blk[$prevlevel]['inner_width'],$this->FontSize,false);
+ break;
+ case 'BORDER-TOP-RIGHT-RADIUS-H':
+ $this->blk[$this->blklvl]['border_radius_TR_H'] = $this->ConvertSize($v,$this->blk[$prevlevel]['inner_width'],$this->FontSize,false);
+ break;
+ case 'BORDER-TOP-RIGHT-RADIUS-V':
+ $this->blk[$this->blklvl]['border_radius_TR_V'] = $this->ConvertSize($v,$this->blk[$prevlevel]['inner_width'],$this->FontSize,false);
+ break;
+ case 'BORDER-BOTTOM-LEFT-RADIUS-H':
+ $this->blk[$this->blklvl]['border_radius_BL_H'] = $this->ConvertSize($v,$this->blk[$prevlevel]['inner_width'],$this->FontSize,false);
+ break;
+ case 'BORDER-BOTTOM-LEFT-RADIUS-V':
+ $this->blk[$this->blklvl]['border_radius_BL_V'] = $this->ConvertSize($v,$this->blk[$prevlevel]['inner_width'],$this->FontSize,false);
+ break;
+ case 'BORDER-BOTTOM-RIGHT-RADIUS-H':
+ $this->blk[$this->blklvl]['border_radius_BR_H'] = $this->ConvertSize($v,$this->blk[$prevlevel]['inner_width'],$this->FontSize,false);
+ break;
+ case 'BORDER-BOTTOM-RIGHT-RADIUS-V':
+ $this->blk[$this->blklvl]['border_radius_BR_V'] = $this->ConvertSize($v,$this->blk[$prevlevel]['inner_width'],$this->FontSize,false);
+ break;
+/*-- END BORDER-RADIUS --*/
+
+ case 'BOX-SHADOW':
+ $bs = $this->cssmgr->setCSSboxshadow($v);
+ if ($bs) { $this->blk[$this->blklvl]['box_shadow'] = $bs; }
+ break;
+
+ case 'BACKGROUND-CLIP':
+ if (strtoupper($v) == 'PADDING-BOX') { $this->blk[$this->blklvl]['background_clip'] = 'padding-box'; }
+ else if (strtoupper($v) == 'CONTENT-BOX') { $this->blk[$this->blklvl]['background_clip'] = 'content-box'; }
+ break;
+
+ case 'PAGE-BREAK-AFTER':
+ if (strtoupper($v) == 'AVOID') { $this->blk[$this->blklvl]['page_break_after_avoid'] = true; }
+ else if (strtoupper($v) == 'ALWAYS' || strtoupper($v) == 'LEFT' || strtoupper($v) == 'RIGHT') { $this->blk[$this->blklvl]['page_break_after'] = strtoupper($v) ; }
+ break;
+
+ // mPDF 6 pagebreaktype
+ case 'BOX-DECORATION-BREAK':
+ if (strtoupper($v) == 'CLONE') { $this->blk[$this->blklvl]['box_decoration_break'] = 'clone'; }
+ else if (strtoupper($v) == 'SLICE') { $this->blk[$this->blklvl]['box_decoration_break'] = 'slice'; }
+ break;
+
+ case 'WIDTH':
+ if (strtoupper($v) != 'AUTO') {
+ $this->blk[$this->blklvl]['css_set_width'] = $this->ConvertSize($v,$this->blk[$prevlevel]['inner_width'],$this->FontSize,false);
+ }
+ break;
+
+ // mPDF 6 Lists
+ // LISTS
+ case 'LIST-STYLE-TYPE':
+ $this->blk[$this->blklvl]['list_style_type'] = strtolower($v);
+ break;
+ case 'LIST-STYLE-IMAGE':
+ $this->blk[$this->blklvl]['list_style_image'] = strtolower($v);
+ break;
+ case 'LIST-STYLE-POSITION':
+ $this->blk[$this->blklvl]['list_style_position'] = strtolower($v);
+ break;
+
+
+ }//end of switch($k)
+ }
+
+
+ if ($type != 'INLINE' && $type != 'TABLECELL') { // All block-level, including BODY tag
+ switch($k){
+
+ case 'TEXT-INDENT':
+ // Computed value - to inherit
+ $this->blk[$this->blklvl]['text_indent'] = $this->ConvertSize($v,$this->blk[$prevlevel]['inner_width'],$this->FontSize,false).'mm';
+ break;
+
+ case 'MARGIN-COLLAPSE': // Custom tag to collapse margins at top and bottom of page
+ if (strtoupper($v) == 'COLLAPSE') { $this->blk[$this->blklvl]['margin_collapse'] = true; }
+ break;
+
+ case 'LINE-HEIGHT':
+ $this->blk[$this->blklvl]['line_height'] = $this->fixLineheight($v);
+ if (!$this->blk[$this->blklvl]['line_height'] ) { $this->blk[$this->blklvl]['line_height'] = 'N'; } // mPDF 6
+ break;
+
+ // mPDF 6
+ case 'LINE-STACKING-STRATEGY':
+ $this->blk[$this->blklvl]['line_stacking_strategy'] = strtolower($v);
+ break;
+
+ case 'LINE-STACKING-SHIFT':
+ $this->blk[$this->blklvl]['line_stacking_shift'] = strtolower($v);
+ break;
+
+ case 'TEXT-ALIGN': //left right center justify
+ switch (strtoupper($v)) {
+ case 'LEFT':
+ $this->blk[$this->blklvl]['align']="L";
+ break;
+ case 'CENTER':
+ $this->blk[$this->blklvl]['align']="C";
+ break;
+ case 'RIGHT':
+ $this->blk[$this->blklvl]['align']="R";
+ break;
+ case 'JUSTIFY':
+ $this->blk[$this->blklvl]['align']="J";
+ break;
+ }
+ break;
+
+/*-- BACKGROUNDS --*/
+ case 'BACKGROUND-GRADIENT':
+ if ($type == 'BLOCK') {
+ $this->blk[$this->blklvl]['gradient'] = $v;
+ }
+ break;
+/*-- END BACKGROUNDS --*/
+
+ case 'DIRECTION':
+ if ($v) { $this->blk[$this->blklvl]['direction'] = strtolower($v); }
+ break;
+
+ }//end of switch($k)
+ }
+
+ // FOR INLINE ONLY
+ if ($type == 'INLINE') {
+ switch($k){
+ case 'DISPLAY':
+ if (strtoupper($v) == 'NONE') { $this->inlineDisplayOff = true; }
+ break;
+ case 'DIRECTION':
+ break;
+ }//end of switch($k)
+ }
+ // FOR INLINE ONLY
+ if ($type == 'INLINE') {
+ switch($k){
+ // BORDERS
+ case 'BORDER-TOP':
+ $this->spanborddet['T'] = $this->border_details($v);
+ $this->spanborder = true;
+ $spanbordset = true;
+ break;
+ case 'BORDER-BOTTOM':
+ $this->spanborddet['B'] = $this->border_details($v);
+ $this->spanborder = true;
+ $spanbordset = true;
+ break;
+ case 'BORDER-LEFT':
+ $this->spanborddet['L'] = $this->border_details($v);
+ $this->spanborder = true;
+ $spanbordset = true;
+ break;
+ case 'BORDER-RIGHT':
+ $this->spanborddet['R'] = $this->border_details($v);
+ $this->spanborder = true;
+ $spanbordset = true;
+ break;
+ case 'VISIBILITY': // block is set in OpenTag
+ $v = strtolower($v);
+ if ($v == 'visible' || $v == 'hidden' || $v == 'printonly' || $v == 'screenonly') {
+ $this->textparam['visibility'] = $v;
+ }
+ break;
+ }//end of switch($k)
+ }
+
+ if ($type != 'TABLECELL') {
+ // FOR INLINE and BLOCK
+ switch($k){
+ case 'TEXT-ALIGN': //left right center justify
+ if (strtoupper($v) == 'NOJUSTIFY' && $this->blk[$this->blklvl]['align']=="J") {
+ $this->blk[$this->blklvl]['align']="";
+ }
+ break;
+ // bgcolor only - to stay consistent with original html2fpdf
+ case 'BACKGROUND':
+ case 'BACKGROUND-COLOR':
+ $cor = $this->ConvertColor($v);
+ if ($cor) {
+ if ($tag == 'BODY') {
+ $this->bodyBackgroundColor = $cor;
+ }
+ else if ($type == 'INLINE') {
+ $this->spanbgcolorarray = $cor;
+ $this->spanbgcolor = true;
+ $spanbgset = true;
+ }
+ else {
+ $this->blk[$this->blklvl]['bgcolorarray'] = $cor;
+ $this->blk[$this->blklvl]['bgcolor'] = true;
+ }
+ }
+ else if ($type != 'INLINE') {
+ if ($this->ColActive) {
+ $this->blk[$this->blklvl]['bgcolorarray'] = $this->blk[$prevlevel]['bgcolorarray'] ;
+ $this->blk[$this->blklvl]['bgcolor'] = $this->blk[$prevlevel]['bgcolor'] ;
+ }
+ }
+ break;
+
+ case 'VERTICAL-ALIGN': //super and sub only dealt with here e.g. and
+ switch (strtoupper($v)) {
+ case 'SUPER':
+ $this->textvar = ($this->textvar | FA_SUPERSCRIPT); // mPDF 5.7.1
+ $this->textvar = ($this->textvar & ~FA_SUBSCRIPT);
+ // mPDF 5.7.3 inline text-decoration parameters
+ if (isset($this->textparam['text-baseline'])) { $this->textparam['text-baseline'] += ($this->baselineSup)*$preceeding_fontsize; }
+ else { $this->textparam['text-baseline'] = ($this->baselineSup)*$preceeding_fontsize; }
+ break;
+ case 'SUB':
+ $this->textvar = ($this->textvar | FA_SUBSCRIPT);
+ $this->textvar = ($this->textvar & ~FA_SUPERSCRIPT);
+ // mPDF 5.7.3 inline text-decoration parameters
+ if (isset($this->textparam['text-baseline'])) { $this->textparam['text-baseline'] += ($this->baselineSub)*$preceeding_fontsize; }
+ else { $this->textparam['text-baseline'] = ($this->baselineSub)*$preceeding_fontsize; }
+ break;
+ case 'BASELINE':
+ $this->textvar = ($this->textvar & ~FA_SUBSCRIPT);
+ $this->textvar = ($this->textvar & ~FA_SUPERSCRIPT);
+ // mPDF 5.7.3 inline text-decoration parameters
+ if (isset($this->textparam['text-baseline'])) { unset($this->textparam['text-baseline']); }
+ break;
+ // mPDF 5.7.3 inline text-decoration parameters
+ default:
+ $lh = $this->_computeLineheight($this->blk[$this->blklvl]['line_height']);
+ $sz = $this->ConvertSize($v,$lh,$this->FontSize,false);
+ $this->textvar = ($this->textvar & ~FA_SUBSCRIPT);
+ $this->textvar = ($this->textvar & ~FA_SUPERSCRIPT);
+ if ($sz) {
+ if ($sz > 0) {
+ $this->textvar = ($this->textvar | FA_SUPERSCRIPT);
+ }
+ else {
+ $this->textvar = ($this->textvar | FA_SUBSCRIPT);
+ }
+ if (isset($this->textparam['text-baseline'])) { $this->textparam['text-baseline'] += $sz; }
+ else { $this->textparam['text-baseline'] = $sz; }
+ }
+
+ }
+ break;
+ }//end of switch($k)
+ }
+
+
+ // FOR ALL
+ switch($k){
+ case 'LETTER-SPACING':
+ $this->lSpacingCSS = $v;
+ if (($this->lSpacingCSS || $this->lSpacingCSS==='0') && strtoupper($this->lSpacingCSS) != 'NORMAL') {
+ $this->fixedlSpacing = $this->ConvertSize($this->lSpacingCSS,$this->FontSize);
+ }
+ break;
+
+ case 'WORD-SPACING':
+ $this->wSpacingCSS = $v;
+ if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') {
+ $this->minwSpacing = $this->ConvertSize($this->wSpacingCSS,$this->FontSize);
+ }
+ break;
+
+ case 'FONT-STYLE': // italic normal oblique
+ switch (strtoupper($v)) {
+ case 'ITALIC':
+ case 'OBLIQUE':
+ $this->SetStyle('I',true);
+ break;
+ case 'NORMAL':
+ $this->SetStyle('I',false);
+ break;
+ }
+ break;
+
+ case 'FONT-WEIGHT': // normal bold //Does not support: bolder, lighter, 100..900(step value=100)
+ switch (strtoupper($v)) {
+ case 'BOLD':
+ $this->SetStyle('B',true);
+ break;
+ case 'NORMAL':
+ $this->SetStyle('B',false);
+ break;
+ }
+ break;
+
+ case 'FONT-KERNING':
+ if (strtoupper($v) == 'NORMAL' || (strtoupper($v) == 'AUTO' && $this->useKerning)) {
+/*-- OTL --*/
+ if ($this->CurrentFont['haskernGPOS']) {
+ if (isset($this->OTLtags['Plus'])) { $this->OTLtags['Plus'] .= ' kern'; }
+ else { $this->OTLtags['Plus'] = ' kern'; }
+ }
+/*-- END OTL --*/
+ else { // *OTL*
+ $this->textvar = ($this->textvar | FC_KERNING);
+ } // *OTL*
+ }
+ else if (strtoupper($v) == 'NONE' || (strtoupper($v) == 'AUTO' && !$this->useKerning)) {
+ if (isset($this->OTLtags['Plus'])) $this->OTLtags['Plus'] = str_replace('kern','', $this->OTLtags['Plus'] ); // *OTL*
+ if (isset($this->OTLtags['FFPlus'])) $this->OTLtags['FFPlus'] = preg_replace('/kern[\d]*/', '', $this->OTLtags['FFPlus'] );
+ $this->textvar = ($this->textvar & ~FC_KERNING);
+ }
+ break;
+
+/*-- OTL --*/
+ case 'FONT-LANGUAGE-OVERRIDE':
+ $v =strtoupper($v);
+ if (strpos($v, 'NORMAL')!==false) { $this->fontLanguageOverride = ''; }
+ else { $this->fontLanguageOverride = trim($v); }
+ break;
+
+
+ case 'FONT-VARIANT-POSITION':
+ if (isset($this->OTLtags['Plus'])) $this->OTLtags['Plus'] = str_replace(array('sups','subs'),'', $this->OTLtags['Plus']);
+ switch (strtoupper($v)) {
+ case 'SUPER':
+ $this->OTLtags['Plus'] .= ' sups';
+ break;
+ case 'SUB':
+ $this->OTLtags['Plus'] .= ' subs';
+ break;
+ case 'NORMAL':
+ break;
+ }
+ break;
+
+ case 'FONT-VARIANT-CAPS':
+ $v =strtoupper($v);
+ if (!isset($this->OTLtags['Plus'])) { $this->OTLtags['Plus'] = ''; }
+ $this->OTLtags['Plus'] = str_replace(array('c2sc','smcp','c2pc','pcap','unic','titl'),'', $this->OTLtags['Plus']);
+ $this->textvar = ($this->textvar & ~FC_SMALLCAPS); // ??????????????
+ if (strpos($v, 'ALL-SMALL-CAPS')!==false) { $this->OTLtags['Plus'] .= ' c2sc smcp'; }
+ else if (strpos($v, 'SMALL-CAPS')!==false) {
+ if (isset($this->CurrentFont['hassmallcapsGSUB']) && $this->CurrentFont['hassmallcapsGSUB']) { $this->OTLtags['Plus'] .= ' smcp'; }
+ else { $this->textvar = ($this->textvar | FC_SMALLCAPS); }
+ }
+ else if (strpos($v, 'ALL-PETITE-CAPS')!==false) { $this->OTLtags['Plus'] .= ' c2pc pcap'; }
+ else if (strpos($v, 'PETITE-CAPS')!==false) { $this->OTLtags['Plus'] .= ' pcap'; }
+ else if (strpos($v, 'UNICASE')!==false) { $this->OTLtags['Plus'] .= ' unic'; }
+ else if (strpos($v, 'TITLING-CAPS')!==false) { $this->OTLtags['Plus'] .= ' titl'; }
+ break;
+
+ case 'FONT-VARIANT-LIGATURES':
+ $v =strtoupper($v);
+ if (!isset($this->OTLtags['Plus'])) { $this->OTLtags['Plus'] = ''; }
+ if (!isset($this->OTLtags['Minus'])) { $this->OTLtags['Minus'] = ''; }
+ if (strpos($v, 'NORMAL')!==false) {
+ $this->OTLtags['Minus'] = str_replace(array('liga','clig','calt'),'', $this->OTLtags['Minus']);
+ $this->OTLtags['Plus'] = str_replace(array('dlig','hlig'),'', $this->OTLtags['Plus']);
+ }
+ else if (strpos($v, 'NONE')!==false) {
+ $this->OTLtags['Minus'] .= ' liga clig calt';
+ $this->OTLtags['Plus'] = str_replace(array('dlig','hlig'),'', $this->OTLtags['Plus']);
+ }
+ if (strpos($v, 'NO-COMMON-LIGATURES')!==false) { $this->OTLtags['Minus'] .= ' liga clig'; }
+ else if (strpos($v, 'COMMON-LIGATURES')!==false) { $this->OTLtags['Minus'] = str_replace(array('liga','clig'),'', $this->OTLtags['Minus']); }
+ if (strpos($v, 'NO-CONTEXTUAL')!==false) { $this->OTLtags['Minus'] .= ' calt'; }
+ else if (strpos($v, 'CONTEXTUAL')!==false) { $this->OTLtags['Minus'] = str_replace('calt','', $this->OTLtags['Minus']); }
+ if (strpos($v, 'NO-DISCRETIONARY-LIGATURES')!==false) { $this->OTLtags['Plus'] = str_replace('dlig','', $this->OTLtags['Plus'] ); }
+ else if (strpos($v, 'DISCRETIONARY-LIGATURES')!==false) { $this->OTLtags['Plus'] .= ' dlig'; }
+ if (strpos($v, 'NO-HISTORICAL-LIGATURES')!==false) { $this->OTLtags['Plus'] = str_replace('hlig','', $this->OTLtags['Plus'] ); }
+ else if (strpos($v, 'HISTORICAL-LIGATURES')!==false) { $this->OTLtags['Plus'] .= ' hlig'; }
+
+ break;
+
+ case 'FONT-VARIANT-NUMERIC':
+ $v =strtoupper($v);
+ if (!isset($this->OTLtags['Plus'])) { $this->OTLtags['Plus'] = ''; }
+ if (strpos($v, 'NORMAL')!==false) {
+ $this->OTLtags['Plus'] = str_replace(array('ordn','zero','lnum','onum','pnum','tnum','frac','afrc'),'', $this->OTLtags['Plus']);
+ }
+ if (strpos($v, 'ORDINAL')!==false) { $this->OTLtags['Plus'] .= ' ordn'; }
+ if (strpos($v, 'SLASHED-ZERO')!==false) { $this->OTLtags['Plus'] .= ' zero'; }
+ if (strpos($v, 'LINING-NUMS')!==false) { $this->OTLtags['Plus'] .= ' lnum'; $this->OTLtags['Plus'] = str_replace('onum','', $this->OTLtags['Plus'] ); }
+ else if (strpos($v, 'OLDSTYLE-NUMS')!==false) { $this->OTLtags['Plus'] .= ' onum'; $this->OTLtags['Plus'] = str_replace('lnum','', $this->OTLtags['Plus'] ); }
+ if (strpos($v, 'PROPORTIONAL-NUMS')!==false) { $this->OTLtags['Plus'] .= ' pnum'; $this->OTLtags['Plus'] = str_replace('tnum','', $this->OTLtags['Plus'] ); }
+ else if (strpos($v, 'TABULAR-NUMS')!==false) { $this->OTLtags['Plus'] .= ' tnum'; $this->OTLtags['Plus'] = str_replace('pnum','', $this->OTLtags['Plus'] ); }
+ if (strpos($v, 'DIAGONAL-FRACTIONS')!==false) { $this->OTLtags['Plus'] .= ' frac'; $this->OTLtags['Plus'] = str_replace('afrc','', $this->OTLtags['Plus'] ); }
+ else if (strpos($v, 'STACKED-FRACTIONS')!==false) { $this->OTLtags['Plus'] .= ' afrc'; $this->OTLtags['Plus'] = str_replace('frac','', $this->OTLtags['Plus'] ); }
+ break;
+
+ case 'FONT-VARIANT-ALTERNATES': // Only supports historical-forms
+ $v =strtoupper($v);
+ if (!isset($this->OTLtags['Plus'])) { $this->OTLtags['Plus'] = ''; }
+ if (strpos($v, 'NORMAL')!==false) {
+ $this->OTLtags['Plus'] = str_replace('hist','', $this->OTLtags['Plus']);
+ }
+ if (strpos($v, 'HISTORICAL-FORMS')!==false) { $this->OTLtags['Plus'] .= ' hist'; }
+ break;
+
+
+ case 'FONT-FEATURE-SETTINGS':
+ $v =strtolower($v);
+ if (strpos($v, 'normal')!==false) {
+ $this->OTLtags['FFMinus'] = '';
+ $this->OTLtags['FFPlus'] = '';
+ }
+ else {
+ if (!isset($this->OTLtags['FFPlus'])) { $this->OTLtags['FFPlus'] = ''; }
+ if (!isset($this->OTLtags['FFMinus'])) { $this->OTLtags['FFMinus'] = ''; }
+ $tags = preg_split('/[,]/',$v);
+ foreach($tags AS $t) {
+ if(preg_match('/[\"\']([a-zA-Z0-9]{4})[\"\']\s*(on|off|\d*){0,1}/', $t, $m)) {
+ if ($m[2]=='off' || $m[2]==='0') {
+ if (strpos($this->OTLtags['FFMinus'],$m[1])===false) { $this->OTLtags['FFMinus'] .= ' '.$m[1]; }
+ $this->OTLtags['FFPlus'] = preg_replace('/'.$m[1].'[\d]*/', '', $this->OTLtags['FFPlus'] );
+ }
+ else {
+ if ($m[2]=='on') { $m[2] = '1'; }
+ if (strpos($this->OTLtags['FFPlus'],$m[1])===false) { $this->OTLtags['FFPlus'] .= ' '.$m[1].$m[2]; }
+ $this->OTLtags['FFMinus'] = str_replace($m[1],'', $this->OTLtags['FFMinus'] );
+ }
+ }
+ }
+ }
+ break;
+/*-- END OTL --*/
+
+
+ case 'TEXT-TRANSFORM': // none uppercase lowercase //Does support: capitalize
+ switch (strtoupper($v)) { //Not working 100%
+ case 'CAPITALIZE':
+ $this->textvar = ($this->textvar | FT_CAPITALIZE); // mPDF 5.7.1
+ $this->textvar = ($this->textvar & ~FT_UPPERCASE); // mPDF 5.7.1
+ $this->textvar = ($this->textvar & ~FT_LOWERCASE); // mPDF 5.7.1
+ break;
+ case 'UPPERCASE':
+ $this->textvar = ($this->textvar | FT_UPPERCASE); // mPDF 5.7.1
+ $this->textvar = ($this->textvar & ~FT_LOWERCASE); // mPDF 5.7.1
+ $this->textvar = ($this->textvar & ~FT_CAPITALIZE); // mPDF 5.7.1
+ break;
+ case 'LOWERCASE':
+ $this->textvar = ($this->textvar | FT_LOWERCASE); // mPDF 5.7.1
+ $this->textvar = ($this->textvar & ~FT_UPPERCASE); // mPDF 5.7.1
+ $this->textvar = ($this->textvar & ~FT_CAPITALIZE); // mPDF 5.7.1
+ break;
+ case 'NONE': break;
+ $this->textvar = ($this->textvar & ~FT_UPPERCASE); // mPDF 5.7.1
+ $this->textvar = ($this->textvar & ~FT_LOWERCASE); // mPDF 5.7.1
+ $this->textvar = ($this->textvar & ~FT_CAPITALIZE); // mPDF 5.7.1
+ }
+ break;
+
+ case 'TEXT-SHADOW':
+ $ts = $this->cssmgr->setCSStextshadow($v);
+ if ($ts) { $this->textshadow = $ts; }
+ break;
+
+ case 'HYPHENS':
+ if (strtoupper($v)=='NONE') {
+ $this->textparam['hyphens'] = 2;
+ }
+ else if (strtoupper($v)=='AUTO') {
+ $this->textparam['hyphens'] = 1;
+ }
+ else if (strtoupper($v)=='MANUAL') {
+ $this->textparam['hyphens'] = 0;
+ }
+ break;
+
+ case 'TEXT-OUTLINE':
+ if (strtoupper($v)=='NONE') {
+ $this->textparam['outline-s'] = false;
+ }
+ break;
+
+ case 'TEXT-OUTLINE-WIDTH':
+ case 'OUTLINE-WIDTH':
+ switch(strtoupper($v)) {
+ case 'THIN': $v = '0.03em'; break;
+ case 'MEDIUM': $v = '0.05em'; break;
+ case 'THICK': $v = '0.07em'; break;
+ }
+ $w = $this->ConvertSize($v,$this->FontSize,$this->FontSize);
+ if ($w) {
+ $this->textparam['outline-WIDTH'] = $w;
+ $this->textparam['outline-s'] = true;
+ }
+ else { $this->textparam['outline-s'] = false; }
+ break;
+
+ case 'TEXT-OUTLINE-COLOR':
+ case 'OUTLINE-COLOR':
+ if (strtoupper($v) == 'INVERT') {
+ if ($this->colorarray) {
+ $cor = $this->colorarray;
+ $this->textparam['outline-COLOR'] = $this->_invertColor($cor);
+ }
+ else {
+ $this->textparam['outline-COLOR'] = $this->ConvertColor(255);
+ }
+ }
+ else {
+ $cor = $this->ConvertColor($v);
+ if ($cor) { $this->textparam['outline-COLOR'] = $cor ; }
+ }
+ break;
+
+ case 'COLOR': // font color
+ $cor = $this->ConvertColor($v);
+ if ($cor) {
+ $this->colorarray = $cor;
+ $this->SetTColor($cor);
+ }
+ break;
+
+
+ }//end of switch($k)
+
+
+ }//end of foreach
+
+ // mPDF 5.7.3 inline text-decoration parameters
+ // Needs to be set at the end - after vertical-align = super/sub, so that textparam['text-baseline'] is set
+ if (isset($arrayaux['TEXT-DECORATION'])) {
+ $v = $arrayaux['TEXT-DECORATION']; // none underline line-through (strikeout) //Does not support: blink
+ if (stristr($v,'LINE-THROUGH')) {
+ $this->textvar = ($this->textvar | FD_LINETHROUGH);
+ // mPDF 5.7.3 inline text-decoration parameters
+ if (isset($this->textparam['text-baseline'])) { $this->textparam['s-decoration']['baseline'] = $this->textparam['text-baseline']; }
+ else { $this->textparam['s-decoration']['baseline'] = 0; }
+ $this->textparam['s-decoration']['fontkey'] = $this->FontFamily . $this->FontStyle;
+ $this->textparam['s-decoration']['fontsize'] = $this->FontSize;
+ $this->textparam['s-decoration']['color'] = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
+ }
+ if (stristr($v,'UNDERLINE')) {
+ $this->textvar = ($this->textvar | FD_UNDERLINE);
+ // mPDF 5.7.3 inline text-decoration parameters
+ if (isset($this->textparam['text-baseline'])) { $this->textparam['u-decoration']['baseline'] = $this->textparam['text-baseline']; }
+ else { $this->textparam['u-decoration']['baseline'] = 0; }
+ $this->textparam['u-decoration']['fontkey'] = $this->FontFamily . $this->FontStyle;
+ $this->textparam['u-decoration']['fontsize'] = $this->FontSize;
+ $this->textparam['u-decoration']['color'] = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
+ }
+ if (stristr($v,'OVERLINE')) {
+ $this->textvar = ($this->textvar | FD_OVERLINE);
+ // mPDF 5.7.3 inline text-decoration parameters
+ if (isset($this->textparam['text-baseline'])) { $this->textparam['o-decoration']['baseline'] = $this->textparam['text-baseline']; }
+ else { $this->textparam['o-decoration']['baseline'] = 0; }
+ $this->textparam['o-decoration']['fontkey'] = $this->FontFamily . $this->FontStyle;
+ $this->textparam['o-decoration']['fontsize'] = $this->FontSize;
+ $this->textparam['o-decoration']['color'] = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG
+ }
+ if (stristr($v,'NONE')) {
+ $this->textvar = ($this->textvar & ~FD_UNDERLINE);
+ $this->textvar = ($this->textvar & ~FD_LINETHROUGH);
+ $this->textvar = ($this->textvar & ~FD_OVERLINE);
+ // mPDF 5.7.3 inline text-decoration parameters
+ if (isset($this->textparam['u-decoration'])) { unset($this->textparam['u-decoration']); }
+ if (isset($this->textparam['s-decoration'])) { unset($this->textparam['s-decoration']); }
+ if (isset($this->textparam['o-decoration'])) { unset($this->textparam['o-decoration']); }
+ }
+ }
+ // mPDF 6
+ if ($spanbordset) { // BORDER has been set on this INLINE element
+ if (isset($this->textparam['text-baseline'])) { $this->textparam['bord-decoration']['baseline'] = $this->textparam['text-baseline']; }
+ else { $this->textparam['bord-decoration']['baseline'] = 0; }
+ $this->textparam['bord-decoration']['fontkey'] = $this->FontFamily . $this->FontStyle;
+ $this->textparam['bord-decoration']['fontsize'] = $this->FontSize;
+ }
+ if ($spanbgset) { // BACKGROUND[-COLOR] has been set on this INLINE element
+ if (isset($this->textparam['text-baseline'])) { $this->textparam['bg-decoration']['baseline'] = $this->textparam['text-baseline']; }
+ else { $this->textparam['bg-decoration']['baseline'] = 0; }
+ $this->textparam['bg-decoration']['fontkey'] = $this->FontFamily . $this->FontStyle;
+ $this->textparam['bg-decoration']['fontsize'] = $this->FontSize;
+ }
+
+
+}
+
+/*-- END HTML-CSS --*/
+
+
+function SetStyle($tag,$enable) {
+ $this->$tag=$enable;
+ $style='';
+ foreach(array('B','I') as $s) {
+ if($this->$s) {
+ $style.=$s;
+ }
+ }
+ $this->currentfontstyle=$style;
+ $this->SetFont('',$style,0,false);
+}
+
+// Set multiple styles at one time
+function SetStylesArray($arr) {
+ $style='';
+ foreach(array('B','I') as $s) {
+ if (isset($arr[$s])) {
+ if ($arr[$s]) {
+ $this->$s = true;
+ $style.=$s;
+ }
+ else { $this->$s = false; }
+ }
+ else if ($this->$s) { $style.=$s; }
+ }
+ $this->currentfontstyle=$style;
+ $this->SetFont('',$style,0,false);
+}
+
+// Set multiple styles at one $str e.g. "BI"
+function SetStyles($str) {
+ $style='';
+ foreach(array('B','I') as $s) {
+ if (strpos($str,$s) !== false) {
+ $this->$s = true;
+ $style.=$s;
+ }
+ else { $this->$s = false; }
+ }
+ $this->currentfontstyle=$style;
+ $this->SetFont('',$style,0,false);
+}
+
+function ResetStyles() {
+ foreach(array('B','I') as $s) {
+ $this->$s = false;
+ }
+ $this->currentfontstyle='';
+ $this->SetFont('','',0,false);
+}
+
+
+function DisableTags($str='') {
+ if ($str == '') { //enable all tags
+ //Insert new supported tags in the long string below.
+ $this->enabledtags = " |
|---|
| |