public function MultiCell($w, $h, $txt, $border=0, $align='J', $fill=false, $ln=1, $x='', $y='', $reseth=true, $stretch=0, $ishtml=false, $autopadding=true, $maxh=0, $valign='T', $fitcell=false) {
$prev_cell_margin = $this->cell_margin;
$prev_cell_padding = $this->cell_padding;
// adjust internal padding
$this->adjustCellPadding($border);
$mc_padding = $this->cell_padding;
$mc_margin = $this->cell_margin;
$this->cell_padding['T'] = 0;
$this->cell_padding['B'] = 0;
$this->setCellMargins(0, 0, 0, 0);
if ($this->empty_string($this->lasth) OR $reseth) {
// reset row height
$this->resetLastH();
}
if (!$this->empty_string($y)) {
$this->SetY($y);
} else {
$y = $this->GetY();
}
$resth = 0;
if ((!$this->InFooter) AND (($y + $h + $mc_margin['T'] + $mc_margin['B']) > $this->PageBreakTrigger)) {
// spit cell in more pages/columns
$newh = $this->PageBreakTrigger - $y;
$resth = $h - $newh; // cell to be printed on the next page/column
$h = $newh;
}
// get current page number
$startpage = $this->page;
// get current column
$startcolumn = $this->current_column;
if (!$this->empty_string($x)) {
$this->SetX($x);
} else {
$x = $this->GetX();
}
// check page for no-write regions and adapt page margins if necessary
$this->checkPageRegions(0, $x, $y);
// apply margins
$oy = $y + $mc_margin['T'];
if ($this->rtl) {
$ox = $this->w - $x - $mc_margin['R'];
} else {
$ox = $x + $mc_margin['L'];
}
$this->x = $ox;
$this->y = $oy;
// set width
if ($this->empty_string($w) OR ($w <= 0)) {
if ($this->rtl) {
$w = $this->x - $this->lMargin - $mc_margin['L'];
} else {
$w = $this->w - $this->x - $this->rMargin - $mc_margin['R'];
}
}
// store original margin values
$lMargin = $this->lMargin;
$rMargin = $this->rMargin;
if ($this->rtl) {
$this->rMargin = $this->w - $this->x;
$this->lMargin = $this->x - $w;
} else {
$this->lMargin = $this->x;
$this->rMargin = $this->w - $this->x - $w;
}
if ($autopadding) {
// add top padding
$this->y += $mc_padding['T'];
}
if ($ishtml) { // ******* Write HTML text
$this->writeHTML($txt, true, 0, $reseth, true, $align);
$nl = 1;
} else { // ******* Write simple text
// vertical alignment
if ($maxh > 0) {
// get text height
$text_height = $this->getStringHeight($w, $txt, $reseth, $autopadding, $mc_padding, $border);
if ($fitcell) {
$prev_FontSizePt = $this->FontSizePt;
// try to reduce font size to fit text on cell (use a quick search algorithm)
$fmin = 1;
$fmax = $this->FontSizePt;
$prev_text_height = $text_height;
$maxit = 100; // max number of iterations
while ($maxit > 0) {
$fmid = (($fmax + $fmin) / 2);
$this->SetFontSize($fmid, false);
$this->resetLastH();
$text_height = $this->getStringHeight($w, $txt, $reseth, $autopadding, $mc_padding, $border);
if (($text_height == $maxh) OR (($text_height < $maxh) AND ($fmin >= ($fmax - 0.01)))) {
break;
} elseif ($text_height < $maxh) {
$fmin = $fmid;
} else {
$fmax = $fmid;
}
--$maxit;
}
$this->SetFontSize($this->FontSizePt);
}
if ($text_height < $maxh) {
if ($valign == 'M') {
// text vertically centered
$this->y += (($maxh - $text_height) / 2);
} elseif ($valign == 'B') {
// text vertically aligned on bottom
$this->y += ($maxh - $text_height);
}
}
}
$nl = $this->Write($this->lasth, $txt, '', 0, $align, true, $stretch, false, true, $maxh, 0, $mc_margin);
if ($fitcell) {
// restore font size
$this->SetFontSize($prev_FontSizePt);
}
}
if ($autopadding) {
// add bottom padding
$this->y += $mc_padding['B'];
}
// Get end-of-text Y position
$currentY = $this->y;
// get latest page number
$endpage = $this->page;
if ($resth > 0) {
$skip = ($endpage - $startpage);
$tmpresth = $resth;
while ($tmpresth > 0) {
if ($skip <= 0) {
// add a page (or trig AcceptPageBreak() for multicolumn mode)
$this->checkPageBreak($this->PageBreakTrigger + 1);
}
if ($this->num_columns > 1) {
$tmpresth -= ($this->h - $this->y - $this->bMargin);
} else {
$tmpresth -= ($this->h - $this->tMargin - $this->bMargin);
}
--$skip;
}
$currentY = $this->y;
$endpage = $this->page;
}
// get latest column
$endcolumn = $this->current_column;
if ($this->num_columns == 0) {
$this->num_columns = 1;
}
// get border modes
$border_start = $this->getBorderMode($border, $position='start');
$border_end = $this->getBorderMode($border, $position='end');
$border_middle = $this->getBorderMode($border, $position='middle');
// design borders around HTML cells.
for ($page = $startpage; $page <= $endpage; ++$page) { // for each page
$ccode = '';
$this->setPage($page);
if ($this->num_columns < 2) {
// single-column mode
$this->SetX($x);
$this->y = $this->tMargin;
}
// account for margin changes
if ($page > $startpage) {
if (($this->rtl) AND ($this->pagedim[$page]['orm'] != $this->pagedim[$startpage]['orm'])) {
$this->x -= ($this->pagedim[$page]['orm'] - $this->pagedim[$startpage]['orm']);
} elseif ((!$this->rtl) AND ($this->pagedim[$page]['olm'] != $this->pagedim[$startpage]['olm'])) {
$this->x += ($this->pagedim[$page]['olm'] - $this->pagedim[$startpage]['olm']);
}
}
if ($startpage == $endpage) {
// single page
for ($column = $startcolumn; $column <= $endcolumn; ++$column) { // for each column
$this->selectColumn($column);
if ($this->rtl) {
$this->x -= $mc_margin['R'];
} else {
$this->x += $mc_margin['L'];
}
if ($startcolumn == $endcolumn) { // single column
$cborder = $border;
$h = max($h, ($currentY - $oy));
$this->y = $oy;
} elseif ($column == $startcolumn) { // first column
$cborder = $border_start;
$this->y = $oy;
$h = $this->h - $this->y - $this->bMargin;
} elseif ($column == $endcolumn) { // end column
$cborder = $border_end;
$h = $currentY - $this->y;
if ($resth > $h) {
$h = $resth;
}
} else { // middle column
$cborder = $border_middle;
$h = $this->h - $this->y - $this->bMargin;
$resth -= $h;
}
$ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
} // end for each column
} elseif ($page == $startpage) { // first page
for ($column = $startcolumn; $column < $this->num_columns; ++$column) { // for each column
$this->selectColumn($column);
if ($this->rtl) {
$this->x -= $mc_margin['R'];
} else {
$this->x += $mc_margin['L'];
}
if ($column == $startcolumn) { // first column
$cborder = $border_start;
$this->y = $oy;
$h = $this->h - $this->y - $this->bMargin;
} else { // middle column
$cborder = $border_middle;
$h = $this->h - $this->y - $this->bMargin;
$resth -= $h;
}
$ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
} // end for each column
} elseif ($page == $endpage) { // last page
for ($column = 0; $column <= $endcolumn; ++$column) { // for each column
$this->selectColumn($column);
if ($this->rtl) {
$this->x -= $mc_margin['R'];
} else {
$this->x += $mc_margin['L'];
}
if ($column == $endcolumn) {
// end column
$cborder = $border_end;
$h = $currentY - $this->y;
if ($resth > $h) {
$h = $resth;
}
} else {
// middle column
$cborder = $border_middle;
$h = $this->h - $this->y - $this->bMargin;
$resth -= $h;
}
$ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
} // end for each column
} else { // middle page
for ($column = 0; $column < $this->num_columns; ++$column) { // for each column
$this->selectColumn($column);
if ($this->rtl) {
$this->x -= $mc_margin['R'];
} else {
$this->x += $mc_margin['L'];
}
$cborder = $border_middle;
$h = $this->h - $this->y - $this->bMargin;
$resth -= $h;
$ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
} // end for each column
}
if ($cborder OR $fill) {
// draw border and fill
if ($this->inxobj) {
// we are inside an XObject template
if (end($this->xobjects[$this->xobjid]['transfmrk']) !== false) {
$pagemarkkey = key($this->xobjects[$this->xobjid]['transfmrk']);
$pagemark = &$this->xobjects[$this->xobjid]['transfmrk'][$pagemarkkey];
} else {
$pagemark = &$this->xobjects[$this->xobjid]['intmrk'];
}
$pagebuff = $this->xobjects[$this->xobjid]['outdata'];
$pstart = substr($pagebuff, 0, $pagemark);
$pend = substr($pagebuff, $pagemark);
$this->xobjects[$this->xobjid]['outdata'] = $pstart.$ccode.$pend;
$pagemark += strlen($ccode);
} else {
if (end($this->transfmrk[$this->page]) !== false) {
$pagemarkkey = key($this->transfmrk[$this->page]);
$pagemark = &$this->transfmrk[$this->page][$pagemarkkey];
} elseif ($this->InFooter) {
$pagemark = &$this->footerpos[$this->page];
} else {
$pagemark = &$this->intmrk[$this->page];
}
$pagebuff = $this->getPageBuffer($this->page);
$pstart = substr($pagebuff, 0, $pagemark);
$pend = substr($pagebuff, $pagemark);
$this->setPageBuffer($this->page, $pstart.$ccode.$pend);
$pagemark += strlen($ccode);
}
}
} // end for each page
// Get end-of-cell Y position
$currentY = $this->GetY();
// restore original margin values
$this->SetLeftMargin($lMargin);
$this->SetRightMargin($rMargin);
if ($ln > 0) {
//Go to the beginning of the next line
$this->SetY($currentY + $mc_margin['B']);
if ($ln == 2) {
$this->SetX($x + $w + $mc_margin['L'] + $mc_margin['R']);
}
} else {
// go left or right by case
$this->setPage($startpage);
$this->y = $y;
$this->SetX($x + $w + $mc_margin['L'] + $mc_margin['R']);
}
$this->setContentMark();
$this->cell_padding = $prev_cell_padding;
$this->cell_margin = $prev_cell_margin;
return $nl;
}