Calculates the Footnotes height

@param ReportHtml $html
@param float      $cellWidth The width of the cell to use it for text wraping

@return float     Footnote height in points
553127
public function getFootnoteHeight($html, float $cellWidth = 0): float
    {
        if ($html->getCurrentStyle() != $this->styleName) {
            $html->setCurrentStyle($this->styleName);
        }

        if ($cellWidth > 0) {
            $this->text = $html->textWrap($this->text, $cellWidth);
        }

        $this->text .= "\n\n";
        $ct         = substr_count($this->text, "\n");
        $fsize      = $html->getCurrentStyleHeight();

        return ($fsize * $ct) * $html->cellHeightRatio;
    }
636296
public function getDimension($w, $h) {
        $textlength = (3 + ($this->ratio + 1) * 2) * strlen($this->text);
        $startlength = 4;
        $checksumlength = 0;
        if ($this->checksum === true) {
            $checksumlength = (3 + ($this->ratio + 1) * 2);
        }

        $endlength = 2 + ($this->ratio + 1);

        $w += $startlength + $textlength + $checksumlength + $endlength;
        $h += $this->thickness;
        return parent::getDimension($w, $h);
    }
246770
function updateHTMLTag(editor, node, width, height) {
	const srcAttr = getAttribute(node, 'src');
	const widthAttr = getAttribute(node, 'width');
	const heightAttr = getAttribute(node, 'height');

	editor.transact(() => {
		// apply changes from right to left, first for height, then for width
		let point;
		const quote = getAttributeQuote(editor, widthAttr || heightAttr || srcAttr);

		if (!heightAttr) {
			// no `height` attribute, add it right after `width` or `src`
			point = widthAttr ? widthAttr.end : srcAttr.end;
			editor.setTextInBufferRange([point, point], ` height=${quote}${height}${quote}`);
		} else {
			editor.setTextInBufferRange(getRange(heightAttr.value), String(height));
		}

		if (!widthAttr) {
			// no `width` attribute, add it right before `height` or after `src`
			point = heightAttr ? heightAttr.start : srcAttr.end;
			editor.setTextInBufferRange([point, point], `${!heightAttr ? ' ' : ''}width=${quote}${width}${quote}${heightAttr ? ' ' : ''}`);
		} else {
			editor.setTextInBufferRange(getRange(widthAttr.value), String(width));
		}
	});
}
836721
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)
	{
		// 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']
				)
			)
			&& !$this->InFooter
			&& $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 & TextVars::FA_SUPERSCRIPT) {
					$baseline_shift = $this->textparam['text-baseline'];
				} elseif ($textvar & TextVars::FA_SUBSCRIPT) {
					$baseline_shift = $this->textparam['text-baseline'];
				} elseif ($this->bullet) {
					$baseline += ($bfx - 0.7) * $this->FontSize;
				}

				// Vertical align (for Images)
				if ($valign == 'T') {
					$va = (0.5 * $bfs * $this->normalLineheight);
				} elseif ($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'] = ['s' => 0, 'style' => '', 'w' => 0];
			}

			if (!isset($this->spanborddet['T'])) {
				$this->spanborddet['T'] = ['s' => 0, 'style' => '', 'w' => 0];
			}

			if (!isset($this->spanborddet['L'])) {
				$this->spanborddet['L'] = ['s' => 0, 'style' => '', 'w' => 0];
			}

			if (!isset($this->spanborddet['R'])) {
				$this->spanborddet['R'] = ['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) * Mpdf::SCALE, ($this->h - $bg_boxtop + $tbw) * Mpdf::SCALE, ($w + $lbw + $rbw) * Mpdf::SCALE, (-$bg_boxheight - $tbw - $bbw) * Mpdf::SCALE);
				}

				$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 * Mpdf::SCALE, $tbw * $dashoff * Mpdf::SCALE);
					} elseif ($this->spanborddet['T']['style'] == 'dotted') {
						$s .= sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ', 0.001, $tbw * $dot * Mpdf::SCALE, -$tbw / 2 * Mpdf::SCALE);
						$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) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F l ', ($this->x + $w + $rbw) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F l ', ($this->x + $w) * Mpdf::SCALE, ($this->h - $bord_boxtop) * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F l ', ($this->x) * Mpdf::SCALE, ($this->h - $bord_boxtop) * Mpdf::SCALE);
						$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 * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw * 5 / 6) * Mpdf::SCALE, ($this->x + $w + $rbw) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw * 5 / 6) * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw / 6) * Mpdf::SCALE, ($this->x + $w + $rbw) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw / 6) * Mpdf::SCALE);
					} elseif ($this->spanborddet['T']['style'] == 'dotted') {
						$s .= sprintf(' %s %.3F w ', $c, $tbw * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw / 2) * Mpdf::SCALE, ($this->x + $w + $rbw - $short) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw / 2) * Mpdf::SCALE);
					} else {
						$s .= sprintf(' %s %.3F w ', $c, $tbw * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw / 2) * Mpdf::SCALE, ($this->x + $w + $rbw - $short) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw / 2) * Mpdf::SCALE);
					}

					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 * Mpdf::SCALE, $bbw * $dashoff * Mpdf::SCALE);
					} elseif ($this->spanborddet['B']['style'] == 'dotted') {
						$s .= sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ', 0.001, $bbw * $dot * Mpdf::SCALE, -$bbw / 2 * Mpdf::SCALE);
						$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) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw) * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F l ', ($this->x + $w + $rbw) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw) * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F l ', ($this->x + $w) * Mpdf::SCALE, ($this->h - $bord_boxbottom) * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F l ', ($this->x) * Mpdf::SCALE, ($this->h - $bord_boxbottom) * Mpdf::SCALE);
						$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 * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw / 6) * Mpdf::SCALE, ($this->x + $w + $rbw - $short) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw / 6) * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw * 5 / 6) * Mpdf::SCALE, ($this->x + $w + $rbw - $short) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw * 5 / 6) * Mpdf::SCALE);
					} elseif ($this->spanborddet['B']['style'] == 'dotted') {
						$s .= sprintf(' %s %.3F w ', $c, $bbw * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw / 2) * Mpdf::SCALE, ($this->x + $w + $rbw - $short) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw / 2) * Mpdf::SCALE);
					} else {
						$s .= sprintf(' %s %.3F w ', $c, $bbw * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw / 2) * Mpdf::SCALE, ($this->x + $w + $rbw - $short) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw / 2) * Mpdf::SCALE);
					}

					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 * Mpdf::SCALE, $lbw * $dashoff * Mpdf::SCALE);
					} elseif ($this->spanborddet['L']['style'] == 'dotted') {
						$s .= sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ', 0.001, $lbw * $dot * Mpdf::SCALE, -$lbw / 2 * Mpdf::SCALE);
						$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) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw) * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F l ', ($this->x) * Mpdf::SCALE, ($this->h - $bord_boxbottom) * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F l ', ($this->x) * Mpdf::SCALE, ($this->h - $bord_boxtop) * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F l ', ($this->x - $lbw) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE);
						$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 * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw / 6) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE, ($this->x - $lbw / 6) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw + $short) * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw * 5 / 6) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE, ($this->x - $lbw * 5 / 6) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw + $short) * Mpdf::SCALE);
					} elseif ($this->spanborddet['L']['style'] == 'dotted') {
						$s .= sprintf(' %s %.3F w ', $c, $lbw * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw / 2) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE, ($this->x - $lbw / 2) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw + $short) * Mpdf::SCALE);
					} else {
						$s .= sprintf(' %s %.3F w ', $c, $lbw * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x - $lbw / 2) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE, ($this->x - $lbw / 2) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw + $short) * Mpdf::SCALE);
					}

					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 * Mpdf::SCALE, $rbw * $dashoff * Mpdf::SCALE);
					} elseif ($this->spanborddet['R']['style'] == 'dotted') {
						$s .= sprintf(' 1 j 1 J [%.3F %.3F] %.3F d ', 0.001, $rbw * $dot * Mpdf::SCALE, -$rbw / 2 * Mpdf::SCALE);
						$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) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw) * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F l ', ($this->x + $w) * Mpdf::SCALE, ($this->h - $bord_boxbottom) * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F l ', ($this->x + $w) * Mpdf::SCALE, ($this->h - $bord_boxtop) * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F l ', ($this->x + $w + $rbw) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE);
						$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 * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x + $w + $rbw / 6) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE, ($this->x + $w + $rbw / 6) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw + $short) * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x + $w + $rbw * 5 / 6) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE, ($this->x + $w + $rbw * 5 / 6) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw + $short) * Mpdf::SCALE);
					} elseif ($this->spanborddet['R']['style'] == 'dotted') {
						$s .= sprintf(' %s %.3F w ', $c, $rbw * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x + $w + $rbw / 2) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE, ($this->x + $w + $rbw / 2) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw + $short) * Mpdf::SCALE);
					} else {
						$s .= sprintf(' %s %.3F w ', $c, $rbw * Mpdf::SCALE);
						$s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($this->x + $w + $rbw / 2) * Mpdf::SCALE, ($this->h - $bord_boxtop + $tbw) * Mpdf::SCALE, ($this->x + $w + $rbw / 2) * Mpdf::SCALE, ($this->h - $bord_boxbottom - $bbw + $short) * Mpdf::SCALE);
					}

					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 * Mpdf::SCALE, ($this->h - $bg_boxtop) * Mpdf::SCALE, $w * Mpdf::SCALE, -$bg_boxheight * Mpdf::SCALE, $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 * Mpdf::SCALE, ($this->h - $bord_boxtop) * Mpdf::SCALE, $x * Mpdf::SCALE, ($this->h - ($bord_boxbottom)) * Mpdf::SCALE);
			}

			if (is_int(strpos($border, 'T'))) {
				$s .= sprintf('%.3F %.3F m %.3F %.3F l S ', $x * Mpdf::SCALE, ($this->h - $bord_boxtop) * Mpdf::SCALE, ($x + $w) * Mpdf::SCALE, ($this->h - $bord_boxtop) * Mpdf::SCALE);
			}

			if (is_int(strpos($border, 'R'))) {
				$s .= sprintf('%.3F %.3F m %.3F %.3F l S ', ($x + $w) * Mpdf::SCALE, ($this->h - $bord_boxtop) * Mpdf::SCALE, ($x + $w) * Mpdf::SCALE, ($this->h - ($bord_boxbottom)) * Mpdf::SCALE);
			}

			if (is_int(strpos($border, 'B'))) {
				$s .= sprintf('%.3F %.3F m %.3F %.3F l S ', $x * Mpdf::SCALE, ($this->h - ($bord_boxbottom)) * Mpdf::SCALE, ($x + $w) * Mpdf::SCALE, ($this->h - ($bord_boxbottom)) * Mpdf::SCALE);
			}
		}

		if ($txt != '') {

			if ($exactWidth) {
				$stringWidth = $w;
			} else {
				$stringWidth = $this->GetStringWidth($txt, true, $OTLdata, $textvar) + ( $this->charspacing * mb_strlen($txt, $this->mb_enc) / Mpdf::SCALE ) + ( $this->ws * mb_substr_count($txt, ' ', $this->mb_enc) / Mpdf::SCALE );
			}

			// 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 & TextVars::FC_SMALLCAPS)) { // mPDF 5.7.1
				$s .=' ' . sprintf('%.3F w', $this->LineWidth * Mpdf::SCALE) . ' ';
				$s .=" $this->DrawColor ";
				$s .=" 2 Tr ";
			} elseif ($this->falseBoldWeight && strpos($this->ReqFontStyle, "B") !== false && strpos($this->FontStyle, "B") === false && !($textvar & TextVars::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) * Mpdf::SCALE * $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) * Mpdf::SCALE;
			$py = ($this->h - ($this->y + $glyphYorigin - $baseline_shift)) * Mpdf::SCALE;

			// 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 & TextVars::FC_SMALLCAPS) && !($textvar & TextVars::FC_KERNING)) {
				$txt2 = $this->writer->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
			elseif (!$this->usingCoreFont && !$this->ws && !($textvar & TextVars::FC_SMALLCAPS) && !($textvar & TextVars::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->writer->utf8ToUtf16BigEndian($txt2, false);
					$txt2 = $this->writer->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
			elseif (!$this->usingCoreFont && $this->ws && !((isset($this->CurrentFont['sip']) && $this->CurrentFont['sip']) || (isset($this->CurrentFont['smp']) && $this->CurrentFont['smp'])) && !($textvar & TextVars::FC_SMALLCAPS) && !($textvar & TextVars::FC_KERNING) && !(isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0xFF) && (!empty($OTLdata['GPOSinfo']) || (strpos($OTLdata['group'], 'M') !== false && $this->charspacing)) )) {
				$space = " ";
				$space = $this->writer->utf8ToUtf16BigEndian($space, false);
				$space = $this->writer->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->writer->utf8ToUtf16BigEndian($tx, false);
					$tx = $this->writer->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 & TextVars::FD_UNDERLINE) { // mPDF 5.7.1	// mPDF 6

				// mPDF 5.7.3  inline text-decoration parameters

				$c = isset($this->textparam['u-decoration']['color']) ? $this->textparam['u-decoration']['color'] : '';
				if ($this->FillColor != $c) {
					$sub .= ' ' . $c . ' ';
				}

				// mPDF 5.7.3  inline text-decoration parameters
				$decorationfontkey = isset($this->textparam['u-decoration']['fontkey']) ? $this->textparam['u-decoration']['fontkey'] : '';
				$decorationfontsize = isset($this->textparam['u-decoration']['fontsize']) ? $this->textparam['u-decoration']['fontsize'] / $shrin_k : 0;

				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 = isset($this->textparam['u-decoration']['baseline'])
					? $glyphYorigin - $this->textparam['u-decoration']['baseline'] / $shrin_k
					: $glyphYorigin;

				$olw = $this->LineWidth;

				$sub .= ' ' . (sprintf(' %.3F w 0 j 0 J ', $ut * Mpdf::SCALE));
				$sub .= ' ' . $this->_dounderline($this->x + $dx, $this->y + $ubaseline + $adjusty, $txt, $OTLdata, $textvar);
				$sub .= ' ' . (sprintf(' %.3F w 2 j 2 J ', $olw * Mpdf::SCALE));

				if ($this->FillColor != $c) {
					$sub .= ' ' . $this->FillColor . ' ';
				}
			}

			// STRIKETHROUGH
			if ($textvar & TextVars::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
				elseif (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 * Mpdf::SCALE));
				$sub .=' ' . $this->_dounderline($this->x + $dx, $this->y + $sbaseline + $adjusty, $txt, $OTLdata, $textvar);
				$sub .=' ' . (sprintf(' %.3F w 2 j 2 J ', $olw * Mpdf::SCALE));

				if ($this->FillColor != $c) {
					$sub .= ' ' . $this->FillColor . ' ';
				}
			}

			// mPDF 5.7.3  inline text-decoration parameters
			// OVERLINE
			if ($textvar & TextVars::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 = (int) (((float) $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 * Mpdf::SCALE));
				$sub .=' ' . $this->_dounderline($this->x + $dx, $this->y + $obaseline + $adjusty, $txt, $OTLdata, $textvar);
				$sub .=' ' . (sprintf(' %.3F w 2 j 2 J ', $olw * Mpdf::SCALE));
				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";
					} elseif ($ts['col']{0} == 6 && ord($ts['col']{5}) < 100) { // CMYKa
						$s .= $this->SetAlpha(ord($ts['col']{5}) / 100, 'Normal', true, 'F') . "\n";
					} elseif ($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'] * Mpdf::SCALE, -$ts['y'] * Mpdf::SCALE) . "\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->writer->write($s);
		}

		// WORD SPACING
		if ($this->ws && !$this->usingCoreFont) {
			$this->writer->write(sprintf('BT %.3F Tc ET', $this->charspacing));
		}
		$this->lasth = $h;
		if (strpos($txt, "\n") !== false) {
			$ln = 1; // cell recognizes \n from <BR> 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;
		}
	}
998640
public function addFootnotes(\DOMElement $articleContent)
    {
        $footnotesWrapper = $this->dom->createElement('footer');
        $footnotesWrapper->setAttribute('class', 'readability-footnotes');
        $footnotesWrapper->setInnerHtml('<h3>References</h3>');
        $articleFootnotes = $this->dom->createElement('ol');
        $articleFootnotes->setAttribute('class', 'readability-footnotes-list');
        $footnotesWrapper->appendChild($articleFootnotes);
        $articleLinks = $articleContent->getElementsByTagName('a');
        $linkCount = 0;

        for ($i = 0; $i < $articleLinks->length; ++$i) {
            $articleLink = $articleLinks->item($i);
            $footnoteLink = $articleLink->cloneNode(true);
            $refLink = $this->dom->createElement('a');
            $footnote = $this->dom->createElement('li');
            $linkDomain = @parse_url($footnoteLink->getAttribute('href'), PHP_URL_HOST);
            if (!$linkDomain && isset($this->url)) {
                $linkDomain = @parse_url($this->url, PHP_URL_HOST);
            }

            $linkText = $this->getInnerText($articleLink);
            if ((false !== strpos($articleLink->getAttribute('class'), 'readability-DoNotFootnote')) || preg_match($this->regexps['skipFootnoteLink'], $linkText)) {
                continue;
            }

            ++$linkCount;

            // Add a superscript reference after the article link.
            $refLink->setAttribute('href', '#readabilityFootnoteLink-' . $linkCount);
            $refLink->setInnerHtml('<small><sup>[' . $linkCount . ']</sup></small>');
            $refLink->setAttribute('class', 'readability-DoNotFootnote');
            $refLink->setAttribute('style', 'color: inherit;');

            if ($articleLink->parentNode->lastChild->isSameNode($articleLink)) {
                $articleLink->parentNode->appendChild($refLink);
            } else {
                $articleLink->parentNode->insertBefore($refLink, $articleLink->nextSibling);
            }

            $articleLink->setAttribute('style', 'color: inherit; text-decoration: none;');
            $articleLink->setAttribute('name', 'readabilityLink-' . $linkCount);
            $footnote->setInnerHtml('<small><sup><a href="#readabilityLink-' . $linkCount . '" title="Jump to Link in Article">^</a></sup></small> ');
            $footnoteLink->setInnerHtml(('' !== $footnoteLink->getAttribute('title') ? $footnoteLink->getAttribute('title') : $linkText));
            $footnoteLink->setAttribute('name', 'readabilityFootnoteLink-' . $linkCount);
            $footnote->appendChild($footnoteLink);

            if ($linkDomain) {
                $footnote->setInnerHtml($footnote->getInnerHTML() . '<small> (' . $linkDomain . ')</small>');
            }
            $articleFootnotes->appendChild($footnote);
        }

        if ($linkCount > 0) {
            $articleContent->appendChild($footnotesWrapper);
        }
    }
822982
public function createHtmlTableFromArray($nbColonnes=4,$styleTableau='border:1px;',$classTableau='',$cellProperty='',$tableauProperties='')
	{
	
		$htmlClassTableau = "";
		if($classTableau!='')
			$htmlClassTableau = " class='".$classTableau."' ";
	
		$html="<table style=\"".$styleTableau."\" ".$htmlClassTableau." ".$tableauProperties."><tbody>";
		
		
		$nbValues = count($this->tabValues);
		
		// calcul du nombre de cases totales :
		if($nbValues%$nbColonnes==0)
		{
			$nbLignes = $nbValues / $nbColonnes;
		}
		else
		{
			$nbLignes = intval($nbValues / $nbColonnes)+1;
		}
		
		$nbCases = $nbLignes * $nbColonnes;
		
		$ligne=0; // coordonn�es horizontales
		$colonne=0; // coordonn�es verticales
		for($i=0 ; $i<$nbCases ; $i++)
		{
			if($colonne==0)
			{
				$html.="<tr>";
			}
			
			if(isset($this->tabValues[$i]))
			{
				if(isset($this->tabStyles[$i]) && $this->tabStyles[$i]!='')
					$html.="<td ".$this->tabStyles[$i].">".$this->tabValues[$i]."</td>";
				else
					$html.="<td ".$cellProperty.">".$this->tabValues[$i]."</td>";
			}
			else
			{
				$html.="<td ".$cellProperty.">&nbsp;</td>";
			}
			
			
			if($colonne==$nbColonnes-1)
			{
				$html.="</tr>";
				$colonne=0;
				$ligne+=1;
			}
			else
			{
				$colonne+=1;
			}
		}
		
		$html=$html."</tbody></table>";
		return $html;
	}
234870
private void determineFootnoteHeading(TableCandidate tc)  {
    	/*
    	 * Gets the maximal column number based on all table rows before footnote
    	 */
    	int maxColumnNum = 0;
    	for (int i = 0; i < tc.getFootnoteBeginRow(); i++) {
    		TableRow row = tc.getRows().get(i);
    		if (row.getCells().size() > maxColumnNum) {
    			maxColumnNum = row.getCells().size();
    		}
    	}
    	tc.setMaxColumnNumber(maxColumnNum);

    	/*
    	 * Counts the number of table column heading lines 
    	 * TODO: this heading finding algorithm should be improved
    	 */
    	int headingLineNumber = 0;
    	for (int i = 0; i < tc.getFootnoteBeginRow(); i++) {
    		TableRow row = tc.getRows().get(i);
		    if (row.getCells().size() < maxColumnNum) {
		    	headingLineNumber++;
		    }
		    else break;
		}
    	/*
    	 * Based on observation, usually we have missing cells, especially happen in the first column 
    	 */
    	if (headingLineNumber>0) headingLineNumber--; 
    	tc.setHeadingLineNumber(Math.max(0, headingLineNumber)); 
    }
877150
public function getHeight($renderer): float
    {
        $ct = substr_count($this->text, "\n");
        if ($ct > 0) {
            $ct += 1;
        }
        $style = $renderer->getStyle($this->styleName);

        return ($style['size'] * $ct) * $renderer->cellHeightRatio;
    }
973134
function() {
            var height = self.innerHeight, // Safari, Opera
                mode = document[COMPAT_MODE];
        
            if ( (mode || isIE) && !isOpera ) { // IE, Gecko
                height = (mode == CSS1_COMPAT) ?
                        documentElement.clientHeight : // Standards
                        document.body.clientHeight; // Quirks
            }
        
            YAHOO.log('getViewportHeight returning ' + height, 'info', 'Dom');
            return height;
        }
606
function(node) {
        var h = Y_DOM._getDocSize(node).height;
        return Math.max(h, Y_DOM._getWinSize(node).height);
    }
449007
function estimateHeight(cm) {
    var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
    var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
    return function(line) {
      if (lineIsHidden(cm.doc, line)) return 0;

      var widgetsHeight = 0;
      if (line.widgets) for (var i = 0; i < line.widgets.length; i++) {
        if (line.widgets[i].height) widgetsHeight += line.widgets[i].height;
      }

      if (wrapping)
        return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th;
      else
        return widgetsHeight + th;
    };
  }
853929
private void findFootnoteBeginRow(TableCandidate tc) {
    	for (int i = 0; i < tc.getRows().size(); i++) {
    		TableRow row = tc.getRows().get(i);
    		TextPiece firstCell = row.getCells().get(0);
    		String text = firstCell.getText();
    		if (text.startsWith("*")
		    || text.startsWith("t ")
		    || text.startsWith("$")
		    || text.startsWith("?")
		    || text.startsWith("''")
		    || text.startsWith("Note:")
		    || (text.startsWith("a") && i >= tc.getRows().size() - 2 && row.isSuperScriptRow())) {
	    			tc.setFootnoteBeginRow(i);
	    			break;
    		}
    	}
    	if (tc.getFootnoteBeginRow()==-1)
    		tc.setFootnoteBeginRow(tc.getRows().size());
    }
658137
function(_contentLength) {
    var scrollTop, rowHeight, columnCount, calculatedStartingIndex,
        contentLength;

    if (_contentLength === undefined) {
      contentLength = get(this, 'content.length');
    } else {
      contentLength = _contentLength;
    }

    scrollTop = this.scrollTop;
    rowHeight = get(this, 'rowHeight');
    columnCount = get(this, 'columnCount');

    if (this.heightForIndex) {
      calculatedStartingIndex = this._calculatedStartingIndex();
    } else {
      calculatedStartingIndex = floor(scrollTop / rowHeight) * columnCount;
    }

    var viewsNeededForViewport = this._numChildViewsForViewport();
    var paddingCount = (1 * columnCount);
    var largestStartingIndex = max(contentLength - viewsNeededForViewport, 0);

    return min(calculatedStartingIndex, largestStartingIndex);
  }
485702
public function withWidth($newWidth)
    {
        return $this->withSize($newWidth, ceil($newWidth * $this->height / $this->width));
    }
1179296
function pageWidth() {
  return win.innerWidth != null ? win.innerWidth : doc.documentElement && doc.documentElement.clientWidth != null ? doc.documentElement.clientWidth : doc.body != null ? doc.body.clientWidth : null;
}
1263981
function _tableColumnWidth(&$table, $firstpass = false)
	{
		$cs = &$table['cells'];

		$nc = $table['nc'];
		$nr = $table['nr'];
		$listspan = [];

		if ($table['borders_separate']) {
			$tblbw = $table['border_details']['L']['w'] + $table['border_details']['R']['w'] + $table['margin']['L'] + $table['margin']['R'] + $table['padding']['L'] + $table['padding']['R'] + $table['border_spacing_H'];
		} else {
			$tblbw = $table['max_cell_border_width']['L'] / 2 + $table['max_cell_border_width']['R'] / 2 + $table['margin']['L'] + $table['margin']['R'];
		}

		// ADDED table['l'][colno]
		// = total length of text approx (using $c['s']) in that column - used to approximately distribute col widths in _tableWidth
		//
		for ($j = 0; $j < $nc; $j++) { // columns
			$wc = &$table['wc'][$j];
			for ($i = 0; $i < $nr; $i++) { // rows
				if (isset($cs[$i][$j]) && $cs[$i][$j]) {
					$c = &$cs[$i][$j];

					if ($this->simpleTables) {
						if ($table['borders_separate']) { // NB twice border width
							$extrcw = $table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w'] + $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H'];
						} else {
							$extrcw = $table['simple']['border_details']['L']['w'] / 2 + $table['simple']['border_details']['R']['w'] / 2 + $c['padding']['L'] + $c['padding']['R'];
						}
					} else {
						if ($this->packTableData) {
							list($bt, $br, $bb, $bl) = $this->_getBorderWidths($c['borderbin']);
						} else {
							$br = $c['border_details']['R']['w'];
							$bl = $c['border_details']['L']['w'];
						}
						if ($table['borders_separate']) { // NB twice border width
							$extrcw = $bl + $br + $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H'];
						} else {
							$extrcw = $bl / 2 + $br / 2 + $c['padding']['L'] + $c['padding']['R'];
						}
					}

					// $mw = $this->GetStringWidth('W') + $extrcw ;
					$mw = $extrcw; // mPDF 6
					if (substr($c['a'], 0, 1) == 'D') {
						$mw = $table['decimal_align'][$j]['maxs0'] + $table['decimal_align'][$j]['maxs1'] + $extrcw;
					}

					$c['absmiw'] = $mw;

					if (isset($c['R']) && $c['R']) {
						$c['maw'] = $c['miw'] = $this->FontSize + $extrcw;
						if (isset($c['w'])) { // If cell width is specified
							if ($c['miw'] < $c['w']) {
								$c['miw'] = $c['w'];
							}
						}
						if (!isset($c['colspan'])) {
							if ($wc['miw'] < $c['miw']) {
								$wc['miw'] = $c['miw'];
							}
							if ($wc['maw'] < $c['maw']) {
								$wc['maw'] = $c['maw'];
							}

							if ($firstpass) {
								if (isset($table['l'][$j])) {
									$table['l'][$j] += $c['miw'];
								} else {
									$table['l'][$j] = $c['miw'];
								}
							}
						}
						if ($c['miw'] > $wc['miw']) {
							$wc['miw'] = $c['miw'];
						}
						if ($wc['miw'] > $wc['maw']) {
							$wc['maw'] = $wc['miw'];
						}
						continue;
					}

					if ($firstpass) {
						if (isset($c['s'])) {
							$c['s'] += $extrcw;
						}
						if (isset($c['maxs'])) {
							$c['maxs'] += $extrcw;
						}
						if (isset($c['nestedmiw'])) {
							$c['nestedmiw'] += $extrcw;
						}
						if (isset($c['nestedmaw'])) {
							$c['nestedmaw'] += $extrcw;
						}
					}


					// If minimum width has already been set by a nested table or inline object (image/form), use it
					if (isset($c['nestedmiw']) && (!isset($this->table[1][1]['overflow']) || $this->table[1][1]['overflow'] != 'visible')) {
						$miw = $c['nestedmiw'];
					} else {
						$miw = $mw;
					}

					if (isset($c['maxs']) && $c['maxs'] != '') {
						$c['s'] = $c['maxs'];
					}

					// If maximum width has already been set by a nested table, use it
					if (isset($c['nestedmaw'])) {
						$c['maw'] = $c['nestedmaw'];
					} else {
						$c['maw'] = $c['s'];
					}

					if (isset($table['overflow']) && $table['overflow'] == 'visible' && $table['level'] == 1) {
						if (($c['maw'] + $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
							$c['maw'] = $this->blk[$this->blklvl]['inner_width'] - $tblbw;
						}
					}

					if (isset($c['nowrap']) && $c['nowrap']) {
						$miw = $c['maw'];
					}

					if (isset($c['wpercent']) && $firstpass) {
						if (isset($c['colspan'])) { // Not perfect - but % set on colspan is shared equally on cols.
							for ($k = 0; $k < $c['colspan']; $k++) {
								$table['wc'][($j + $k)]['wpercent'] = $c['wpercent'] / $c['colspan'];
							}
						} else {
							if (isset($table['w']) && $table['w']) {
								$c['w'] = $c['wpercent'] / 100 * ($table['w'] - $tblbw );
							}
							$wc['wpercent'] = $c['wpercent'];
						}
					}

					if (isset($table['overflow']) && $table['overflow'] == 'visible' && $table['level'] == 1) {
						if (isset($c['w']) && ($c['w'] + $tblbw) > $this->blk[$this->blklvl]['inner_width']) {
							$c['w'] = $this->blk[$this->blklvl]['inner_width'] - $tblbw;
						}
					}


					if (isset($c['w'])) { // If cell width is specified
						if ($miw < $c['w']) {
							$c['miw'] = $c['w'];
						} // Cell min width = that specified
						if ($miw > $c['w']) {
							$c['miw'] = $c['w'] = $miw;
						} // If width specified is less than minimum allowed (W) increase it
						// mPDF 5.7.4  Do not set column width in colspan
						// cf. http://www.mpdf1.com/forum/discussion/2221/colspan-bug
						if (!isset($c['colspan'])) {
							if (!isset($wc['w'])) {
								$wc['w'] = 1;
							}  // If the Col width is not specified = set it to 1
						}
						// mPDF 5.7.3  cf. http://www.mpdf1.com/forum/discussion/1648/nested-table-bug-
						$c['maw'] = $c['w'];
					} else {
						$c['miw'] = $miw;
					} // If cell width not specified -> set Cell min width it to minimum allowed (W)

					if (isset($c['miw']) && $c['maw'] < $c['miw']) {
						$c['maw'] = $c['miw'];
					} // If Cell max width < Minwidth - increase it to =
					if (!isset($c['colspan'])) {
						if (isset($c['miw']) && $wc['miw'] < $c['miw']) {
							$wc['miw'] = $c['miw'];
						} // Update Col Minimum and maximum widths
						if ($wc['maw'] < $c['maw']) {
							$wc['maw'] = $c['maw'];
						}
						if ((isset($wc['absmiw']) && $wc['absmiw'] < $c['absmiw']) || !isset($wc['absmiw'])) {
							$wc['absmiw'] = $c['absmiw'];
						} // Update Col Minimum and maximum widths

						if (isset($table['l'][$j])) {
							$table['l'][$j] += $c['s'];
						} else {
							$table['l'][$j] = $c['s'];
						}
					} else {
						$listspan[] = [$i, $j];
					}

					// Check if minimum width of the whole column is big enough for largest word to fit
					// mPDF 6
					if (isset($c['textbuffer'])) {
						if (isset($table['overflow']) && $table['overflow'] == 'wrap') {
							$letter = true;
						} // check for maximum width of letters
						else {
							$letter = false;
						}
						$minwidth = $this->TableCheckMinWidth($wc['miw'] - $extrcw, 0, $c['textbuffer'], $letter);
					} else {
						$minwidth = 0;
					}
					if ($minwidth < 0) {
						// increase minimum width
						if (!isset($c['colspan'])) {
							$wc['miw'] = max($wc['miw'], ((-$minwidth) + $extrcw));
						} else {
							$c['miw'] = max($c['miw'], ((-$minwidth) + $extrcw));
						}
					}
					if (!isset($c['colspan'])) {
						if ($wc['miw'] > $wc['maw']) {
							$wc['maw'] = $wc['miw'];
						} // update maximum width, if needed
					}
				}
				unset($c);
			}//rows
		}//columns
		// COLUMN SPANS
		$wc = &$table['wc'];
		foreach ($listspan as $span) {
			list($i, $j) = $span;
			$c = &$cs[$i][$j];
			$lc = $j + $c['colspan'];
			if ($lc > $nc) {
				$lc = $nc;
			}
			$wis = $wisa = 0;
			$was = $wasa = 0;
			$list = [];
			for ($k = $j; $k < $lc; $k++) {
				if (isset($table['l'][$k])) {
					if ($c['R']) {
						$table['l'][$k] += $c['miw'] / $c['colspan'];
					} else {
						$table['l'][$k] += $c['s'] / $c['colspan'];
					}
				} else {
					if ($c['R']) {
						$table['l'][$k] = $c['miw'] / $c['colspan'];
					} else {
						$table['l'][$k] = $c['s'] / $c['colspan'];
					}
				}
				$wis += $wc[$k]['miw'];   // $wis is the sum of the column miw in the colspan
				$was += $wc[$k]['maw'];   // $was is the sum of the column maw in the colspan
				if (!isset($c['w'])) {
					$list[] = $k;
					$wisa += $wc[$k]['miw']; // $wisa is the sum of the column miw in cells with no width specified in the colspan
					$wasa += $wc[$k]['maw']; // $wasa is the sum of the column maw in cells with no width specified in the colspan
				}
			}
			if ($c['miw'] > $wis) {
				if (!$wis) {
					for ($k = $j; $k < $lc; $k++) {
						$wc[$k]['miw'] = $c['miw'] / $c['colspan'];
					}
				} elseif (!count($list)) {
					$wi = $c['miw'] - $wis;
					for ($k = $j; $k < $lc; $k++) {
						$wc[$k]['miw'] += ($wc[$k]['miw'] / $wis) * $wi;
					}
				} else {
					$wi = $c['miw'] - $wis;
					// mPDF 5.7.2   Extra min width distributed proportionately to all cells in colspan without a specified width
					// cf. http://www.mpdf1.com/forum/discussion/1607#Item_4
					foreach ($list as $k) {
						if (!isset($wc[$k]['w']) || !$wc[$k]['w']) {
							$wc[$k]['miw'] += ($wc[$k]['miw'] / $wisa) * $wi;
						}
					} // mPDF 5.7.2
				}
			}
			if ($c['maw'] > $was) {
				if (!$wis) {
					for ($k = $j; $k < $lc; $k++) {
						$wc[$k]['maw'] = $c['maw'] / $c['colspan'];
					}
				} elseif (!count($list)) {
					$wi = $c['maw'] - $was;
					for ($k = $j; $k < $lc; $k++) {
						$wc[$k]['maw'] += ($wc[$k]['maw'] / $was) * $wi;
					}
				} else {
					$wi = $c['maw'] - $was;
					// mPDF 5.7.4  Extra max width distributed evenly to all cells in colspan without a specified width
					// cf. http://www.mpdf1.com/forum/discussion/2221/colspan-bug
					foreach ($list as $k) {
						$wc[$k]['maw'] += $wi / count($list);
					}
				}
			}
			unset($c);
		}

		$checkminwidth = 0;
		$checkmaxwidth = 0;
		$totallength = 0;

		for ($i = 0; $i < $nc; $i++) {
			$checkminwidth += $table['wc'][$i]['miw'];
			$checkmaxwidth += $table['wc'][$i]['maw'];
			$totallength += isset($table['l']) ? $table['l'][$i] : 0;
		}

		if (!isset($table['w']) && $firstpass) {
			$sumpc = 0;
			$notset = 0;
			for ($i = 0; $i < $nc; $i++) {
				if (isset($table['wc'][$i]['wpercent']) && $table['wc'][$i]['wpercent']) {
					$sumpc += $table['wc'][$i]['wpercent'];
				} else {
					$notset++;
				}
			}

			// If sum of widths as %  >= 100% and not all columns are set
			// Set a nominal width of 1% for unset columns
			if ($sumpc >= 100 && $notset) {
				for ($i = 0; $i < $nc; $i++) {
					if ((!isset($table['wc'][$i]['wpercent']) || !$table['wc'][$i]['wpercent']) &&
						(!isset($table['wc'][$i]['w']) || !$table['wc'][$i]['w'])) {
						$table['wc'][$i]['wpercent'] = 1;
					}
				}
			}


			if ($sumpc) { // if any percents are set
				$sumnonpc = (100 - $sumpc);
				$sumpc = max($sumpc, 100);
				$miwleft = 0;
				$miwleftcount = 0;
				$miwsurplusnonpc = 0;
				$maxcalcmiw = 0;
				$mawleft = 0;
				$mawleftcount = 0;
				$mawsurplusnonpc = 0;
				$maxcalcmaw = 0;
				$mawnon = 0;
				$miwnon = 0;
				for ($i = 0; $i < $nc; $i++) {
					if (isset($table['wc'][$i]['wpercent'])) {
						$maxcalcmiw = max($maxcalcmiw, ($table['wc'][$i]['miw'] * $sumpc / $table['wc'][$i]['wpercent']));
						$maxcalcmaw = max($maxcalcmaw, ($table['wc'][$i]['maw'] * $sumpc / $table['wc'][$i]['wpercent']));
					} else {
						$miwleft += $table['wc'][$i]['miw'];
						$mawleft += $table['wc'][$i]['maw'];
						if (!isset($table['wc'][$i]['w'])) {
							$miwleftcount++;
							$mawleftcount++;
						}
					}
				}
				if ($miwleft && $sumnonpc > 0) {
					$miwnon = $miwleft * 100 / $sumnonpc;
				}
				if ($mawleft && $sumnonpc > 0) {
					$mawnon = $mawleft * 100 / $sumnonpc;
				}
				if (($miwnon > $checkminwidth || $maxcalcmiw > $checkminwidth) && $this->keep_table_proportions) {
					if ($miwnon > $maxcalcmiw) {
						$miwsurplusnonpc = round((($miwnon * $sumnonpc / 100) - $miwleft), 3);
						$checkminwidth = $miwnon;
					} else {
						$checkminwidth = $maxcalcmiw;
					}
					for ($i = 0; $i < $nc; $i++) {
						if (isset($table['wc'][$i]['wpercent'])) {
							$newmiw = $checkminwidth * $table['wc'][$i]['wpercent'] / 100;
							if ($table['wc'][$i]['miw'] < $newmiw) {
								$table['wc'][$i]['miw'] = $newmiw;
							}
							$table['wc'][$i]['w'] = 1;
						} elseif ($miwsurplusnonpc && !$table['wc'][$i]['w']) {
							$table['wc'][$i]['miw'] += $miwsurplusnonpc / $miwleftcount;
						}
					}
				}
				if (($mawnon > $checkmaxwidth || $maxcalcmaw > $checkmaxwidth)) {
					if ($mawnon > $maxcalcmaw) {
						$mawsurplusnonpc = round((($mawnon * $sumnonpc / 100) - $mawleft), 3);
						$checkmaxwidth = $mawnon;
					} else {
						$checkmaxwidth = $maxcalcmaw;
					}
					for ($i = 0; $i < $nc; $i++) {
						if (isset($table['wc'][$i]['wpercent'])) {
							$newmaw = $checkmaxwidth * $table['wc'][$i]['wpercent'] / 100;
							if ($table['wc'][$i]['maw'] < $newmaw) {
								$table['wc'][$i]['maw'] = $newmaw;
							}
							$table['wc'][$i]['w'] = 1;
						} elseif ($mawsurplusnonpc && !$table['wc'][$i]['w']) {
							$table['wc'][$i]['maw'] += $mawsurplusnonpc / $mawleftcount;
						}
						if ($table['wc'][$i]['maw'] < $table['wc'][$i]['miw']) {
							$table['wc'][$i]['maw'] = $table['wc'][$i]['miw'];
						}
					}
				}
				if ($checkminwidth > $checkmaxwidth) {
					$checkmaxwidth = $checkminwidth;
				}
			}
		}

		if (isset($table['wpercent']) && $table['wpercent']) {
			$checkminwidth *= (100 / $table['wpercent']);
			$checkmaxwidth *= (100 / $table['wpercent']);
		}


		$checkminwidth += $tblbw;
		$checkmaxwidth += $tblbw;

		// Table['miw'] set by percent in first pass may be larger than sum of column miw
		if ((isset($table['miw']) && $checkminwidth > $table['miw']) || !isset($table['miw'])) {
			$table['miw'] = $checkminwidth;
		}
		if ((isset($table['maw']) && $checkmaxwidth > $table['maw']) || !isset($table['maw'])) {
			$table['maw'] = $checkmaxwidth;
		}
		$table['tl'] = $totallength;

		// mPDF 6
		if ($this->table_rotate) {
			$mxw = $this->tbrot_maxw;
		} else {
			$mxw = $this->blk[$this->blklvl]['inner_width'];
		}

		if (!isset($table['overflow'])) {
			$table['overflow'] = null;
		}

		if ($table['overflow'] == 'visible') {
			return [0, 0];
		} elseif ($table['overflow'] == 'hidden' && !$this->table_rotate && !$this->ColActive && $checkminwidth > $mxw) {
			$table['w'] = $table['miw'];
			return [0, 0];
		}
		// elseif ($table['overflow']=='wrap') { return array(0,0); }	// mPDF 6

		if (isset($table['w']) && $table['w']) {

			if ($table['w'] >= $checkminwidth && $table['w'] <= $mxw) {
				$table['maw'] = $mxw = $table['w'];
			} elseif ($table['w'] >= $checkminwidth && $table['w'] > $mxw && $this->keep_table_proportions) {
				$checkminwidth = $table['w'];
			} elseif ($table['w'] < $checkminwidth && $checkminwidth < $mxw && $this->keep_table_proportions) {
				$table['maw'] = $table['w'] = $checkminwidth;
			} else {
				unset($table['w']);
			}
		}

		$ratio = $checkminwidth / $mxw;

		if ($checkminwidth > $mxw) {
			return [($ratio + 0.001), $checkminwidth]; // 0.001 to allow for rounded numbers when resizing
		}

		unset($cs);

		return [0, 0];
	}
625752
function(node) {
        var w = Y_DOM._getDocSize(node).width;
        return Math.max(w, Y_DOM._getWinSize(node).width);
    }