pdf = new PDF($this->orientation, parent::unit, array($this->pagew, $this->pageh), self::unicode, $this->charset, self::diskcache);
// Setup the PDF margins
$this->pdf->setMargins($this->leftmargin, $this->topmargin, $this->rightmargin);
$this->pdf->SetHeaderMargin($this->headermargin);
$this->pdf->SetFooterMargin($this->footermargin);
//Set auto page breaks
$this->pdf->SetAutoPageBreak(true, $this->bottommargin);
// Setup PDF compression
$this->pdf->SetCompression(self::compression);
// Setup RTL support
$this->pdf->setRTL($this->rtl);
// Set the document information
// Only admin should see the version number
$appversion = WT_WEBTREES;
if (WT_USER_IS_ADMIN) {
$appversion .= " ".WT_VERSION_TEXT;
}
$this->pdf->SetCreator($appversion." (".parent::pgv_url.")");
// Not implemented yet - ReportBase::setup()
//$this->pdf->SetAuthor($this->rauthor);
$this->pdf->SetTitle($this->title);
$this->pdf->SetSubject($this->rsubject);
$this->pdf->SetKeywords($this->rkeywords);
$this->pdf->setReport($this);
if ($this->showGenText) {
// The default style name for Generated by.... is 'genby'
$element = new CellPDF(0, 10, 0, "C", "", "genby", 1, ".", ".", 0, 0, "", "", true);
$element->addText($this->generatedby);
$element->setUrl(parent::pgv_url);
$this->pdf->addFooter($element);
}
}
/**
* Add an element - ReportBasePDF
* @param object|string &$element Object or string
*/
function addElement($element) {
if ($this->processing == "B") {
return $this->pdf->addBody($element);
} elseif ($this->processing == "H") {
return $this->pdf->addHeader($element);
} elseif ($this->processing == "F") {
return $this->pdf->addFooter($element);
}
return 0;
}
function run() {
$this->pdf->Body();
header('Expires:');
header('Pragma:');
header('Cache-control:');
$this->pdf->Output('webtrees_'.basename(dirname($_REQUEST['report'])).'.pdf', 'I');
}
/**
* Clear the Header - ReportBasePDF
*/
function clearHeader() {
$this->pdf->clearHeader();
}
/**
* Clear the Page Header - ReportBasePDF
*/
function clearPageHeader() {
$this->pdf->clearPageHeader();
}
/**
* Create a new Cell object - ReportBasePDF
*
* @param int $width cell width (expressed in points)
* @param int $height cell height (expressed in points)
* @param mixed $border Border style
* @param string $align Text alignement
* @param string $bgcolor Background color code
* @param string $style The name of the text style
* @param int $ln Indicates where the current position should go after the call
* @param mixed $top Y-position
* @param mixed $left X-position
* @param int $fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 1
* @param int $stretch Stretch carachter mode
* @param string $bocolor Border color
* @param string $tcolor Text color
* @param bolean $reseth
* @return CellPDF
*/
function createCell($width, $height, $border, $align, $bgcolor, $style, $ln, $top, $left, $fill, $stretch, $bocolor, $tcolor, $reseth) {
return new CellPDF($width, $height, $border, $align, $bgcolor, $style, $ln, $top, $left, $fill, $stretch, $bocolor, $tcolor, $reseth);
}
/**
* Create a new TextBox object - ReportBasePDF
*
* @param float $width Text box width
* @param float $height Text box height
* @param boolean $border
* @param string $bgcolor Background color code in HTML
* @param boolean $newline
* @param mixed $left
* @param mixed $top
* @param boolean $pagecheck
* @param string $style
* @param boolean $fill
* @param boolean $padding
* @param boolaen $reseth
* @return TextBoxPDF
*/
function createTextBox($width, $height, $border, $bgcolor, $newline, $left, $top, $pagecheck, $style, $fill, $padding, $reseth) {
return new TextBoxPDF($width, $height, $border, $bgcolor, $newline, $left, $top, $pagecheck, $style, $fill, $padding, $reseth);
}
/**
* Create a new Text object- ReportBasePDF
*
* @param string $style The name of the text style
* @param string $color HTML color code
* @return TextPDF
*/
function createText($style, $color) {
return new TextPDF($style, $color);
}
/**
* Create a new Footnote object - ReportBasePDF
* @param string $style Style name
* @return FootnotePDF
*/
function createFootnote($style) {
return new FootnotePDF($style);
}
/**
* Create a new Page Header object - ReportBasePDF
* @return PageHeaderPDF
*/
function createPageHeader() {
return new PageHeaderPDF();
}
/**
* Create a new image object - ReportBasePDF
* @param string $file File name
* @param mixed $x
* @param mixed $y
* @param int $w Image width
* @param int $h Image height
* @param string $align L:left, C:center, R:right or empty to use x/y
* @param string $ln T:same line, N:next line
* @return ImagePDF
*/
function createImage($file, $x, $y, $w, $h, $align, $ln) {
return new ImagePDF($file, $x, $y, $w, $h, $align, $ln);
}
/**
* Create a new line object - ReportBasePDF
* @param mixed $x1
* @param mixed $y1
* @param mixed $x2
* @param mixed $y2
* @return LinePDF
*/
function createLine($x1, $y1, $x2, $y2) {
return new LinePDF($x1, $y1, $x2, $y2);
}
/**
* @return HtmlPDF
*/
function createHTML($tag, $attrs) {
return new HtmlPDF($tag, $attrs);
}
} //-- end Report
/**
* WT Report PDF Class
*
* This class inherits from the TCPDF class and is used to generate the PDF document
* @package webtrees
* @subpackage Reports
*/
class PDF extends TCPDF {
/**
* Array of elements in the header
* @var array
*/
public $headerElements = array();
/**
* Array of elements in the page header
* @var array
*/
public $pageHeaderElements = array();
/**
* Array of elements in the footer
* @var array
*/
public $footerElements = array();
/**
* Array of elements in the body
* @var array
*/
public $bodyElements = array();
/**
* Array of elements in the footer notes
* @var array
*/
public $printedfootnotes = array();
/**
* Currently used style name
* @var string
*/
public $currentStyle;
/**
* The last cell height
* @var int
*/
public $lastCellHeight = 0;
/**
* The largest font size within a TextBox
* to calculate the height
* @var int
*/
public $largestFontHeight = 0;
/**
* The last pictures page number
* @var int
*/
public $lastpicpage = 0;
public $wt_report;
/**
* PDF Header -PDF
*/
function Header() {
foreach($this->headerElements as $element) {
if (is_object($element)) {
$element->render($this);
} elseif (is_string($element) && $element=="footnotetexts") {
$this->Footnotes();
} elseif (is_string($element) && $element=="addpage") {
$this->newPage();
}
}
foreach($this->pageHeaderElements as $element) {
if (is_object($element)) {
$element->render($this);
} elseif (is_string($element) && $element=="footnotetexts") {
$this->Footnotes();
} elseif (is_string($element) && $element=="addpage") {
$this->newPage();
}
}
}
/**
* PDF Body -PDF
*/
function Body() {
$this->AddPage();
foreach($this->bodyElements as $key => $element) {
if (is_object($element)) {
$element->render($this);
} elseif (is_string($element) && $element=="footnotetexts") {
$this->Footnotes();
} elseif (is_string($element) && $element=="addpage") {
$this->newPage();
}
// Delete used elements in hope to reduce 'some' memory usage
unset($this->bodyElements[$key]);
}
}
/**
* PDF Footnotes -PDF
*/
function Footnotes() {
foreach($this->printedfootnotes as $element) {
if (($this->GetY() + $element->getFootnoteHeight($this)) > $this->getPageHeight()) {
$this->AddPage();
}
$element->renderFootnote($this);
if ($this->GetY() > $this->getPageHeight()) {
$this->AddPage();
}
}
}
/**
* PDF Footer -PDF
*/
function Footer() {
foreach($this->footerElements as $element) {
if (is_object($element)) {
$element->render($this);
} elseif (is_string($element) && $element=="footnotetexts") {
$this->Footnotes();
} elseif (is_string($element) && $element=="addpage") {
$this->newPage();
}
}
}
/**
* Add an element to the Header -PDF
* @param object|string &$element
* @return int The number of the Header elements
*/
function addHeader($element) {
$this->headerElements[] = $element;
return count($this->headerElements)-1;
}
/**
* Add an element to the Page Header -PDF
* @param object|string &$element
* @return int The number of the Page Header elements
*/
function addPageHeader($element) {
$this->pageHeaderElements[] = $element;
return count($this->pageHeaderElements)-1;
}
/**
* Add an element to the Body -PDF
* @param object|string &$element
* @return int The number of the Body elements
*/
function addBody($element) {
$this->bodyElements[] = $element;
return count($this->bodyElements)-1;
}
/**
* Add an element to the Footer -PDF
* @param object|string &$element
* @return int The number of the Footer elements
*/
function addFooter($element) {
$this->footerElements[] = $element;
return count($this->footerElements)-1;
}
function removeHeader($index) {
unset($this->headerElements[$index]);
}
function removePageHeader($index) {
unset($this->pageHeaderElements[$index]);
}
function removeBody($index) {
unset($this->bodyElements[$index]);
}
function removeFooter($index) {
unset($this->footerElements[$index]);
}
/**
* Clear the Header -PDF
*/
function clearHeader() {
unset($this->headerElements);
$this->headerElements = array();
}
/**
* Clear the Page Header -PDF
*/
function clearPageHeader() {
unset($this->pageHeaderElements);
$this->pageHeaderElements = array();
}
function setReport($r) {
$this->pgvreport = $r;
}
/**
* Get the currently used style name -PDF
* @return string
*/
function getCurrentStyle() {
return $this->currentStyle;
}
/**
* Setup a style for usage -PDF
* @param string $s Style name
*/
function setCurrentStyle($s) {
$this->currentStyle = $s;
$style = $this->pgvreport->getStyle($s);
$this->SetFont($style["font"], $style["style"], $style["size"]);
}
/**
* Get the style -PDF
* @param string $s Style name
* @return array
*/
function getStyle($s) {
if (!isset($this->pgvreport->Styles[$s])) {
$s = $this->getCurrentStyle();
$this->pgvreport->Styles[$s] = $s;
}
return $this->pgvreport->Styles[$s];
}
/**
* Add margin when static horizontal position is used -PDF
* RTL supported
* @param float $x Static position
* @return float
*/
function addMarginX($x) {
$m = $this->getMargins();
if ($this->getRTL()) {
$x += $m["right"];
} else {
$x += $m["left"];
}
$this->SetX($x);
return $x;
}
/**
* Get the maximum line width to draw from the curren position -PDF
* RTL supported
* @return float
*/
function getMaxLineWidth() {
$m = $this->getMargins();
if ($this->getRTL()){
return ($this->getRemainingWidth() + $m["right"]);
} else {
return ($this->getRemainingWidth() + $m["left"]);
}
}
function getFootnotesHeight() {
$h=0;
foreach($this->printedfootnotes as $element) {
$h+=$element->getHeight($this);
}
return $h;
}
/**
* Returns the the current font size height -PDF
* @return int
*/
function getCurrentStyleHeight() {
if (empty($this->currentStyle)) {
return $this->pgvreport->defaultFontSize;
}
$style = $this->pgvreport->getStyle($this->currentStyle);
return $style["size"];
}
/**
* Checks the Footnote and numbers them
*
* @param object &$footnote
* @return boolen false if not numbered befor | object if already numbered
*/
function checkFootnote(&$footnote) {
$ct = count($this->printedfootnotes);
$val = $footnote->getValue();
$i = 0;
while($i < $ct) {
if ($this->printedfootnotes[$i]->getValue() == $val) {
// If this footnote already exist then set up the numbers for this object
$footnote->setNum($i + 1);
$footnote->setAddlink($i + 1);
return $this->printedfootnotes[$i];
}
$i++;
}
// If this Footnote has not been set up yet
$footnote->setNum($ct + 1);
$footnote->setAddlink($this->AddLink());
$this->printedfootnotes[] = $footnote;
return false;
}
/**
* Used this function instead of AddPage()
* This function will make sure that images will not be overwritten
*/
function newPage() {
if ($this->lastpicpage > $this->getPage()){
$this->setPage($this->lastpicpage);
}
$this->AddPage();
}
/*******************************************
* TCPDF protected functions
*******************************************/
/**
* Add a page if needed -PDF
* @param $height Cell height. Default value: 0
* @return boolean true in case of page break, false otherwise
*/
function checkPageBreakPDF($height) {
return $this->checkPageBreak($height);
}
/**
* Returns the remaining width between the current position and margins -PDF
* @return float Remaining width
*/
function getRemainingWidthPDF() {
return $this->getRemainingWidth();
}
} //-- END PDF
/**
* Report Base object of ReportBase class inherited by ReportBasePDF
* @global ReportBasePDF $wt_report
*/
$wt_report = new ReportBasePDF();
$ReportRoot = $wt_report;
/**
* Cell element - PDF
*
* @package webtrees
* @subpackage Reports
*/
class CellPDF extends Cell {
/**
* Create a class CELL for PDF
*
* @param int $width cell width (expressed in points)
* @param int $height cell height (expressed in points)
* @param mixed $border Border style
* @param string $align Text alignement
* @param string $bgcolor Background color code
* @param string $style The name of the text style
* @param int $ln Indicates where the current position should go after the call
* @param mixed $top Y-position
* @param mixed $left X-position
* @param int $fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 1
* @param int $stretch Stretch carachter mode
* @param string $bocolor Border color
* @param string $tcolor Text color
* @param boolean $reseth
*/
function CellPDF($width, $height, $border, $align, $bgcolor, $style, $ln, $top, $left, $fill, $stretch, $bocolor, $tcolor, $reseth) {
parent::Cell($width, $height, $border, $align, $bgcolor, $style, $ln, $top, $left, $fill, $stretch, $bocolor, $tcolor, $reseth);
}
/**
* PDF Cell renderer
* @param PDF &$pdf
*/
function render(&$pdf) {
/**
* Use these variables to update/manipulate values
* Repeted classes would reupdate all their class variables again, Header/Page Header/Footer
* This is the bugfree version
*/
$cX = 0; // Class Left
// Set up the text style
if (($pdf->getCurrentStyle()) != ($this->styleName)) {
$pdf->setCurrentStyle($this->styleName);
}
$temptext = str_replace("#PAGENUM#", $pdf->PageNo(), $this->text);
$match = array();
// Indicates if the cell background must be painted (1) or transparent (0)
if ($this->fill == 1) {
if (!empty($this->bgcolor)) {
// HTML color to RGB
if (preg_match("/#?(..)(..)(..)/", $this->bgcolor, $match)) {
$r = hexdec($match[1]);
$g = hexdec($match[2]);
$b = hexdec($match[3]);
$pdf->SetFillColor($r, $g, $b);
}
}
// If no color set then don't fill
else $this->fill = 0;
}
// Paint the Border color if set
if (!empty($this->bocolor)) {
// HTML color to RGB
if (preg_match("/#?(..)(..)(..)/", $this->bocolor, $match)) {
$r = hexdec($match[1]);
$g = hexdec($match[2]);
$b = hexdec($match[3]);
$pdf->SetDrawColor($r, $g, $b);
}
}
// Paint the text color or they might use inherited colors by the previous function
if (preg_match("/#?(..)(..)(..)/", $this->tcolor, $match)) {
$r = hexdec($match[1]);
$g = hexdec($match[2]);
$b = hexdec($match[3]);
$pdf->SetTextColor($r, $g, $b);
} else {
$pdf->SetTextColor(0, 0, 0);
}
// If current position (left)
if ($this->left == ".") {
$cX = $pdf->GetX();
}
// For static position add margin (also updates X)
else $cX = $pdf->addMarginX($this->left);
// Check the width if set to page wide OR set by xml to larger then page wide
if (($this->width == 0) or ($this->width > $pdf->getRemainingWidthPDF())) {
$this->width = $pdf->getRemainingWidthPDF();
}
// For current position
if ($this->top == ".") {
$this->top = $pdf->GetY();
} else {
$pdf->SetY($this->top);
}
// Check the last cell height and adjust the current cell height if needed
if ($pdf->lastCellHeight > $this->height) {
$this->height = $pdf->lastCellHeight;
}
// Check for pagebreak
if (!empty($temptext)) {
$cHT = $pdf->getNumLines($temptext, $this->width);
$cHT = $cHT * $pdf->getCellHeightRatio() * $pdf->getCurrentStyleHeight();
$cM = $pdf->getMargins();
// Add padding
$cHT += ($cM["cell"] * 2);
// Add a new page if needed
if ($pdf->checkPageBreakPDF($cHT)) {
$this->top = $pdf->GetY();
}
$temptext = spanLTRRTL($temptext, "BOTH");
}
// HTML ready - last value is true
$pdf->MultiCell($this->width, $this->height, $temptext, $this->border, $this->align, $this->fill, $this->newline, $cX, $this->top, $this->reseth, $this->stretch, true);
// Reset the last cell height for the next line
if ($this->newline >= 1) {
$pdf->lastCellHeight = 0;
}
// OR save the last height if heigher then before
elseif ($pdf->lastCellHeight < $pdf->getLastH()) {
$pdf->lastCellHeight = $pdf->getLastH();
}
// Set up the url link if exists ontop of the cell
if (!empty($this->url)) {
$pdf->Link($cX, $this->top, $this->width, $this->height, $this->url);
}
// Reset the border and the text color to black or they will be inherited
$pdf->SetDrawColor(0, 0, 0);
$pdf->SetTextColor(0, 0, 0);
}
}
/**
* HTML element - PDF Report
*
* @package webtrees
* @subpackage Reports
* @todo add info
*/
class HtmlPDF extends Html {
function HtmlPDF($tag, $attrs) {
parent::Html($tag, $attrs);
}
function render(&$pdf, $sub = false) {
if (!empty($this->attrs["pgvrstyle"])) {
$pdf->setCurrentStyle($this->attrs["pgvrstyle"]);
}
if (!empty($this->attrs["width"])) {
$this->attrs["width"] *= 3.9;
}
$this->text = $this->getStart().$this->text;
foreach($this->elements as $element) {
if (is_string($element) && $element=="footnotetexts") {
$pdf->Footnotes();
} elseif (is_string($element) && $element=="addpage") {
$pdf->newPage();
} elseif ($element->get_type()=="Html") {
$this->text .= $element->render($pdf, true);
} else {
$element->render($pdf);
}
}
$this->text .= $this->getEnd();
if ($sub) {
return $this->text;
}
$pdf->writeHTML($this->text); //prints 2 empty cells in the Expanded Relatives report
return 0;
}
}
/**
* TextBox element
*
* @package webtrees
* @subpackage Reports
* @todo add info
*/
class TextBoxPDF extends TextBox {
/**
* Create a class Text Box for PDF
*
* @param float $width Text box width
* @param float $height Text box height
* @param boolean $border
* @param string $bgcolor Background color code in HTML
* @param boolean $newline
* @param mixed $left
* @param mixed $top
* @param boolean $pagecheck
* @param string $style
* @param boolean $fill
* @param boolean $padding
* @param boolean $reseth Reset the last height after this bos is done
*/
function TextBoxPDF($width, $height, $border, $bgcolor, $newline, $left, $top, $pagecheck, $style, $fill, $padding, $reseth) {
parent::TextBox($width, $height, $border, $bgcolor, $newline, $left, $top, $pagecheck, $style, $fill, $padding, $reseth);
}
/**
* PDF Text Box renderer
* @param PDF &$pdf
*/
function render(&$pdf) {
$newelements = array();
$lastelement = "";
$footnote_element = array();
// Element counter
$cE = count($this->elements);
//-- collapse duplicate elements
for($i = 0; $i < $cE; $i++){
$element = $this->elements[$i];
if (is_object($element)){
if ($element->get_type() == "Text"){
if (!empty($footnote_element)){
ksort($footnote_element);
foreach ($footnote_element as $links){
$newelements[] = $links;
}
$footnote_element = array();
}
if (empty($lastelement)){
$lastelement = $element;
} else {
// Checking if the Text has the same style
if ($element->getStyleName() == $lastelement->getStyleName()){
$lastelement->addText(str_replace("\n", "
", $element->getValue()));
} elseif (!empty($lastelement)){
$newelements[] = $lastelement;
$lastelement = $element;
}
}
}
// Collect the Footnote links
elseif ($element->get_type() == "Footnote"){
// Check if the Footnote has been set with it's link number
$pdf->checkFootnote($element);
// Save first the last element if any
if (!empty($lastelement)){
$newelements[] = $lastelement;
$lastelement = array();
}
// Save the Footnote with it's link number as key for sorting later
$footnote_element[$element->num] = $element;
}
//-- do not keep empty footnotes
elseif (($element->get_type() != "Footnote") || (trim($element->getValue()) != "")){
if (!empty($footnote_element)){
ksort($footnote_element);
foreach ($footnote_element as $links){
$newelements[] = $links;
}
$footnote_element = array();
}
if (!empty($lastelement)){
$newelements[] = $lastelement;
$lastelement = array();
}
$newelements[] = $element;
}
} else {
if (!empty($lastelement)){
$newelements[] = $lastelement;
$lastelement = array();
}
if (!empty($footnote_element)){
ksort($footnote_element);
foreach ($footnote_element as $links){
$newelements[] = $links;
}
$footnote_element = array();
}
$newelements[] = $element;
}
}
if (!empty($lastelement)){
$newelements[] = $lastelement;
}
if (!empty($footnote_element)){
ksort($footnote_element);
foreach ($footnote_element as $links){
$newelements[] = $links;
}
}
$this->elements = $newelements;
unset($footnote_element, $lastelement, $links, $newelements);
/**
* Use these variables to update/manipulate values
* Repeted classes would reupdate all their class variables again, Header/Page Header/Footer
* This is the bugfree version
*/
$cH = 0; // Class Height
$cW = 0; // Class Width
$cX = 0; // Class Left
$cY = 0; // Class Top
// Used with line breaks and cell height calculation within this box
$pdf->largestFontHeight = 0;
// If current position (left)
if ($this->left == ".") {
$cX = $pdf->GetX();
}
// For static position add margin (returns and updates X)
else $cX = $pdf->addMarginX($this->left);
// If current position (top)
if ($this->top == ".") {
$cY = $pdf->GetY();
} else {
$cY = $this->top;
$pdf->SetY($cY);
}
// Check the width if set to page wide OR set by xml to larger then page width (margin)
if (($this->width == 0) or ($this->width > $pdf->getRemainingWidthPDF())) {
$cW = $pdf->getRemainingWidthPDF();
} else {
$cW = $this->width;
}
// Save the original margins
$cM = $pdf->getMargins();
// Use cell padding to wrap the width
// Temp Width with cell padding
$cWT = $cW - ($cM["cell"] * 2);
// Element height (exept text)
$eH = 0;
$w = 0;
// Temp Height
$cHT = 0;
//-- $lw is an array
// 0 => last line width
// 1 => 1 if text was wrapped, 0 if text did not wrap
// 2 => number of LF
$lw = array();
// Element counter
$cE = count($this->elements);
//-- calculate the text box height + width
for($i = 0; $i < $cE; $i++) {
if (is_object($this->elements[$i])) {
$ew = $this->elements[$i]->setWrapWidth($cWT - $w, $cWT);
if ($ew == $cWT) {
$w = 0;
}
$lw = $this->elements[$i]->getWidth($pdf);
// Text is already gets the # LF
$cHT += $lw[2];
if ($lw[1] == 1) {
$w = $lw[0];
} elseif ($lw[1] == 2) {
$w = 0;
} else {
$w += $lw[0];
}
if ($w > $cWT) {
$w = $lw[0];
}
// Footnote is at the bottom of the page. No need to calculate it's height or wrap the text!
// We are changing the margins anyway!
// For anything else but text (images), get the height
$eH += $this->elements[$i]->getHeight($pdf);
}
//else {
//$h += $pdf->getFootnotesHeight();
//}
}
// Add up what's the final height
$cH = $this->height;
// If any element exist
if ($cE > 0) {
// Check if this is text or some other element, like images
if ($eH == 0) {
// This is text elements. Number of LF but at least one line
$cHT = ($cHT + 1) * $pdf->getCellHeightRatio();
// Calculate the cell hight with the largest font size used within this Box
$cHT = $cHT * $pdf->largestFontHeight;
// Add cell padding
if ($this->padding) {
$cHT += ($cM["cell"] * 2);
}
if ($cH < $cHT) {
$cH = $cHT;
}
}
// This is any other element
elseif ($cH < $eH) {
$cH = $eH;
}
}
// Finaly, check the last cells height
if ($cH < $pdf->lastCellHeight) {
$cH = $pdf->lastCellHeight;
}
// Add a new page if needed
if ($this->pagecheck) {
// Reset last cell height or Header/Footer will inherit it, in case of pagebreak
$pdf->lastCellHeight = 0;
if ($pdf->checkPageBreakPDF($cH)) {
$cY = $pdf->GetY();
}
}
// Setup the border and background color
$cS = ""; // Class Style
if ($this->border) $cS = "D"; // D or empty string: Draw (default)
$match = array();
// Fill the background
if ($this->fill) {
if (!empty($this->bgcolor)) {
if (preg_match("/#?(..)(..)(..)/", $this->bgcolor, $match)) {
$cS .= "F"; // F: Fill the background
$r = hexdec($match[1]);
$g = hexdec($match[2]);
$b = hexdec($match[3]);
$pdf->SetFillColor($r, $g, $b);
}
}
}
// Clean up a bit
unset($lw, $w, $match, $cE, $eH);
// Draw the border
if (!empty($cS)) {
$pdf->Rect($cX, $cY, $cW, $cH, $cS);
}
// Add cell pedding if set and if any text (element) exist
if ($this->padding) {
if ($cHT > 0) {
$pdf->SetY($cY + $cM["cell"]);
}
}
// Change the margins X, Width
if (!$pdf->getRTL()) {
if ($this->padding){
$pdf->SetLeftMargin($cX + $cM["cell"]);
$pdf->SetRightMargin($pdf->getRemainingWidthPDF() - $cW + $cM["right"]);
}
else {
$pdf->SetLeftMargin($cX);
$pdf->SetRightMargin($pdf->getRemainingWidthPDF() - $cW + $cM["right"]);
}
} else {
if ($this->padding){
$pdf->SetRightMargin($cX + $cM["cell"]);
$pdf->SetLeftMargin($pdf->getRemainingWidthPDF() - $cW + $cM["left"]);
} else {
$pdf->SetRightMargin($cX);
$pdf->SetLeftMargin($pdf->getRemainingWidthPDF() - $cW + $cM["left"]);
}
}
// Save the current page number
$cPN = $pdf->getPage();
// Render the elements (write text, print picture...)
foreach($this->elements as $element) {
if (is_object($element)) {
$element->render($pdf);
} elseif (is_string($element) and $element == "footnotetexts") {
$pdf->Footnotes();
} elseif (is_string($element) and $element == "addpage") {
$pdf->newPage();
}
}
// Restore the margins
$pdf->SetLeftMargin($cM["left"]);
$pdf->SetRightMargin($cM["right"]);
// This will be mostly used to trick the multiple images last height
if ($this->reseth) {
$cH = 0;
// This can only happen with multiple images and with pagebreak
if ($cPN != $pdf->getPage()) {
$pdf->setPage($cPN);
}
}
// New line and some clean up
if (!$this->newline) {
$pdf->SetXY(($cX + $cW), $cY);
$pdf->lastCellHeight = $cH;
} else {
// addMarginX() also updates X
$pdf->addMarginX(0);
$pdf->SetY($cY + $cH);
$pdf->lastCellHeight = 0;
}
return true;
}
}
/**
* Text element
*
* @package webtrees
* @subpackage Reports
* @todo add info
*/
class TextPDF extends Text {
/**
* Create a Text class for PDF
*
* @param string $style The name of the text style
* @param string $color HTML color code
*/
function TextPDF($style, $color) {
parent::Text($style, $color);
}
/**
* PDF Text renderer
* @param PDF &$pdf
*/
function render(&$pdf) {
// Set up the style
if ($pdf->getCurrentStyle() != $this->styleName) {
$pdf->setCurrentStyle($this->styleName);
}
$temptext = str_replace("#PAGENUM#", $pdf->PageNo(), $this->text);
// Paint the text color or they might use inherited colors by the previous function
$match = array();
if (preg_match("/#?(..)(..)(..)/", $this->color, $match)) {
$r = hexdec($match[1]);
$g = hexdec($match[2]);
$b = hexdec($match[3]);
$pdf->SetTextColor($r, $g, $b);
} else {
$pdf->SetTextColor(0, 0, 0);
}
$temptext = spanLTRRTL($temptext, "BOTH");
$pdf->writeHTML($temptext, false, false, true, false, ""); //change height - line break etc.
// Reset the text color to black or it will be inherited
$pdf->SetTextColor(0, 0, 0);
}
/**
* Returns the height in points of the text element
*
* The height is already calculated in getWidth()
* @param PDF &$pdf
* @return float 0
*/
function getHeight(&$pdf) {
return 0;
}
/**
* Splits the text into lines if necessary to fit into a giving cell
*
* @param PDF &$pdf
* @return array
*/
function getWidth(&$pdf) {
// Setup the style name, a font must be selected to calculate the width
if ($pdf->getCurrentStyle() != $this->styleName) {
$pdf->setCurrentStyle($this->styleName);
}
// Check for the largest font size in the box
$fsize = $pdf->getCurrentStyleHeight();
if ($fsize > $pdf->largestFontHeight) {
$pdf->largestFontHeight = $fsize;
}
// Get the line width
$lw = $pdf->GetStringWidth($this->text);
// Line Feed counter - Number of lines in the text
$lfct = substr_count($this->text, "\n") + 1;
// If there is still remaining wrap width...
if ($this->wrapWidthRemaining > 0) {
// Check with line counter too!
// but floor the $wrapWidthRemaining first to keep it bugfree!
$wrapWidthRemaining = floor($this->wrapWidthRemaining);
if (($lw >= ($wrapWidthRemaining)) or ($lfct > 1)) {
$newtext = "";
$lines = explode("\n", $this->text);
// Go throught the text line by line
foreach($lines as $line) {
// Line width in points + a little margin
$lw = $pdf->GetStringWidth($line);
// If the line has to be wraped
if ($lw >= $wrapWidthRemaining) {
$words = explode(" ", $line);
$addspace = count($words);
$lw = 0;
foreach($words as $word) {
$addspace--;
$lw += $pdf->GetStringWidth($word." ");
if ($lw <= $wrapWidthRemaining) {
$newtext .= $word;
if ($addspace != 0) {
$newtext .= " ";
}
} else {
$lw = $pdf->GetStringWidth($word." ");
$newtext .= "\n$word";
if ($addspace != 0) {
$newtext .= " ";
}
// Reset the wrap width to the cell width
$wrapWidthRemaining = $this->wrapWidthCell;
}
}
} else {
$newtext .= $line;
}
// Check the Line Feed counter
if ($lfct > 1) {
// Add a new line as long as it's not the last line
$newtext.= "\n";
// Reset the line width
$lw = 0;
// Reset the wrap width to the cell width
$wrapWidthRemaining = $this->wrapWidthCell;
}
$lfct--;
}
$this->text = $newtext;
$lfct = substr_count($this->text, "\n");
return array($lw, 1, $lfct);
}
}
$l = 0;
$lfct = substr_count($this->text, "\n");
if ($lfct > 0) {
$l = 2;
}
return array($lw, $l, $lfct);
}
}
/**
* Footnote element
*
* @package webtrees
* @subpackage Reports
* @todo add info
*/
class FootnotePDF extends Footnote {
function FootnotePDF($style="") {
parent::Footnote($style);
}
/**
* PDF Footnotes number renderer
* @param PDF &$pdf
*/
function render(&$pdf) {
$pdf->setCurrentStyle("footnotenum");
$pdf->Write($pdf->getCurrentStyleHeight(), $this->numText, $this->addlink); //source link numbers after name
}
/**
* Write the Footnote text
* Uses style name "footnote" by default
*
* @param PDF &$pdf
*/
function renderFootnote(&$pdf) {
if ($pdf->getCurrentStyle() != $this->styleName) {
$pdf->setCurrentStyle($this->styleName);
}
$temptext = str_replace("#PAGENUM#", $pdf->PageNo(), $this->text);
// Set the link to this y/page position
$pdf->SetLink($this->addlink, -1, -1);
// Print first the source number
// working
if ($pdf->getRTL()) {
$pdf->writeHTML(" .".$this->num."", false, false, false, false, "");
} else {
$temptext = "".$this->num.". ".$temptext;
}
$temptext = spanLTRRTL($temptext, "BOTH");
$pdf->writeHTML($temptext."
", true, false, true, false, "");
//$pdf->Write($pdf->getCurrentStyleHeight(), $this->num.". ".$temptext."\n\n"); //@@ indi list of sources
}
/**
* Returns the height in points of the Footnote element
*
* @param PDF &$pdf
* @return float $h
*/
function getFootnoteHeight(&$pdf) {
//$style = $pdf->getStyle($this->styleName);
//$ct = substr_count($this->numText, "\n");
//if ($ct > 0) {
//$ct += 1;
//}
//$h = ($style["size"] * $ct);
//return $h;
return 0;
}
/**
* Splits the text into lines to fit into a giving cell
* and returns the last lines width
*
* @param PDF &$pdf
* @return array
*/
function getWidth(&$pdf) {
// Setup the style name, a font must be selected to calculate the width
$pdf->setCurrentStyle("footnotenum");
// Check for the largest font size in the box
$fsize = $pdf->getCurrentStyleHeight();
if ($fsize > $pdf->largestFontHeight) {
$pdf->largestFontHeight = $fsize;
}
// Returns the Object if already numbered else false
if (empty($this->num)){
$pdf->checkFootnote($this);
}
// Get the line width
$lw = ceil($pdf->GetStringWidth($this->numText));
// Line Feed counter - Number of lines in the text
$lfct = substr_count($this->numText, "\n") + 1;
// If there is still remaining wrap width...
if ($this->wrapWidthRemaining > 0) {
// Check with line counter too!
// but floor the $wrapWidthRemaining first to keep it bugfree!
$wrapWidthRemaining = floor($this->wrapWidthRemaining);
if (($lw >= $wrapWidthRemaining) or ($lfct > 1)) {
$newtext = "";
$lines = explode("\n", $this->numText);
// Go throught the text line by line
foreach($lines as $line) {
// Line width in points
$lw = ceil($pdf->GetStringWidth($line));
// If the line has to be wraped
if ($lw >= $wrapWidthRemaining) {
$words = explode(" ", $line);
$addspace = count($words);
$lw = 0;
foreach($words as $word) {
$addspace--;
$lw += ceil($pdf->GetStringWidth($word." "));
if ($lw < $wrapWidthRemaining) {
$newtext .= $word;
if ($addspace != 0) {
$newtext .= " ";
}
} else {
$lw = $pdf->GetStringWidth($word." ");
$newtext .= "\n$word";
if ($addspace != 0) {
$newtext .= " ";
}
// Reset the wrap width to the cell width
$wrapWidthRemaining = $this->wrapWidthCell;
}
}
} else {
$newtext .= $line;
}
// Check the Line Feed counter
if ($lfct > 1) {
// Add a new line feed as long as it's not the last line
$newtext.= "\n";
// Reset the line width
$lw = 0;
// Reset the wrap width to the cell width
$wrapWidthRemaining = $this->wrapWidthCell;
}
$lfct--;
}
$this->numText = $newtext;
$lfct = substr_count($this->numText, "\n");
return array($lw, 1, $lfct);
}
}
$l = 0;
$lfct = substr_count($this->numText, "\n");
if ($lfct > 0) {
$l = 2;
}
return array($lw, $l, $lfct);
}
}
/**
* PageHeader element
*
* @package webtrees
* @subpackage Reports
*/
class PageHeaderPDF extends PageHeader {
function PageHeaderPDF() {
parent::PageHeader();
}
/**
* PageHeader element renderer
* @param PDF &$pdf
*/
function render(&$pdf) {
$pdf->clearPageHeader();
foreach($this->elements as $element) {
$pdf->addPageHeader($element);
}
}
}
/**
* ImagePDF class element
*
* @package webtrees
* @subpackage Reports
*/
class ImagePDF extends Image {
function ImagePDF($file, $x, $y, $w, $h, $align, $ln) {
parent::Image($file, $x, $y, $w, $h, $align, $ln);
}
/**
* PDF image renderer
* @param PDF &$pdf
*/
function render(&$pdf) {
global $lastpicbottom, $lastpicpage, $lastpicleft, $lastpicright;
// Check for a pagebreak first
if ($pdf->checkPageBreakPDF($this->height + 5)) {
$this->y = $pdf->GetY();
}
$curx = $pdf->GetX();
// If current position (left)set "."
if ($this->x == ".") {
$this->x = $pdf->GetX();
}
// For static position add margin
else {
$this->x = $pdf->addMarginX($this->x);
$pdf->SetX($curx);
}
if ($this->y == ".") {
//-- first check for a collision with the last picture
if (isset($lastpicbottom)) {
if (($pdf->PageNo()==$lastpicpage) && ($lastpicbottom >= $pdf->GetY()) && ($this->x >= $lastpicleft) && ($this->x <= $lastpicright))
$pdf->SetY($lastpicbottom + 5);
}
$this->y = $pdf->GetY();
} else {
$pdf->SetY($this->y);
}
$pdf->Image($this->file, $this->x, $this->y, $this->width, $this->height, "", "", $this->line, false, 72, $this->align);
$lastpicpage = $pdf->PageNo();
$pdf->lastpicpage = $pdf->getPage();
$lastpicleft = $this->x;
$lastpicright = $this->x + $this->width;
$lastpicbottom = $this->y + $this->height;
// Setup for the next line
if ($this->line == "N") {
$pdf->SetY($lastpicbottom);
}
}
/**
* Get the image height
* @param PDF &$pdf
* @return float
*/
function getHeight(&$pdf) {
return $this->height;
}
function getWidth(&$pdf) {
return $this->width;
}
}
/**
* Line element
*
* @package webtrees
* @subpackage Reports
* @todo add info
*/
class LinePDF extends Line {
/**
* Create a line class -PDF
* @param mixed $x1
* @param mixed $y1
* @param mixed $x2
* @param mixed $y2
*/
function LinePDF($x1, $y1, $x2, $y2) {
parent::Line($x1, $y1, $x2, $y2);
}
/**
* PDF line renderer
* @param PDF &$pdf
*/
function render(&$pdf) {
if ($this->x1 == ".") $this->x1=$pdf->GetX();
if ($this->y1 == ".") $this->y1=$pdf->GetY();
if ($this->x2 == ".") {
$this->x2 = $pdf->getMaxLineWidth();
}
if ($this->y2 == ".") $this->y2=$pdf->GetY();
$pdf->Line($this->x1, $this->y1, $this->x2, $this->y2);
}
}