/*!
Function for setting frame margins. Frames are used to define for example footer and header areas

\param info, standard ezpdf callback function
550689
function callFrameMargins( $info )
    {
        $params = array();
        eZPDFTable::extractParameters( $info['p'], 0, $params, true );

        if( isset( $this->ezFrame[$params['identifier']] ) )
        {
            $this->ezFrame[$params['identifier']] = array_merge( $this->ezFrame[$params['identifier']],
                                                                 $params );
        }
        else
        {
            $this->ezFrame[$params['identifier']] = $params;
        }
    }
1223166
public function registerPageMargins(): PdfInterface
    {
        $mpdf = $this->mpdf;

        /* Set the margins and page current page width */
        $mpdf->SetLeftMargin($this->marginLeft);
        $mpdf->SetTopMargin($this->marginTop);
        $mpdf->SetRightMargin($this->marginRight);
        $mpdf->SetAutoPageBreak(true, $this->marginBottom);
        $mpdf->margin_header = $this->marginHeader;
        $mpdf->margin_footer = $this->marginFooter;
        $mpdf->orig_lMargin = $mpdf->DeflMargin = $mpdf->lMargin = $this->marginLeft;
        $mpdf->orig_tMargin = $mpdf->tMargin = $this->marginTop;
        $mpdf->orig_rMargin = $mpdf->DefrMargin = $mpdf->rMargin = $this->marginRight;
        $mpdf->orig_bMargin = $mpdf->bMargin = $this->marginBottom;
        $mpdf->orig_hMargin = $mpdf->margin_header = $this->marginHeader;
        $mpdf->orig_fMargin = $mpdf->margin_footer = $this->marginFooter;
        $mpdf->pgwidth = $mpdf->w - $mpdf->lMargin - $mpdf->rMargin;

        return $this;
    }
1287549
function () {
            var i, len, page, $page,
                width, height, left, top, paddingH,
                state = this.state,
                viewportWidth = state.viewportDimensions.clientWidth,
                viewportHeight = state.viewportDimensions.clientHeight;
            // update pages so they are centered (preserving margins)
            for (i = 0, len = this.$pages.length; i < len; ++i) {
                $page = this.$pages.eq(i);
                page = state.pages[i];

                if (this.twoPageMode) {
                    paddingH = (i % 2 === 1) ? page.paddingRight : page.paddingLeft;
                } else {
                    paddingH = page.paddingRight + page.paddingLeft;
                }
                width = (page.actualWidth + paddingH) * state.zoomState.zoom;
                height = (page.actualHeight + page.paddingTop + page.paddingBottom) * state.zoomState.zoom;

                if (this.twoPageMode) {
                    left = Math.max(0, (viewportWidth - width * 2) / 2);
                    if (i % 2 === 1) {
                        left += width;
                    }
                } else {
                    left = (viewportWidth - width) / 2;
                }
                top = (viewportHeight - height) / 2;
                left = Math.max(left, 0);
                top = Math.max(top, 0);
                $page.css({
                    marginLeft: left,
                    marginTop: top
                });
            }
        }
476156
function set_containing_block($x = null, $y = null, $w = null, $h = null) {
    parent::set_containing_block($x,$y,$w,$h);
    //$w = $this->get_containing_block("w");
    if ( isset($h) )
      $this->_bottom_page_margin = $h; // - $this->_frame->get_style()->length_in_pt($this->_frame->get_style()->margin_bottom, $w);
  }
691118
function SetMargins() {
    /////////////////////////////////////////////////////////////////
    // When the image is first created - set the margins
    // to be the standard viewport.
    // The standard viewport is the full area of the view surface (or panel),
    // less a margin of 4 character heights all round for labelling.
    // It thus depends on the current character size, set by SetCharacterHeight().
    /////////////////////////////////////////////////////////////////

    $str = preg_split("/\n/",$this->title_txt);
    $nbLines = count($str);

    if ($this->use_ttf == 1) {
      $title_size = $this->TTFBBoxSize($this->title_ttffont_size, $this->title_angle, $this->title_ttffont, 'X'); //An array
      if ($nbLines == 1) {
        $this->y_top_margin = $title_size[1] * 4;
      } else {
        $this->y_top_margin = $title_size[1] * ($nbLines+3);
      }

      //ajo working here
      //$x_label_size = $this->TTFBBoxSize($this->x_label_ttffont_size, 0, $this->axis_ttffont, $this->x_label_txt);

      $this->y_bot_margin = $this->x_label_height ;
      $this->x_left_margin = $this->y_label_width * 2 + $this->tick_length;
      $this->x_right_margin = 33.0; // distance between right and end of x axis in pixels
    } else {
      $title_size = array(ImageFontWidth($this->title_font) * strlen($this->title_txt),ImageFontHeight($this->title_font));
      //$this->y_top_margin = ($title_size[1] * 4);
      if ($nbLines == 1) {
        $this->y_top_margin = $title_size[1] * 4;
      } else {
        $this->y_top_margin = $title_size[1] * ($nbLines+3);
      }
      if ($this->x_datalabel_angle == 90) {
        $this->y_bot_margin = 76.0; // Must be integer
      } else {
        $this->y_bot_margin = 66.0; // Must be integer
      }
      $this->x_left_margin = 77.0; // distance between left and start of x axis in pixels
      $this->x_right_margin = 33.0; // distance between right and end of x axis in pixels
    }

//exit;
    $this->x_tot_margin = $this->x_left_margin + $this->x_right_margin;
    $this->y_tot_margin = $this->y_top_margin + $this->y_bot_margin;

    if ($this->plot_max_x && $this->plot_max_y && $this->plot_area_width ) { //If data has already been analysed then set translation
      $this->SetTranslation();
    }
  }
805950
function set_frame_heights($table_height, $content_height) {


    // Distribute the increased height proportionally amongst each row
    foreach ( $this->_frames as $arr ) {
      $frame = $arr["frame"];

      $h = 0;
      foreach ($arr["rows"] as $row ) {
        if ( !isset($this->_rows[$row]) )
          continue;

        $h += $this->_rows[$row]["height"];
      }
      
      if ( $content_height > 0 )
        $new_height = ($h / $content_height) * $table_height;
      else
        $new_height = 0;

      if ( $frame instanceof Table_Cell_Frame_Decorator )
        $frame->set_cell_height($new_height);
      else
        $frame->get_style()->height = $new_height;
    }

  }
108841
function text($x, $y, $text, $font, $size, $color = array(0, 0, 0), $adjust = 0.0, $char_space = 0.0, $angle = 0.0) { //***
		//Helpers::dompdf_debug("trace", "($x, $y, $text, ". basename($font) .", $size, [$color[0], $color[1], $color[2]], $adjust, $angle, $blend, $opacity)");

		list ($r, $g, $b) = $this->_get_rgb($color);
		$this->_pdf->SetTextColor($r, $g, $b);
		//***$this->_set_line_transparency($blend, $opacity);
		//***$this->_set_fill_transparency($blend, $opacity);

		$fontdata = $this->_get_font($font);
		$this->_pdf->SetFont($fontdata['family'], $fontdata['style'] /*strpos($font, '-Bold') === false ? '' : 'B'*/, $size, $font);

		//$this->_pdf->SetFontSize($size); // ???

		if ($adjust > 0) {
			$a = explode(' ', $text);
			//$this->_pdf->SetXY($x - 3, $y + (self::FONT_HEIGHT_SCALE - 1) * $size);
			$this->_pdf->SetXY($x, $y);

			//$y += self::FONT_HEIGHT_SCALE * $size + 1;
			for ($i = 0; $i < count($a)-1; $i++) {
				$this->_pdf->Write($size, $a[$i].' ', '');
				//$this->_pdf->Text($x, $y, $a[$i].' ');
				$this->_pdf->SetX($this->_pdf->GetX()+$adjust);
				//$x += $this->_pdf->GetX() + $adjust;
			}
			$this->_pdf->Write($size, $a[$i], '');
			//$this->_pdf->Text($x, $y, $a[$i].' ');
		}
		else {
			if ($angle != 0) {
				$this->_pdf->StartTransform();
				//$y += self::FONT_HEIGHT_SCALE * $size;
				//$y += $size;
				$this->_pdf->Rotate(-$angle, $x, $y);
				$this->_pdf->Text($x, $y, $text, false, false, true, 0, 0, '', 0, '', 0, false, 'T', 'T');
				$this->_pdf->StopTransform();
			}
			else {
				//$pippo = $this->_pdf->getFontAscent($fontdata['family'], $fontdata['style'], $size);
				//$y += $pippo / 8;
				//$y = $y - 0.85 * $size;	// + 0.8 * $size;
				$this->_pdf->Text($x, $y, $text, false, false, true, 0, 0, '', 0, '', 0, false, 'T', 'T');
			}
		}
	}
772973
function callImage( $info )
    {
        $params = array();
        $leftMargin = false;
        $rightMargin = false;

        eZPDFTable::extractParameters( $info['p'], 0, $params, true );

        $filename = rawurldecode( $params['src'] );

        $mimetype = eZMimeType::findByFileContents( $filename );

        $this->transaction( 'start' );

        if ( !isset( $params['static'] ) )
        {
            $params['static'] = false;
        }

        if ( $this->yOffset()-$params['height'] < $this->ez['bottomMargin'] )
        {
            $this->ezNewPage();
        }

        if ( isset( $params['dpi'] ) )
        {
            $newWidth = (int)( $params['width'] * ( (int)$params['dpi'] / 72 ) );
            $newHeight = (int)( $params['height'] * ( (int)$params['dpi'] / 72 ) );
            $newFilename = eZSys::cacheDirectory() . '/' . md5( mt_rand() ) . '.jpg';
            while( file_exists( $newFilename ) )
            {
                $newFilename = eZSys::cacheDirectory() . '/' . md5( mt_rand() ) . '.jpg';
            }

            $img = eZImageManager::factory();
            $newImg = $img->convert( $filename,
                                     $newFilename,
                                     false,
                                     array( 'filters' => array( array( 'name' => 'geometry/scaledownonly',
                                                                       'data' => array( $newWidth, $newHeight ) ) ) ) );
            $filename = $newFilename['url'];
        }

        $drawableAreaWidth = $this->ez['pageWidth'] - $this->ez['leftMargin'] - $this->ez['rightMargin'];

        switch( $params['align'] )
        {
            case 'right':
            {
                $xOffset = $this->ez['pageWidth'] - ( $this->rightMargin() + $params['width'] );
                $rightMargin = $this->rightMargin() + $params['width'];
                if ( $rightMargin > ( $drawableAreaWidth + $this->rightMargin() ) )
                {
                    // the image is equal or larger then width of the page(of the drawable area) => no point
                    // to set $rightMargin and next object(text, image, ...) should be outputted below the image.
                    $rightMargin = false;
                }
            } break;

            case 'center':
            {
                $xOffset = ( $this->ez['pageWidth'] - $this->rightMargin() - $this->leftMargin() ) / 2 + $this->leftMargin() - $params['width'] / 2;
            } break;

            case 'left':
            default:
            {
                $xOffset = $this->leftMargin();
                $leftMargin = $this->leftMargin() + $params['width'];
                if ( $leftMargin > ( $drawableAreaWidth + $this->leftMargin() ) )
                {
                    // the image is equal or larger then width of the page(of the drawable area) => no point
                    // to set $leftMargin and next object(text, image, ...) should be outputted below the image.
                    $leftMargin = false;
                }

            } break;
        }

        if ( isset( $params['x'] ) )
        {
            $xOffset = $params['x'];
            $leftMargin = false;
            $rightMargin = false;
        }

        $yOffset = $this->yOffset();
        $whileCount = 0;

        if ( $params['width'] < $drawableAreaWidth )
        {
            while ( $this->leftMargin( $yOffset ) > $xOffset &&
                    ++$whileCount < 100 )
            {
                $yOffset -= 10;
            }
        }

        $yOffset -= $params['height'];
        $yOffset += $this->lineHeight()/2;
        if ( isset( $params['y'] ) )
        {
            $yOffset = $params['y'];
        }

        if ( $leftMargin !== false )
        {
            $this->setLimitedLeftMargin( $yOffset - 7, $yOffset + $params['height'] + 7, $leftMargin + 7 );
        }
        if ( $rightMargin !== false )
        {
            $this->setLimitedRightMargin( $yOffset- 7, $yOffset + $params['height'] + 7, $rightMargin + 7 );
        }

        switch( $mimetype['name'] )
        {
            case 'image/gif':
            {
                $newFilename = eZSys::cacheDirectory() . '/' . md5( mt_rand() ) . '.jpg';
                while( file_exists( $newFilename ) )
                {
                    $newFilename = eZSys::cacheDirectory() . '/' . md5( mt_rand() ) . '.jpg';
                }
                $newMimetype = eZMimeType::findByURL( $newFilename );

                $img = eZImageManager::factory();
                $newImg = $img->convert( $mimetype,
                                         $newMimetype,
                                         false,
                                         array() );
                $this->addJpegFromFile( $newMimetype['url'],
                                        $xOffset,
                                        $yOffset,
                                        $params['width'],
                                        $params['height'] );
            } break;

            case 'image/jpeg':
            {
                $this->addJpegFromFile( $filename,
                                        $xOffset,
                                        $yOffset,
                                        $params['width'],
                                        $params['height'] );
            } break;

            case 'image/png':
            {
                if ( $this->addPngFromFile( $filename,
                                            $xOffset,
                                            $yOffset,
                                            $params['width'],
                                            $params['height'] ) === false )
                {
                    $this->transaction('abort');
                    return;
                }
            } break;

            default:
            {
                eZDebug::writeError( 'Unsupported image file type, '. $mimetype['name'], __METHOD__ );
                $this->transaction( 'abort' );
                return;
            } break;
        }

        $this->transaction( 'commit' );

        if ( !$leftMargin && !$rightMargin  && !$params['static'] )
        {
            $this->y -= $params['height'] + $this->lineHeight();
        }

        return array( 'y' => $params['height'] + $this->lineHeight() );
    }
16123
function _setListMarker($listitemtype, $listitemimage, $listitemposition)
	{
		// if position:inside (and NOT table) - output now as a textbuffer; (so if next is block, will move to new line)
		// elseif position:outside (and NOT table) - output in front of first textbuffer output by setting listitem (cf. _saveTextBuffer)
		$e = '';
		$this->listitem = '';
		$spacer = ' ';
		// IMAGE
		if ($listitemimage && $listitemimage != 'none') {
			$listitemimage = trim(preg_replace('/url\(["\']*(.*?)["\']*\)/', '\\1', $listitemimage));

			// ? Restrict maximum height/width of list marker??
			$maxWidth = 100;
			$maxHeight = 100;

			$objattr = [];
			$objattr['margin_top'] = 0;
			$objattr['margin_bottom'] = 0;
			$objattr['margin_left'] = 0;
			$objattr['margin_right'] = 0;
			$objattr['padding_top'] = 0;
			$objattr['padding_bottom'] = 0;
			$objattr['padding_left'] = 0;
			$objattr['padding_right'] = 0;
			$objattr['width'] = 0;
			$objattr['height'] = 0;
			$objattr['border_top']['w'] = 0;
			$objattr['border_bottom']['w'] = 0;
			$objattr['border_left']['w'] = 0;
			$objattr['border_right']['w'] = 0;
			$objattr['visibility'] = 'visible';
			$srcpath = $listitemimage;
			$orig_srcpath = $listitemimage;

			$objattr['vertical-align'] = 'BS'; // vertical alignment of marker (baseline)
			$w = 0;
			$h = 0;

			// Image file
			$info = $this->imageProcessor->getImage($srcpath, true, true, $orig_srcpath);
			if (!$info) {
				return;
			}

			if ($info['w'] == 0 && $info['h'] == 0) {
				$info['h'] = $this->sizeConverter->convert('1em', $this->blk[$this->blklvl]['inner_width'], $this->FontSize, false);
			}

			$objattr['file'] = $srcpath;

			// Default width and height calculation if needed
			if ($w == 0 and $h == 0) {
				/* -- IMAGES-WMF -- */
				if ($info['type'] == 'wmf') {
					// WMF units are twips (1/20pt)
					// divide by 20 to get points
					// divide by k to get user units
					$w = abs($info['w']) / (20 * Mpdf::SCALE);
					$h = abs($info['h']) / (20 * Mpdf::SCALE);
				} else { 				/* -- END IMAGES-WMF -- */
					if ($info['type'] == 'svg') {
						// SVG units are pixels
						$w = abs($info['w']) / Mpdf::SCALE;
						$h = abs($info['h']) / Mpdf::SCALE;
					} else {
						// Put image at default image dpi
						$w = ($info['w'] / Mpdf::SCALE) * (72 / $this->img_dpi);
						$h = ($info['h'] / Mpdf::SCALE) * (72 / $this->img_dpi);
					}
				}
			}
			// IF WIDTH OR HEIGHT SPECIFIED
			if ($w == 0) {
				$w = abs($h * $info['w'] / $info['h']);
			}
			if ($h == 0) {
				$h = abs($w * $info['h'] / $info['w']);
			}

			if ($w > $maxWidth) {
				$w = $maxWidth;
				$h = abs($w * $info['h'] / $info['w']);
			}

			if ($h > $maxHeight) {
				$h = $maxHeight;
				$w = abs($h * $info['w'] / $info['h']);
			}

			$objattr['type'] = 'image';
			$objattr['itype'] = $info['type'];

			$objattr['orig_h'] = $info['h'];
			$objattr['orig_w'] = $info['w'];

			/* -- IMAGES-WMF -- */
			if ($info['type'] == 'wmf') {
				$objattr['wmf_x'] = $info['x'];
				$objattr['wmf_y'] = $info['y'];
			} else { 			/* -- END IMAGES-WMF -- */
				if ($info['type'] == 'svg') {
					$objattr['wmf_x'] = $info['x'];
					$objattr['wmf_y'] = $info['y'];
				}
			}

			$objattr['height'] = $h;
			$objattr['width'] = $w;
			$objattr['image_height'] = $h;
			$objattr['image_width'] = $w;

			$objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr');
			$objattr['listmarker'] = true;

			$objattr['listmarkerposition'] = $listitemposition;

			$e = "\xbb\xa4\xactype=image,objattr=" . serialize($objattr) . "\xbb\xa4\xac";
			$this->_saveTextBuffer($e);

			if ($listitemposition == 'inside') {
				$e = $spacer;
				$this->_saveTextBuffer($e);
			}
		} elseif ($listitemtype == 'disc' || $listitemtype == 'circle' || $listitemtype == 'square') { // SYMBOL (needs new font)
			$objattr = [];
			$objattr['type'] = 'listmarker';
			$objattr['listmarkerposition'] = $listitemposition;
			$objattr['width'] = 0;
			$size = $this->sizeConverter->convert($this->list_symbol_size, $this->FontSize);
			$objattr['size'] = $size;
			$objattr['offset'] = $this->sizeConverter->convert($this->list_marker_offset, $this->FontSize);

			if ($listitemposition == 'inside') {
				$objattr['width'] = $size + $objattr['offset'];
			}

			$objattr['height'] = $this->FontSize;
			$objattr['vertical-align'] = 'T';
			$objattr['text'] = '';
			$objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr');
			$objattr['bullet'] = $listitemtype;
			$objattr['colorarray'] = $this->colorarray;
			$objattr['fontfamily'] = $this->FontFamily;
			$objattr['fontsize'] = $this->FontSize;
			$objattr['fontsizept'] = $this->FontSizePt;
			$objattr['fontstyle'] = $this->FontStyle;

			$e = "\xbb\xa4\xactype=listmarker,objattr=" . serialize($objattr) . "\xbb\xa4\xac";
			$this->listitem = $this->_saveTextBuffer($e, '', '', true); // true returns array

		} elseif (preg_match('/U\+([a-fA-F0-9]+)/i', $listitemtype, $m)) { // SYMBOL 2 (needs new font)

			if ($this->_charDefined($this->CurrentFont['cw'], hexdec($m[1]))) {
				$list_item_marker = UtfString::codeHex2utf($m[1]);
			} else {
				$list_item_marker = '-';
			}
			if (preg_match('/rgb\(.*?\)/', $listitemtype, $m)) {
				$list_item_color = $this->colorConverter->convert($m[0], $this->PDFAXwarnings);
			} else {
				$list_item_color = '';
			}

			// SAVE then SET COLR
			$save_colorarray = $this->colorarray;
			if ($list_item_color) {
				$this->colorarray = $list_item_color;
			}

			if ($listitemposition == 'inside') {
				$e = $list_item_marker . $spacer;
				$this->_saveTextBuffer($e);
			} else {
				$objattr = [];
				$objattr['type'] = 'listmarker';
				$objattr['width'] = 0;
				$objattr['height'] = $this->FontSize;
				$objattr['vertical-align'] = 'T';
				$objattr['text'] = $list_item_marker;
				$objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr');
				$objattr['colorarray'] = $this->colorarray;
				$objattr['fontfamily'] = $this->FontFamily;
				$objattr['fontsize'] = $this->FontSize;
				$objattr['fontsizept'] = $this->FontSizePt;
				$objattr['fontstyle'] = $this->FontStyle;
				$e = "\xbb\xa4\xactype=listmarker,objattr=" . serialize($objattr) . "\xbb\xa4\xac";
				$this->listitem = $this->_saveTextBuffer($e, '', '', true); // true returns array
			}

			// RESET COLOR
			$this->colorarray = $save_colorarray;

		} else { // TEXT
			$counter = $this->listcounter[$this->listlvl];

			if ($listitemtype == 'none') {
				return;
			}

			$num = $this->_getStyledNumber($counter, $listitemtype, true);

			if ($listitemposition == 'inside') {
				$e = $num . $this->list_number_suffix . $spacer;
				$this->_saveTextBuffer($e);
			} else {
				if (isset($this->blk[$this->blklvl]['direction']) && $this->blk[$this->blklvl]['direction'] == 'rtl') {
					// REPLACE MIRRORED RTL $this->list_number_suffix  e.g. ) -> (  (NB could use Ucdn::$mirror_pairs)
					$m = strtr($this->list_number_suffix, ")]}", "([{") . $num;
				} else {
					$m = $num . $this->list_number_suffix;
				}

				$objattr = [];
				$objattr['type'] = 'listmarker';
				$objattr['width'] = 0;
				$objattr['height'] = $this->FontSize;
				$objattr['vertical-align'] = 'T';
				$objattr['text'] = $m;
				$objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr');
				$objattr['colorarray'] = $this->colorarray;
				$objattr['fontfamily'] = $this->FontFamily;
				$objattr['fontsize'] = $this->FontSize;
				$objattr['fontsizept'] = $this->FontSizePt;
				$objattr['fontstyle'] = $this->FontStyle;
				$e = "\xbb\xa4\xactype=listmarker,objattr=" . serialize($objattr) . "\xbb\xa4\xac";

				$this->listitem = $this->_saveTextBuffer($e, '', '', true); // true returns array
			}
		}
	}
985311
function WriteFixedPosHTML($html, $x, $y, $w, $h, $overflow = 'visible', $bounding = [])
	{
		// $overflow can be 'hidden', 'visible' or 'auto' - 'auto' causes autofit to size
		// Annotations disabled - enabled in mPDF 5.0
		// Links do work
		// Will always go on current page (or start Page 1 if required)
		// Probably INCOMPATIBLE WITH keep with table, columns etc.
		// Called externally or interally via <div style="position: [fixed|absolute]">
		// When used internally, $x $y $w $h and $overflow are all overridden by $bounding

		$overflow = strtolower($overflow);
		if ($this->state == 0) {
			$this->AddPage($this->CurOrientation);
		}
		$save_y = $this->y;
		$save_x = $this->x;
		$this->fullImageHeight = $this->h;
		$save_cols = false;
		/* -- COLUMNS -- */
		if ($this->ColActive) {
			$save_cols = true;
			$save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off
			$this->SetColumns(0);
		}
		/* -- END COLUMNS -- */
		$save_annots = $this->title2annots; // *ANNOTATIONS*
		$this->writingHTMLheader = true; // a FIX to stop pagebreaks etc.
		$this->writingHTMLfooter = true;
		$this->InFooter = true; // suppresses autopagebreaks
		$save_bgs = $this->pageBackgrounds;
		$checkinnerhtml = preg_replace('/\s/', '', $html);
		$rotate = 0;

		if ($w > $this->w) {
			$x = 0;
			$w = $this->w;
		}
		if ($h > $this->h) {
			$y = 0;
			$h = $this->h;
		}
		if ($x > $this->w) {
			$x = $this->w - $w;
		}
		if ($y > $this->h) {
			$y = $this->h - $h;
		}

		if (!empty($bounding)) {
			// $cont_ containing block = full physical page (position: absolute) or page inside margins (position: fixed)
			// $bbox_ Bounding box is the <div> which is positioned absolutely/fixed
			// top/left/right/bottom/width/height/background*/border*/padding*/margin* are taken from bounding
			// font*[family/size/style/weight]/line-height/text*[align/decoration/transform/indent]/color are transferred to $inner
			// as an enclosing <div> (after having checked ID/CLASS)
			// $x, $y, $w, $h are inside of $bbox_ = containing box for $inner_
			// $inner_ InnerHTML is the contents of that block to be output
			$tag = $bounding[0];
			$attr = $bounding[1];
			$orig_x0 = $bounding[2];
			$orig_y0 = $bounding[3];

			// As in WriteHTML() initialising
			$this->blklvl = 0;
			$this->lastblocklevelchange = 0;
			$this->blk = [];
			$this->initialiseBlock($this->blk[0]);

			$this->blk[0]['width'] = & $this->pgwidth;
			$this->blk[0]['inner_width'] = & $this->pgwidth;

			$this->blk[0]['blockContext'] = $this->blockContext;

			$properties = $this->cssManager->MergeCSS('BLOCK', 'BODY', '');
			$this->setCSS($properties, '', 'BODY');
			$this->blklvl = 1;
			$this->initialiseBlock($this->blk[1]);
			$this->blk[1]['tag'] = $tag;
			$this->blk[1]['attr'] = $attr;
			$this->Reset();
			$p = $this->cssManager->MergeCSS('BLOCK', $tag, $attr);
			if (isset($p['ROTATE']) && ($p['ROTATE'] == 90 || $p['ROTATE'] == -90 || $p['ROTATE'] == 180)) {
				$rotate = $p['ROTATE'];
			} // mPDF 6
			if (isset($p['OVERFLOW'])) {
				$overflow = strtolower($p['OVERFLOW']);
			}
			if (strtolower($p['POSITION']) == 'fixed') {
				$cont_w = $this->pgwidth; // $this->blk[0]['inner_width'];
				$cont_h = $this->h - $this->tMargin - $this->bMargin;
				$cont_x = $this->lMargin;
				$cont_y = $this->tMargin;
			} else {
				$cont_w = $this->w; // ABSOLUTE;
				$cont_h = $this->h;
				$cont_x = 0;
				$cont_y = 0;
			}

			// Pass on in-line properties to the innerhtml
			$css = '';
			if (isset($p['TEXT-ALIGN'])) {
				$css .= 'text-align: ' . strtolower($p['TEXT-ALIGN']) . '; ';
			}
			if (isset($p['TEXT-TRANSFORM'])) {
				$css .= 'text-transform: ' . strtolower($p['TEXT-TRANSFORM']) . '; ';
			}
			if (isset($p['TEXT-INDENT'])) {
				$css .= 'text-indent: ' . strtolower($p['TEXT-INDENT']) . '; ';
			}
			if (isset($p['TEXT-DECORATION'])) {
				$css .= 'text-decoration: ' . strtolower($p['TEXT-DECORATION']) . '; ';
			}
			if (isset($p['FONT-FAMILY'])) {
				$css .= 'font-family: ' . strtolower($p['FONT-FAMILY']) . '; ';
			}
			if (isset($p['FONT-STYLE'])) {
				$css .= 'font-style: ' . strtolower($p['FONT-STYLE']) . '; ';
			}
			if (isset($p['FONT-WEIGHT'])) {
				$css .= 'font-weight: ' . strtolower($p['FONT-WEIGHT']) . '; ';
			}
			if (isset($p['FONT-SIZE'])) {
				$css .= 'font-size: ' . strtolower($p['FONT-SIZE']) . '; ';
			}
			if (isset($p['LINE-HEIGHT'])) {
				$css .= 'line-height: ' . strtolower($p['LINE-HEIGHT']) . '; ';
			}
			if (isset($p['TEXT-SHADOW'])) {
				$css .= 'text-shadow: ' . strtolower($p['TEXT-SHADOW']) . '; ';
			}
			if (isset($p['LETTER-SPACING'])) {
				$css .= 'letter-spacing: ' . strtolower($p['LETTER-SPACING']) . '; ';
			}
			// mPDF 6
			if (isset($p['FONT-VARIANT-POSITION'])) {
				$css .= 'font-variant-position: ' . strtolower($p['FONT-VARIANT-POSITION']) . '; ';
			}
			if (isset($p['FONT-VARIANT-CAPS'])) {
				$css .= 'font-variant-caps: ' . strtolower($p['FONT-VARIANT-CAPS']) . '; ';
			}
			if (isset($p['FONT-VARIANT-LIGATURES'])) {
				$css .= 'font-variant-ligatures: ' . strtolower($p['FONT-VARIANT-LIGATURES']) . '; ';
			}
			if (isset($p['FONT-VARIANT-NUMERIC'])) {
				$css .= 'font-variant-numeric: ' . strtolower($p['FONT-VARIANT-NUMERIC']) . '; ';
			}
			if (isset($p['FONT-VARIANT-ALTERNATES'])) {
				$css .= 'font-variant-alternates: ' . strtolower($p['FONT-VARIANT-ALTERNATES']) . '; ';
			}
			if (isset($p['FONT-FEATURE-SETTINGS'])) {
				$css .= 'font-feature-settings: ' . strtolower($p['FONT-FEATURE-SETTINGS']) . '; ';
			}
			if (isset($p['FONT-LANGUAGE-OVERRIDE'])) {
				$css .= 'font-language-override: ' . strtolower($p['FONT-LANGUAGE-OVERRIDE']) . '; ';
			}
			if (isset($p['FONT-KERNING'])) {
				$css .= 'font-kerning: ' . strtolower($p['FONT-KERNING']) . '; ';
			}

			if (isset($p['COLOR'])) {
				$css .= 'color: ' . strtolower($p['COLOR']) . '; ';
			}
			if (isset($p['Z-INDEX'])) {
				$css .= 'z-index: ' . $p['Z-INDEX'] . '; ';
			}
			if ($css) {
				$html = '<div style="' . $css . '">' . $html . '</div>';
			}
			// Copy over (only) the properties to set for border and background
			$pb = [];
			$pb['MARGIN-TOP'] = (isset($p['MARGIN-TOP']) ? $p['MARGIN-TOP'] : '');
			$pb['MARGIN-RIGHT'] = (isset($p['MARGIN-RIGHT']) ? $p['MARGIN-RIGHT'] : '');
			$pb['MARGIN-BOTTOM'] = (isset($p['MARGIN-BOTTOM']) ? $p['MARGIN-BOTTOM'] : '');
			$pb['MARGIN-LEFT'] = (isset($p['MARGIN-LEFT']) ? $p['MARGIN-LEFT'] : '');
			$pb['PADDING-TOP'] = (isset($p['PADDING-TOP']) ? $p['PADDING-TOP'] : '');
			$pb['PADDING-RIGHT'] = (isset($p['PADDING-RIGHT']) ? $p['PADDING-RIGHT'] : '');
			$pb['PADDING-BOTTOM'] = (isset($p['PADDING-BOTTOM']) ? $p['PADDING-BOTTOM'] : '');
			$pb['PADDING-LEFT'] = (isset($p['PADDING-LEFT']) ? $p['PADDING-LEFT'] : '');
			$pb['BORDER-TOP'] = (isset($p['BORDER-TOP']) ? $p['BORDER-TOP'] : '');
			$pb['BORDER-RIGHT'] = (isset($p['BORDER-RIGHT']) ? $p['BORDER-RIGHT'] : '');
			$pb['BORDER-BOTTOM'] = (isset($p['BORDER-BOTTOM']) ? $p['BORDER-BOTTOM'] : '');
			$pb['BORDER-LEFT'] = (isset($p['BORDER-LEFT']) ? $p['BORDER-LEFT'] : '');
			if (isset($p['BORDER-TOP-LEFT-RADIUS-H'])) {
				$pb['BORDER-TOP-LEFT-RADIUS-H'] = $p['BORDER-TOP-LEFT-RADIUS-H'];
			}
			if (isset($p['BORDER-TOP-LEFT-RADIUS-V'])) {
				$pb['BORDER-TOP-LEFT-RADIUS-V'] = $p['BORDER-TOP-LEFT-RADIUS-V'];
			}
			if (isset($p['BORDER-TOP-RIGHT-RADIUS-H'])) {
				$pb['BORDER-TOP-RIGHT-RADIUS-H'] = $p['BORDER-TOP-RIGHT-RADIUS-H'];
			}
			if (isset($p['BORDER-TOP-RIGHT-RADIUS-V'])) {
				$pb['BORDER-TOP-RIGHT-RADIUS-V'] = $p['BORDER-TOP-RIGHT-RADIUS-V'];
			}
			if (isset($p['BORDER-BOTTOM-LEFT-RADIUS-H'])) {
				$pb['BORDER-BOTTOM-LEFT-RADIUS-H'] = $p['BORDER-BOTTOM-LEFT-RADIUS-H'];
			}
			if (isset($p['BORDER-BOTTOM-LEFT-RADIUS-V'])) {
				$pb['BORDER-BOTTOM-LEFT-RADIUS-V'] = $p['BORDER-BOTTOM-LEFT-RADIUS-V'];
			}
			if (isset($p['BORDER-BOTTOM-RIGHT-RADIUS-H'])) {
				$pb['BORDER-BOTTOM-RIGHT-RADIUS-H'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-H'];
			}
			if (isset($p['BORDER-BOTTOM-RIGHT-RADIUS-V'])) {
				$pb['BORDER-BOTTOM-RIGHT-RADIUS-V'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-V'];
			}
			if (isset($p['BACKGROUND-COLOR'])) {
				$pb['BACKGROUND-COLOR'] = $p['BACKGROUND-COLOR'];
			}
			if (isset($p['BOX-SHADOW'])) {
				$pb['BOX-SHADOW'] = $p['BOX-SHADOW'];
			}
			/* -- BACKGROUNDS -- */
			if (isset($p['BACKGROUND-IMAGE'])) {
				$pb['BACKGROUND-IMAGE'] = $p['BACKGROUND-IMAGE'];
			}
			if (isset($p['BACKGROUND-IMAGE-RESIZE'])) {
				$pb['BACKGROUND-IMAGE-RESIZE'] = $p['BACKGROUND-IMAGE-RESIZE'];
			}
			if (isset($p['BACKGROUND-IMAGE-OPACITY'])) {
				$pb['BACKGROUND-IMAGE-OPACITY'] = $p['BACKGROUND-IMAGE-OPACITY'];
			}
			if (isset($p['BACKGROUND-REPEAT'])) {
				$pb['BACKGROUND-REPEAT'] = $p['BACKGROUND-REPEAT'];
			}
			if (isset($p['BACKGROUND-POSITION'])) {
				$pb['BACKGROUND-POSITION'] = $p['BACKGROUND-POSITION'];
			}
			if (isset($p['BACKGROUND-GRADIENT'])) {
				$pb['BACKGROUND-GRADIENT'] = $p['BACKGROUND-GRADIENT'];
			}
			if (isset($p['BACKGROUND-SIZE'])) {
				$pb['BACKGROUND-SIZE'] = $p['BACKGROUND-SIZE'];
			}
			if (isset($p['BACKGROUND-ORIGIN'])) {
				$pb['BACKGROUND-ORIGIN'] = $p['BACKGROUND-ORIGIN'];
			}
			if (isset($p['BACKGROUND-CLIP'])) {
				$pb['BACKGROUND-CLIP'] = $p['BACKGROUND-CLIP'];
			}

			/* -- END BACKGROUNDS -- */

			$this->setCSS($pb, 'BLOCK', $tag);

			// ================================================================
			$bbox_br = $this->blk[1]['border_right']['w'];
			$bbox_bl = $this->blk[1]['border_left']['w'];
			$bbox_bt = $this->blk[1]['border_top']['w'];
			$bbox_bb = $this->blk[1]['border_bottom']['w'];
			$bbox_pr = $this->blk[1]['padding_right'];
			$bbox_pl = $this->blk[1]['padding_left'];
			$bbox_pt = $this->blk[1]['padding_top'];
			$bbox_pb = $this->blk[1]['padding_bottom'];
			$bbox_mr = $this->blk[1]['margin_right'];
			if (isset($p['MARGIN-RIGHT']) && strtolower($p['MARGIN-RIGHT']) == 'auto') {
				$bbox_mr = 'auto';
			}
			$bbox_ml = $this->blk[1]['margin_left'];
			if (isset($p['MARGIN-LEFT']) && strtolower($p['MARGIN-LEFT']) == 'auto') {
				$bbox_ml = 'auto';
			}
			$bbox_mt = $this->blk[1]['margin_top'];
			if (isset($p['MARGIN-TOP']) && strtolower($p['MARGIN-TOP']) == 'auto') {
				$bbox_mt = 'auto';
			}
			$bbox_mb = $this->blk[1]['margin_bottom'];
			if (isset($p['MARGIN-BOTTOM']) && strtolower($p['MARGIN-BOTTOM']) == 'auto') {
				$bbox_mb = 'auto';
			}
			if (isset($p['LEFT']) && strtolower($p['LEFT']) != 'auto') {
				$bbox_left = $this->sizeConverter->convert($p['LEFT'], $cont_w, $this->FontSize, false);
			} else {
				$bbox_left = 'auto';
			}
			if (isset($p['TOP']) && strtolower($p['TOP']) != 'auto') {
				$bbox_top = $this->sizeConverter->convert($p['TOP'], $cont_h, $this->FontSize, false);
			} else {
				$bbox_top = 'auto';
			}
			if (isset($p['RIGHT']) && strtolower($p['RIGHT']) != 'auto') {
				$bbox_right = $this->sizeConverter->convert($p['RIGHT'], $cont_w, $this->FontSize, false);
			} else {
				$bbox_right = 'auto';
			}
			if (isset($p['BOTTOM']) && strtolower($p['BOTTOM']) != 'auto') {
				$bbox_bottom = $this->sizeConverter->convert($p['BOTTOM'], $cont_h, $this->FontSize, false);
			} else {
				$bbox_bottom = 'auto';
			}
			if (isset($p['WIDTH']) && strtolower($p['WIDTH']) != 'auto') {
				$inner_w = $this->sizeConverter->convert($p['WIDTH'], $cont_w, $this->FontSize, false);
			} else {
				$inner_w = 'auto';
			}
			if (isset($p['HEIGHT']) && strtolower($p['HEIGHT']) != 'auto') {
				$inner_h = $this->sizeConverter->convert($p['HEIGHT'], $cont_h, $this->FontSize, false);
			} else {
				$inner_h = 'auto';
			}

			// If bottom or right pos are set and not left / top - save this to adjust rotated block later
			if ($rotate == 90 || $rotate == -90) { // mPDF 6
				if ($bbox_left === 'auto' && $bbox_right !== 'auto') {
					$rot_rpos = $bbox_right;
				} else {
					$rot_rpos = false;
				}
				if ($bbox_top === 'auto' && $bbox_bottom !== 'auto') {
					$rot_bpos = $bbox_bottom;
				} else {
					$rot_bpos = false;
				}
			}

			// ================================================================
			if ($checkinnerhtml == '' && $inner_h === 'auto') {
				$inner_h = 0.0001;
			}
			if ($checkinnerhtml == '' && $inner_w === 'auto') {
				$inner_w = 2 * $this->GetCharWidth('W', false);
			}
			// ================================================================
			// Algorithm from CSS2.1  See http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-height
			// mPD 5.3.14
			// Special case (not CSS) if all not specified, centre vertically on page
			$bbox_top_orig = '';
			if ($bbox_top === 'auto' && $inner_h === 'auto' && $bbox_bottom === 'auto' && $bbox_mt === 'auto' && $bbox_mb === 'auto') {
				$bbox_top_orig = $bbox_top;
				if ($bbox_mt === 'auto') {
					$bbox_mt = 0;
				}
				if ($bbox_mb === 'auto') {
					$bbox_mb = 0;
				}
				$bbox_top = $orig_y0 - $bbox_mt - $cont_y;
				// solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
			} // mPD 5.3.14
			elseif ($bbox_top === 'auto' && $inner_h === 'auto' && $bbox_bottom === 'auto') {
				$bbox_top_orig = $bbox_top = $orig_y0 - $cont_y;
				if ($bbox_mt === 'auto') {
					$bbox_mt = 0;
				}
				if ($bbox_mb === 'auto') {
					$bbox_mb = 0;
				}
				// solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
			} elseif ($bbox_top !== 'auto' && $inner_h !== 'auto' && $bbox_bottom !== 'auto') {
				if ($bbox_mt === 'auto' && $bbox_mb === 'auto') {
					$x = $cont_h - $bbox_top - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_bottom;
					$bbox_mt = $bbox_mb = ($x / 2);
				} elseif ($bbox_mt === 'auto') {
					$bbox_mt = $cont_h - $bbox_top - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
				} elseif ($bbox_mb === 'auto') {
					$bbox_mb = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_bottom;
				} else {
					$bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
				}
			} else {
				if ($bbox_mt === 'auto') {
					$bbox_mt = 0;
				}
				if ($bbox_mb === 'auto') {
					$bbox_mb = 0;
				}
				if ($bbox_top === 'auto' && $inner_h === 'auto' && $bbox_bottom !== 'auto') {
					// solve for $bbox_top when content_h known - $inner_h=='auto' && $bbox_top =='auto'
				} elseif ($bbox_top === 'auto' && $bbox_bottom === 'auto' && $inner_h !== 'auto') {
					$bbox_top = $orig_y0 - $bbox_mt - $cont_y;
					$bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
				} elseif ($inner_h === 'auto' && $bbox_bottom === 'auto' && $bbox_top !== 'auto') {
					// solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto'
				} elseif ($bbox_top === 'auto' && $inner_h !== 'auto' && $bbox_bottom !== 'auto') {
					$bbox_top = $cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt - $bbox_bottom;
				} elseif ($inner_h === 'auto' && $bbox_top !== 'auto' && $bbox_bottom !== 'auto') {
					$inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mt - $bbox_bottom;
				} elseif ($bbox_bottom === 'auto' && $bbox_top !== 'auto' && $inner_h !== 'auto') {
					$bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt;
				}
			}

			// THEN DO SAME FOR WIDTH
			// http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width
			if ($bbox_left === 'auto' && $inner_w === 'auto' && $bbox_right === 'auto') {
				if ($bbox_ml === 'auto') {
					$bbox_ml = 0;
				}
				if ($bbox_mr === 'auto') {
					$bbox_mr = 0;
				}
				// IF containing element RTL, should set $bbox_right
				$bbox_left = $orig_x0 - $bbox_ml - $cont_x;
				// solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto'
			} elseif ($bbox_left !== 'auto' && $inner_w !== 'auto' && $bbox_right !== 'auto') {
				if ($bbox_ml === 'auto' && $bbox_mr === 'auto') {
					$x = $cont_w - $bbox_left - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_right;
					$bbox_ml = $bbox_mr = ($x / 2);
				} elseif ($bbox_ml === 'auto') {
					$bbox_ml = $cont_w - $bbox_left - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_mr - $bbox_right;
				} elseif ($bbox_mr === 'auto') {
					$bbox_mr = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_right;
				} else {
					$bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
				}
			} else {
				if ($bbox_ml === 'auto') {
					$bbox_ml = 0;
				}
				if ($bbox_mr === 'auto') {
					$bbox_mr = 0;
				}
				if ($bbox_left === 'auto' && $inner_w === 'auto' && $bbox_right !== 'auto') {
					// solve for $bbox_left when content_w known - $inner_w=='auto' && $bbox_left =='auto'
				} elseif ($bbox_left === 'auto' && $bbox_right === 'auto' && $inner_w !== 'auto') {
					// IF containing element RTL, should set $bbox_right
					$bbox_left = $orig_x0 - $bbox_ml - $cont_x;
					$bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
				} elseif ($inner_w === 'auto' && $bbox_right === 'auto' && $bbox_left !== 'auto') {
					// solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto'
				} elseif ($bbox_left === 'auto' && $inner_w !== 'auto' && $bbox_right !== 'auto') {
					$bbox_left = $cont_w - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
				} elseif ($inner_w === 'auto' && $bbox_left !== 'auto' && $bbox_right !== 'auto') {
					$inner_w = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
				} elseif ($bbox_right === 'auto' && $bbox_left !== 'auto' && $inner_w !== 'auto') {
					$bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
				}
			}

			// ================================================================
			// ================================================================
			/* -- BACKGROUNDS -- */
			if (isset($pb['BACKGROUND-IMAGE']) && $pb['BACKGROUND-IMAGE']) {
				$ret = $this->SetBackground($pb, $this->blk[1]['inner_width']);
				if ($ret) {
					$this->blk[1]['background-image'] = $ret;
				}
			}
			/* -- END BACKGROUNDS -- */

			$bbox_top_auto = $bbox_top === 'auto';
			$bbox_left_auto = $bbox_left === 'auto';
			$bbox_right_auto = $bbox_right === 'auto';
			$bbox_bottom_auto = $bbox_bottom === 'auto';

			$bbox_top = is_numeric($bbox_top) ? $bbox_top : 0;
			$bbox_left = is_numeric($bbox_left) ? $bbox_left : 0;
			$bbox_right = is_numeric($bbox_right) ? $bbox_right : 0;
			$bbox_bottom = is_numeric($bbox_bottom) ? $bbox_bottom : 0;

			$y = $cont_y + $bbox_top + $bbox_mt + $bbox_bt + $bbox_pt;
			$h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;

			$x = $cont_x + $bbox_left + $bbox_ml + $bbox_bl + $bbox_pl;
			$w = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $bbox_pr - $bbox_br - $bbox_mr - $bbox_right;

			// Set (temporary) values for x y w h to do first paint, if values are auto
			if ($inner_h === 'auto' && $bbox_top_auto) {
				$y = $cont_y + $bbox_mt + $bbox_bt + $bbox_pt;
				$h = $cont_h - ($bbox_bottom + $bbox_mt + $bbox_mb + $bbox_bt + $bbox_bb + $bbox_pt + $bbox_pb);
			} elseif ($inner_h === 'auto' && $bbox_bottom_auto) {
				$y = $cont_y + $bbox_top + $bbox_mt + $bbox_bt + $bbox_pt;
				$h = $cont_h - ($bbox_top + $bbox_mt + $bbox_mb + $bbox_bt + $bbox_bb + $bbox_pt + $bbox_pb);
			}
			if ($inner_w === 'auto' && $bbox_left_auto) {
				$x = $cont_x + $bbox_ml + $bbox_bl + $bbox_pl;
				$w = $cont_w - ($bbox_right + $bbox_ml + $bbox_mr + $bbox_bl + $bbox_br + $bbox_pl + $bbox_pr);
			} elseif ($inner_w === 'auto' && $bbox_right_auto) {
				$x = $cont_x + $bbox_left + $bbox_ml + $bbox_bl + $bbox_pl;
				$w = $cont_w - ($bbox_left + $bbox_ml + $bbox_mr + $bbox_bl + $bbox_br + $bbox_pl + $bbox_pr);
			}

			$bbox_y = $cont_y + $bbox_top + $bbox_mt;
			$bbox_x = $cont_x + $bbox_left + $bbox_ml;

			$saved_block1 = $this->blk[1];

			unset($p);
			unset($pb);

			// ================================================================
			if ($inner_w === 'auto') { // do a first write
				$this->lMargin = $x;
				$this->rMargin = $this->w - $w - $x;

				// SET POSITION & FONT VALUES
				$this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
				$this->pageoutput[$this->page] = [];
				$this->x = $x;
				$this->y = $y;
				$this->HTMLheaderPageLinks = [];
				$this->HTMLheaderPageAnnots = [];
				$this->HTMLheaderPageForms = [];
				$this->pageBackgrounds = [];
				$this->maxPosR = 0;
				$this->maxPosL = $this->w; // For RTL
				$this->WriteHTML($html, HTMLParserMode::HTML_HEADER_BUFFER);
				$inner_w = $this->maxPosR - $this->lMargin;
				if ($bbox_right_auto) {
					$bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml;
				} elseif ($bbox_left_auto) {
					$bbox_left = $cont_w - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right;
					$bbox_x = $cont_x + $bbox_left + $bbox_ml;
					$inner_x = $bbox_x + $bbox_bl + $bbox_pl;
					$x = $inner_x;
				}

				$w = $inner_w;
				$bbox_y = $cont_y + $bbox_top + $bbox_mt;
				$bbox_x = $cont_x + $bbox_left + $bbox_ml;
			}

			if ($inner_h === 'auto') { // do a first write

				$this->lMargin = $x;
				$this->rMargin = $this->w - $w - $x;

				// SET POSITION & FONT VALUES
				$this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
				$this->pageoutput[$this->page] = [];
				$this->x = $x;
				$this->y = $y;
				$this->HTMLheaderPageLinks = [];
				$this->HTMLheaderPageAnnots = [];
				$this->HTMLheaderPageForms = [];
				$this->pageBackgrounds = [];
				$this->WriteHTML($html, HTMLParserMode::HTML_HEADER_BUFFER);
				$inner_h = $this->y - $y;

				if ($overflow != 'hidden' && $overflow != 'visible') { // constrained
					if (($this->y + $bbox_pb + $bbox_bb) > ($cont_y + $cont_h)) {
						$adj = ($this->y + $bbox_pb + $bbox_bb) - ($cont_y + $cont_h);
						$inner_h -= $adj;
					}
				}
				if ($bbox_bottom_auto && $bbox_top_orig === 'auto') {
					$bbox_bottom = $bbox_top = ($cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb) / 2;
					if ($overflow != 'hidden' && $overflow != 'visible') { // constrained
						if ($bbox_top < 0) {
							$bbox_top = 0;
							$inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
						}
					}
					$bbox_y = $cont_y + $bbox_top + $bbox_mt;
					$inner_y = $bbox_y + $bbox_bt + $bbox_pt;
					$y = $inner_y;
				} elseif ($bbox_bottom_auto) {
					$bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb;
				} elseif ($bbox_top_auto) {
					$bbox_top = $cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
					if ($overflow != 'hidden' && $overflow != 'visible') { // constrained
						if ($bbox_top < 0) {
							$bbox_top = 0;
							$inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom;
						}
					}
					$bbox_y = $cont_y + $bbox_top + $bbox_mt;
					$inner_y = $bbox_y + $bbox_bt + $bbox_pt;
					$y = $inner_y;
				}
				$h = $inner_h;
				$bbox_y = $cont_y + $bbox_top + $bbox_mt;
				$bbox_x = $cont_x + $bbox_left + $bbox_ml;
			}

			$inner_w = $w;
			$inner_h = $h;
		}

		$this->lMargin = $x;
		$this->rMargin = $this->w - $w - $x;

		// SET POSITION & FONT VALUES
		$this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
		$this->pageoutput[$this->page] = [];

		$this->x = $x;
		$this->y = $y;

		$this->HTMLheaderPageLinks = [];
		$this->HTMLheaderPageAnnots = [];
		$this->HTMLheaderPageForms = [];

		$this->pageBackgrounds = [];

		$this->WriteHTML($html, HTMLParserMode::HTML_HEADER_BUFFER);

		$actual_h = $this->y - $y;
		$use_w = $w;
		$use_h = $h;
		$ratio = $actual_h / $use_w;

		if ($overflow != 'hidden' && $overflow != 'visible') {
			$target = $h / $w;
			if ($target > 0) {
				if (($ratio / $target) > 1) {
					$nl = ceil($actual_h / $this->lineheight);
					$l = $use_w * $nl;
					$est_w = sqrt(($l * $this->lineheight) / $target) * 0.8;
					$use_w += ($est_w - $use_w) - ($w / 100);
				}
				$bpcstart = ($ratio / $target);
				$bpcctr = 1;

				while (($ratio / $target) > 1) {
					// @log 'Auto-sizing fixed-position block $bpcctr++

					$this->x = $x;
					$this->y = $y;

					if (($ratio / $target) > 1.5 || ($ratio / $target) < 0.6) {
						$use_w += ($w / $this->incrementFPR1);
					} elseif (($ratio / $target) > 1.2 || ($ratio / $target) < 0.85) {
						$use_w += ($w / $this->incrementFPR2);
					} elseif (($ratio / $target) > 1.1 || ($ratio / $target) < 0.91) {
						$use_w += ($w / $this->incrementFPR3);
					} else {
						$use_w += ($w / $this->incrementFPR4);
					}

					$use_h = $use_w * $target;
					$this->rMargin = $this->w - $use_w - $x;
					$this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
					$this->HTMLheaderPageLinks = [];
					$this->HTMLheaderPageAnnots = [];
					$this->HTMLheaderPageForms = [];
					$this->pageBackgrounds = [];
					$this->WriteHTML($html, HTMLParserMode::HTML_HEADER_BUFFER);
					$actual_h = $this->y - $y;
					$ratio = $actual_h / $use_w;
				}
			}
		}

		$shrink_f = $w / $use_w;

		// ================================================================

		$this->pages[$this->page] .= '___BEFORE_BORDERS___';
		$block_s = $this->PrintPageBackgrounds(); // Save to print later inside clipping path
		$this->pageBackgrounds = [];

		// ================================================================

		if ($rotate == 90 || $rotate == -90) { // mPDF 6
			$prerotw = $bbox_bl + $bbox_pl + $inner_w + $bbox_pr + $bbox_br;
			$preroth = $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb;
			$rot_start = " q\n";
			if ($rotate == 90) {
				if ($rot_rpos !== false) {
					$adjw = $prerotw;
				} // width before rotation
				else {
					$adjw = $preroth;
				} // height before rotation
				if ($rot_bpos !== false) {
					$adjh = -$prerotw + $preroth;
				} else {
					$adjh = 0;
				}
			} else {
				if ($rot_rpos !== false) {
					$adjw = $prerotw - $preroth;
				} else {
					$adjw = 0;
				}
				if ($rot_bpos !== false) {
					$adjh = $preroth;
				} // height before rotation
				else {
					$adjh = $prerotw;
				} // width before rotation
			}
			$rot_start .= $this->transformTranslate($adjw, $adjh, true) . "\n";
			$rot_start .= $this->transformRotate($rotate, $bbox_x, $bbox_y, true) . "\n";
			$rot_end = " Q\n";
		} elseif ($rotate == 180) { // mPDF 6
			$rot_start = " q\n";
			$rot_start .= $this->transformTranslate($bbox_bl + $bbox_pl + $inner_w + $bbox_pr + $bbox_br, $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb, true) . "\n";
			$rot_start .= $this->transformRotate(180, $bbox_x, $bbox_y, true) . "\n";
			$rot_end = " Q\n";
		} else {
			$rot_start = '';
			$rot_end = '';
		}

		// ================================================================
		if (!empty($bounding)) {
			// WHEN HEIGHT // BOTTOM EDGE IS KNOWN and $this->y is set to the bottom
			// Re-instate saved $this->blk[1]
			$this->blk[1] = $saved_block1;

			// These are only needed when painting border/background
			$this->blk[1]['width'] = $bbox_w = $cont_w - $bbox_left - $bbox_ml - $bbox_mr - $bbox_right;
			$this->blk[1]['x0'] = $bbox_x;
			$this->blk[1]['y0'] = $bbox_y;
			$this->blk[1]['startpage'] = $this->page;
			$this->blk[1]['y1'] = $bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb;
			$this->writer->write($rot_start);
			$this->PaintDivBB('', 0, 1); // Prints borders and sets backgrounds in $this->pageBackgrounds
			$this->writer->write($rot_end);
		}

		$s = $this->PrintPageBackgrounds();
		$s = $rot_start . $s . $rot_end;
		$this->pages[$this->page] = preg_replace('/___BEFORE_BORDERS___/', "\n" . $s . "\n", $this->pages[$this->page]);
		$this->pageBackgrounds = [];

		$this->writer->write($rot_start);

		// Clipping Output
		if ($overflow == 'hidden') {
			// Bounding rectangle to clip
			$clip_y1 = $this->y;
			if (!empty($bounding) && ($this->y + $bbox_pb + $bbox_bb) > ($bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb )) {
				$clip_y1 = ($bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb ) - ($bbox_pb + $bbox_bb);
			}
			// $op = 'W* n';	// Clipping
			$op = 'W n'; // Clipping alternative mode
			$this->writer->write("q");
			$ch = $clip_y1 - $y;
			$this->writer->write(sprintf('%.3F %.3F %.3F %.3F re %s', $x * Mpdf::SCALE, ($this->h - $y) * Mpdf::SCALE, $w * Mpdf::SCALE, -$ch * Mpdf::SCALE, $op));
			if (!empty($block_s)) {
				$tmp = "q\n" . sprintf('%.3F %.3F %.3F %.3F re %s', $x * Mpdf::SCALE, ($this->h - $y) * Mpdf::SCALE, $w * Mpdf::SCALE, -$ch * Mpdf::SCALE, $op);
				$tmp .= "\n" . $block_s . "\nQ";
				$block_s = $tmp;
			}
		}


		if (!empty($block_s)) {
			if ($shrink_f != 1) { // i.e. autofit has resized the box
				$tmp = "q\n" . $this->transformScale(($shrink_f * 100), ($shrink_f * 100), $x, $y, true);
				$tmp .= "\n" . $block_s . "\nQ";
				$block_s = $tmp;
			}
			$this->writer->write($block_s);
		}



		if ($shrink_f != 1) { // i.e. autofit has resized the box
			$this->StartTransform();
			$this->transformScale(($shrink_f * 100), ($shrink_f * 100), $x, $y);
		}

		$this->writer->write($this->headerbuffer);

		if ($shrink_f != 1) { // i.e. autofit has resized the box
			$this->StopTransform();
		}

		if ($overflow == 'hidden') {
			// End clipping
			$this->writer->write("Q");
		}

		$this->writer->write($rot_end);


		// Page Links
		foreach ($this->HTMLheaderPageLinks as $lk) {
			if ($rotate) {
				$tmp = $lk[2]; // Switch h - w
				$lk[2] = $lk[3];
				$lk[3] = $tmp;

				$lx1 = (($lk[0] / Mpdf::SCALE));
				$ly1 = (($this->h - ($lk[1] / Mpdf::SCALE)));
				if ($rotate == 90) {
					$adjx = -($lx1 - $bbox_x) + ($preroth - ($ly1 - $bbox_y));
					$adjy = -($ly1 - $bbox_y) + ($lx1 - $bbox_x);
					$lk[2] = -$lk[2];
				} elseif ($rotate == -90) {
					$adjx = -($lx1 - $bbox_x) + ($ly1 - $bbox_y);
					$adjy = -($ly1 - $bbox_y) - ($lx1 - $bbox_x) + $prerotw;
					$lk[3] = -$lk[3];
				}
				if ($rot_rpos !== false) {
					$adjx += $prerotw - $preroth;
				}
				if ($rot_bpos !== false) {
					$adjy += $preroth - $prerotw;
				}
				$lx1 += $adjx;
				$ly1 += $adjy;

				$lk[0] = $lx1 * Mpdf::SCALE;
				$lk[1] = ($this->h - $ly1) * Mpdf::SCALE;
			}
			if ($shrink_f != 1) {  // i.e. autofit has resized the box
				$lx1 = (($lk[0] / Mpdf::SCALE) - $x);
				$lx2 = $x + ($lx1 * $shrink_f);
				$lk[0] = $lx2 * Mpdf::SCALE;
				$ly1 = (($this->h - ($lk[1] / Mpdf::SCALE)) - $y);
				$ly2 = $y + ($ly1 * $shrink_f);
				$lk[1] = ($this->h - $ly2) * Mpdf::SCALE;
				$lk[2] *= $shrink_f; // width
				$lk[3] *= $shrink_f; // height
			}
			$this->PageLinks[$this->page][] = $lk;
		}

		foreach ($this->HTMLheaderPageForms as $n => $f) {
			if ($shrink_f != 1) {  // i.e. autofit has resized the box
				$f['x'] = $x + (($f['x'] - $x) * $shrink_f);
				$f['y'] = $y + (($f['y'] - $y) * $shrink_f);
				$f['w'] *= $shrink_f;
				$f['h'] *= $shrink_f;
				$f['style']['fontsize'] *= $shrink_f;
			}
			$this->form->forms[$f['n']] = $f;
		}
		// Page Annotations
		foreach ($this->HTMLheaderPageAnnots as $lk) {
			if ($rotate) {
				if ($rotate == 90) {
					$adjx = -($lk['x'] - $bbox_x) + ($preroth - ($lk['y'] - $bbox_y));
					$adjy = -($lk['y'] - $bbox_y) + ($lk['x'] - $bbox_x);
				} elseif ($rotate == -90) {
					$adjx = -($lk['x'] - $bbox_x) + ($lk['y'] - $bbox_y);
					$adjy = -($lk['y'] - $bbox_y) - ($lk['x'] - $bbox_x) + $prerotw;
				}
				if ($rot_rpos !== false) {
					$adjx += $prerotw - $preroth;
				}
				if ($rot_bpos !== false) {
					$adjy += $preroth - $prerotw;
				}
				$lk['x'] += $adjx;
				$lk['y'] += $adjy;
			}
			if ($shrink_f != 1) {  // i.e. autofit has resized the box
				$lk['x'] = $x + (($lk['x'] - $x) * $shrink_f);
				$lk['y'] = $y + (($lk['y'] - $y) * $shrink_f);
			}
			$this->PageAnnots[$this->page][] = $lk;
		}

		// Restore
		$this->headerbuffer = '';
		$this->HTMLheaderPageLinks = [];
		$this->HTMLheaderPageAnnots = [];
		$this->HTMLheaderPageForms = [];
		$this->pageBackgrounds = $save_bgs;
		$this->writingHTMLheader = false;

		$this->writingHTMLfooter = false;
		$this->fullImageHeight = false;
		$this->ResetMargins();
		$this->pgwidth = $this->w - $this->lMargin - $this->rMargin;
		$this->SetXY($save_x, $save_y);
		$this->title2annots = $save_annots; // *ANNOTATIONS*
		$this->InFooter = false; // turns back on autopagebreaks
		$this->pageoutput[$this->page] = [];
		$this->pageoutput[$this->page]['Font'] = '';
		/* -- COLUMNS -- */
		if ($save_cols) {
			$this->SetColumns($save_nbcol, $this->colvAlign, $this->ColGap);
		}
		/* -- END COLUMNS -- */
	}
353922
function _setInlineBlockHeights(&$lineBox, &$stackHeight, &$content, &$font, $is_table)
	{
		if ($this->shrin_k > 1) {
			$shrin_k = $this->shrin_k;
		} else {
			$shrin_k = 1;
		}

		$ypos = [];
		$bordypos = [];
		$bgypos = [];

		if ($is_table) {
			// FOR TABLE
			$fontsize = $this->FontSize;
			$fontkey = $this->FontFamily . $this->FontStyle;
			$fontdesc = $this->fonts[$fontkey]['desc'];
			$CSSlineheight = $this->cellLineHeight;
			$line_stacking_strategy = $this->cellLineStackingStrategy; // inline-line-height [default] | block-line-height | max-height | grid-height
			$line_stacking_shift = $this->cellLineStackingShift;  // consider-shifts [default] | disregard-shifts
		} else {
			// FOR BLOCK FONT
			$fontsize = $this->blk[$this->blklvl]['InlineProperties']['size'];
			$fontkey = $this->blk[$this->blklvl]['InlineProperties']['family'] . $this->blk[$this->blklvl]['InlineProperties']['style'];
			$fontdesc = $this->fonts[$fontkey]['desc'];
			$CSSlineheight = $this->blk[$this->blklvl]['line_height'];
			// inline-line-height | block-line-height | max-height | grid-height
			$line_stacking_strategy = (isset($this->blk[$this->blklvl]['line_stacking_strategy']) ? $this->blk[$this->blklvl]['line_stacking_strategy'] : 'inline-line-height');
			// consider-shifts | disregard-shifts
			$line_stacking_shift = (isset($this->blk[$this->blklvl]['line_stacking_shift']) ? $this->blk[$this->blklvl]['line_stacking_shift'] : 'consider-shifts');
		}
		$boxLineHeight = $this->_computeLineheight($CSSlineheight, $fontsize);


		// First, set a "strut" using block font at index $lineBox[-1]
		$ypos[-1] = $this->_setLineYpos($fontsize, $fontdesc, $CSSlineheight);

		// for the block element - always taking the block EXTENDED progression including leading - which may be negative
		if ($line_stacking_strategy == 'block-line-height') {
			$topy = $ypos[-1]['exttop'];
			$bottomy = $ypos[-1]['extbottom'];
		} else {
			$topy = 0;
			$bottomy = 0;
		}

		// Get text-middle for aligning images/objects
		$midpoint = $ypos[-1]['boxtop'] - (($ypos[-1]['boxtop'] - $ypos[-1]['boxbottom']) / 2);

		// for images / inline objects / replaced elements
		$mta = 0; // Maximum top-aligned
		$mba = 0; // Maximum bottom-aligned
		foreach ($content as $k => $chunk) {
			if (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]['type'] == 'listmarker') {
				$ypos[$k] = $ypos[-1];
				// UPDATE Maximums
				if ($line_stacking_strategy == 'block-line-height' || $line_stacking_strategy == 'grid-height' || $line_stacking_strategy == 'max-height') { // don't include extended block progression of all inline elements
					if ($ypos[$k]['boxtop'] > $topy) {
						$topy = $ypos[$k]['boxtop'];
					}
					if ($ypos[$k]['boxbottom'] < $bottomy) {
						$bottomy = $ypos[$k]['boxbottom'];
					}
				} else {
					if ($ypos[$k]['exttop'] > $topy) {
						$topy = $ypos[$k]['exttop'];
					}
					if ($ypos[$k]['extbottom'] < $bottomy) {
						$bottomy = $ypos[$k]['extbottom'];
					}
				}
			} elseif (isset($this->objectbuffer[$k]) && $this->objectbuffer[$k]['type'] == 'dottab') { // mPDF 6 DOTTAB
				$fontsize = $font[$k]['size'];
				$fontdesc = $font[$k]['curr']['desc'];
				$lh = 1;
				$ypos[$k] = $this->_setLineYpos($fontsize, $fontdesc, $lh, $ypos[-1]); // Lineheight=1 fixed
			} elseif (isset($this->objectbuffer[$k])) {
				$oh = $this->objectbuffer[$k]['OUTER-HEIGHT'];
				$va = $this->objectbuffer[$k]['vertical-align'];

				if ($va == 'BS') { //  (BASELINE default)
					if ($oh > $topy) {
						$topy = $oh;
					}
				} elseif ($va == 'M') {
					if (($midpoint + $oh / 2) > $topy) {
						$topy = $midpoint + $oh / 2;
					}
					if (($midpoint - $oh / 2) < $bottomy) {
						$bottomy = $midpoint - $oh / 2;
					}
				} elseif ($va == 'TT') {
					if (($ypos[-1]['boxtop'] - $oh) < $bottomy) {
						$bottomy = $ypos[-1]['boxtop'] - $oh;
						$topy = max($topy, $ypos[-1]['boxtop']);
					}
				} elseif ($va == 'TB') {
					if (($ypos[-1]['boxbottom'] + $oh) > $topy) {
						$topy = $ypos[-1]['boxbottom'] + $oh;
						$bottomy = min($bottomy, $ypos[-1]['boxbottom']);
					}
				} elseif ($va == 'T') {
					if ($oh > $mta) {
						$mta = $oh;
					}
				} elseif ($va == 'B') {
					if ($oh > $mba) {
						$mba = $oh;
					}
				}
			} elseif ($content[$k] || $content[$k] === '0') {
				// FOR FLOWING BLOCK
				$fontsize = $font[$k]['size'];
				$fontdesc = $font[$k]['curr']['desc'];
				// In future could set CSS line-height from inline elements; for now, use block level:
				$ypos[$k] = $this->_setLineYpos($fontsize, $fontdesc, $CSSlineheight, $ypos[-1]);

				if (isset($font[$k]['textparam']['text-baseline']) && $font[$k]['textparam']['text-baseline'] != 0) {
					$ypos[$k]['baseline-shift'] = $font[$k]['textparam']['text-baseline'];
				}

				// DO ALIGNMENT FOR BASELINES *******************
				// Until most fonts have OpenType BASE tables, this won't work
				// $ypos[$k] compared to $ypos[-1] or $ypos[$k-1] using $dominant_baseline and $baseline_table
				// UPDATE Maximums
				if ($line_stacking_strategy == 'block-line-height' || $line_stacking_strategy == 'grid-height' || $line_stacking_strategy == 'max-height') { // don't include extended block progression of all inline elements
					if ($line_stacking_shift == 'disregard-shifts') {
						if ($ypos[$k]['boxtop'] > $topy) {
							$topy = $ypos[$k]['boxtop'];
						}
						if ($ypos[$k]['boxbottom'] < $bottomy) {
							$bottomy = $ypos[$k]['boxbottom'];
						}
					} else {
						if (($ypos[$k]['boxtop'] + $ypos[$k]['baseline-shift']) > $topy) {
							$topy = $ypos[$k]['boxtop'] + $ypos[$k]['baseline-shift'];
						}
						if (($ypos[$k]['boxbottom'] + $ypos[$k]['baseline-shift']) < $bottomy) {
							$bottomy = $ypos[$k]['boxbottom'] + $ypos[$k]['baseline-shift'];
						}
					}
				} else {
					if ($line_stacking_shift == 'disregard-shifts') {
						if ($ypos[$k]['exttop'] > $topy) {
							$topy = $ypos[$k]['exttop'];
						}
						if ($ypos[$k]['extbottom'] < $bottomy) {
							$bottomy = $ypos[$k]['extbottom'];
						}
					} else {
						if (($ypos[$k]['exttop'] + $ypos[$k]['baseline-shift']) > $topy) {
							$topy = $ypos[$k]['exttop'] + $ypos[$k]['baseline-shift'];
						}
						if (($ypos[$k]['extbottom'] + $ypos[$k]['baseline-shift']) < $bottomy) {
							$bottomy = $ypos[$k]['extbottom'] + $ypos[$k]['baseline-shift'];
						}
					}
				}

				// If BORDER set on inline element
				if (isset($font[$k]['bord']) && $font[$k]['bord']) {
					$bordfontsize = $font[$k]['textparam']['bord-decoration']['fontsize'] / $shrin_k;
					$bordfontkey = $font[$k]['textparam']['bord-decoration']['fontkey'];
					if ($bordfontkey != $fontkey || $bordfontsize != $fontsize || isset($font[$k]['textparam']['bord-decoration']['baseline'])) {
						$bordfontdesc = $this->fonts[$bordfontkey]['desc'];
						$bordypos[$k] = $this->_setLineYpos($bordfontsize, $bordfontdesc, $CSSlineheight, $ypos[-1]);
						if (isset($font[$k]['textparam']['bord-decoration']['baseline']) && $font[$k]['textparam']['bord-decoration']['baseline'] != 0) {
							$bordypos[$k]['baseline-shift'] = $font[$k]['textparam']['bord-decoration']['baseline'] / $shrin_k;
						}
					}
				}
				// If BACKGROUND set on inline element
				if (isset($font[$k]['spanbgcolor']) && $font[$k]['spanbgcolor']) {
					$bgfontsize = $font[$k]['textparam']['bg-decoration']['fontsize'] / $shrin_k;
					$bgfontkey = $font[$k]['textparam']['bg-decoration']['fontkey'];
					if ($bgfontkey != $fontkey || $bgfontsize != $fontsize || isset($font[$k]['textparam']['bg-decoration']['baseline'])) {
						$bgfontdesc = $this->fonts[$bgfontkey]['desc'];
						$bgypos[$k] = $this->_setLineYpos($bgfontsize, $bgfontdesc, $CSSlineheight, $ypos[-1]);
						if (isset($font[$k]['textparam']['bg-decoration']['baseline']) && $font[$k]['textparam']['bg-decoration']['baseline'] != 0) {
							$bgypos[$k]['baseline-shift'] = $font[$k]['textparam']['bg-decoration']['baseline'] / $shrin_k;
						}
					}
				}
			}
		}


		// TOP or BOTTOM aligned images
		if ($mta > ($topy - $bottomy)) {
			if (($topy - $mta) < $bottomy) {
				$bottomy = $topy - $mta;
			}
		}
		if ($mba > ($topy - $bottomy)) {
			if (($bottomy + $mba) > $topy) {
				$topy = $bottomy + $mba;
			}
		}

		if ($line_stacking_strategy == 'block-line-height') { // fixed height set by block element (whether present or not)
			$topy = $ypos[-1]['exttop'];
			$bottomy = $ypos[-1]['extbottom'];
		}

		$inclusiveHeight = $topy - $bottomy;

		// SET $stackHeight taking note of line_stacking_strategy
		// NB inclusive height already takes account of need to consider block progression height (excludes leading set by lineheight)
		// or extended block progression height (includes leading set by lineheight)
		if ($line_stacking_strategy == 'block-line-height') { // fixed = extended block progression height of block element
			$stackHeight = $boxLineHeight;
		} elseif ($line_stacking_strategy == 'max-height') { // smallest height which includes extended block progression height of block element
			// and block progression heights of inline elements (NOT extended)
			$stackHeight = $inclusiveHeight;
		} elseif ($line_stacking_strategy == 'grid-height') { // smallest multiple of block element lineheight to include
			// block progression heights of inline elements (NOT extended)
			$stackHeight = $boxLineHeight;
			while ($stackHeight < $inclusiveHeight) {
				$stackHeight += $boxLineHeight;
			}
		} else { // 'inline-line-height' = default		// smallest height which includes extended block progression height of block element
			// AND extended block progression heights of inline elements
			$stackHeight = $inclusiveHeight;
		}

		$diff = $stackHeight - $inclusiveHeight;
		$topy += $diff / 2;
		$bottomy -= $diff / 2;

		// ADJUST $ypos => lineBox using $stackHeight; lineBox are all offsets from the top of stackHeight in mm
		// and SET IMAGE OFFSETS
		$lineBox[-1]['boxtop'] = $topy - $ypos[-1]['boxtop'];
		$lineBox[-1]['boxbottom'] = $topy - $ypos[-1]['boxbottom'];
		// $lineBox[-1]['exttop'] = $topy - $ypos[-1]['exttop'];
		// $lineBox[-1]['extbottom'] = $topy - $ypos[-1]['extbottom'];
		$lineBox[-1]['glyphYorigin'] = $topy - $ypos[-1]['glyphYorigin'];
		$lineBox[-1]['baseline-shift'] = $ypos[-1]['baseline-shift'];

		$midpoint = $lineBox[-1]['boxbottom'] - (($lineBox[-1]['boxbottom'] - $lineBox[-1]['boxtop']) / 2);

		foreach ($content as $k => $chunk) {
			if (isset($this->objectbuffer[$k])) {
				$oh = $this->objectbuffer[$k]['OUTER-HEIGHT'];
				// LIST MARKERS
				if ($this->objectbuffer[$k]['type'] == 'listmarker') {
					$oh = $fontsize;
				} elseif ($this->objectbuffer[$k]['type'] == 'dottab') { // mPDF 6 DOTTAB
					$oh = $font[$k]['size']; // == $this->objectbuffer[$k]['fontsize']/Mpdf::SCALE;
					$lineBox[$k]['boxtop'] = $topy - $ypos[$k]['boxtop'];
					$lineBox[$k]['boxbottom'] = $topy - $ypos[$k]['boxbottom'];
					$lineBox[$k]['glyphYorigin'] = $topy - $ypos[$k]['glyphYorigin'];
					$lineBox[$k]['baseline-shift'] = 0;
					// continue;
				}
				$va = $this->objectbuffer[$k]['vertical-align']; // = $objattr['vertical-align'] = set as M,T,B,S

				if ($va == 'BS') { //  (BASELINE default)
					$lineBox[$k]['top'] = $lineBox[-1]['glyphYorigin'] - $oh;
				} elseif ($va == 'M') {
					$lineBox[$k]['top'] = $midpoint - $oh / 2;
				} elseif ($va == 'TT') {
					$lineBox[$k]['top'] = $lineBox[-1]['boxtop'];
				} elseif ($va == 'TB') {
					$lineBox[$k]['top'] = $lineBox[-1]['boxbottom'] - $oh;
				} elseif ($va == 'T') {
					$lineBox[$k]['top'] = 0;
				} elseif ($va == 'B') {
					$lineBox[$k]['top'] = $stackHeight - $oh;
				}
			} elseif ($content[$k] || $content[$k] === '0') {
				$lineBox[$k]['boxtop'] = $topy - $ypos[$k]['boxtop'];
				$lineBox[$k]['boxbottom'] = $topy - $ypos[$k]['boxbottom'];
				// $lineBox[$k]['exttop'] = $topy - $ypos[$k]['exttop'];
				// $lineBox[$k]['extbottom'] = $topy - $ypos[$k]['extbottom'];
				$lineBox[$k]['glyphYorigin'] = $topy - $ypos[$k]['glyphYorigin'];
				$lineBox[$k]['baseline-shift'] = $ypos[$k]['baseline-shift'];
				if (isset($bordypos[$k]['boxtop'])) {
					$lineBox[$k]['border-boxtop'] = $topy - $bordypos[$k]['boxtop'];
					$lineBox[$k]['border-boxbottom'] = $topy - $bordypos[$k]['boxbottom'];
					$lineBox[$k]['border-baseline-shift'] = $bordypos[$k]['baseline-shift'];
				}
				if (isset($bgypos[$k]['boxtop'])) {
					$lineBox[$k]['background-boxtop'] = $topy - $bgypos[$k]['boxtop'];
					$lineBox[$k]['background-boxbottom'] = $topy - $bgypos[$k]['boxbottom'];
					$lineBox[$k]['background-baseline-shift'] = $bgypos[$k]['baseline-shift'];
				}
			}
		}
	}
223454
function _enddoc()
	{
		// @log Writing Headers & Footers

		$this->_puthtmlheaders();

		// @log Writing Pages

		// Remove references to unused fonts (usually default font)
		foreach ($this->fonts as $fk => $font) {
			if (isset($font['type']) && $font['type'] == 'TTF' && !$font['used']) {
				if ($font['sip'] || $font['smp']) {
					foreach ($font['subsetfontids'] as $k => $fid) {
						foreach ($this->pages as $pn => $page) {
							$this->pages[$pn] = preg_replace('/\s\/F' . $fid . ' \d[\d.]* Tf\s/is', ' ', $this->pages[$pn]);
						}
					}
				} else {
					foreach ($this->pages as $pn => $page) {
						$this->pages[$pn] = preg_replace('/\s\/F' . $font['i'] . ' \d[\d.]* Tf\s/is', ' ', $this->pages[$pn]);
					}
				}
			}
		}

		if (count($this->layers)) {
			foreach ($this->pages as $pn => $page) {
				preg_match_all('/\/OCZ-index \/ZI(\d+) BDC(.*?)(EMCZ)-index/is', $this->pages[$pn], $m1);
				preg_match_all('/\/OCBZ-index \/ZI(\d+) BDC(.*?)(EMCBZ)-index/is', $this->pages[$pn], $m2);
				preg_match_all('/\/OCGZ-index \/ZI(\d+) BDC(.*?)(EMCGZ)-index/is', $this->pages[$pn], $m3);
				$m = [];
				for ($i = 0; $i < 4; $i++) {
					$m[$i] = array_merge($m1[$i], $m2[$i], $m3[$i]);
				}
				if (count($m[0])) {
					$sortarr = [];
					for ($i = 0; $i < count($m[0]); $i++) {
						$key = $m[1][$i] * 2;
						if ($m[3][$i] == 'EMCZ') {
							$key +=2; // background first then gradient then normal
						} elseif ($m[3][$i] == 'EMCGZ') {
							$key +=1;
						}
						$sortarr[$i] = $key;
					}
					asort($sortarr);
					foreach ($sortarr as $i => $k) {
						$this->pages[$pn] = str_replace($m[0][$i], '', $this->pages[$pn]);
						$this->pages[$pn] .= "\n" . $m[0][$i] . "\n";
					}
					$this->pages[$pn] = preg_replace('/\/OC[BG]{0,1}Z-index \/ZI(\d+) BDC/is', '/OC /ZI\\1 BDC ', $this->pages[$pn]);
					$this->pages[$pn] = preg_replace('/EMC[BG]{0,1}Z-index/is', 'EMC', $this->pages[$pn]);
				}
			}
		}

		$this->pageWriter->writePages();

		// @log Writing document resources

		$this->resourceWriter->writeResources();

		// Info
		$this->writer->object();
		$this->InfoRoot = $this->n;
		$this->writer->write('<<');

		// @log Writing document info
		$this->metadataWriter->writeInfo();

		$this->writer->write('>>');
		$this->writer->write('endobj');

		// METADATA
		if ($this->PDFA || $this->PDFX) {
			$this->metadataWriter->writeMetadata();
		}

		// OUTPUTINTENT
		if ($this->PDFA || $this->PDFX || $this->ICCProfile) {
			$this->metadataWriter->writeOutputIntent();
		}

		// Associated files
		if ($this->associatedFiles) {
			$this->metadataWriter->writeAssociatedFiles();
		}

		// Catalog
		$this->writer->object();
		$this->writer->write('<<');

		// @log Writing document catalog

		$this->metadataWriter->writeCatalog();

		$this->writer->write('>>');
		$this->writer->write('endobj');

		// Cross-ref
		$o = strlen($this->buffer);
		$this->writer->write('xref');
		$this->writer->write('0 ' . ($this->n + 1));
		$this->writer->write('0000000000 65535 f ');

		for ($i = 1; $i <= $this->n; $i++) {
			$this->writer->write(sprintf('%010d 00000 n ', $this->offsets[$i]));
		}

		// Trailer
		$this->writer->write('trailer');
		$this->writer->write('<<');

		$this->metadataWriter->writeTrailer();

		$this->writer->write('>>');
		$this->writer->write('startxref');
		$this->writer->write($o);

		$this->buffer .= '%%EOF';
		$this->state = 3;
	}
1284170
protected function _text_align()
    {
        $style = $this->_frame->get_style();
        $w = $this->_frame->get_containing_block("w");
        $width = (float)$style->length_in_pt($style->width, $w);

        switch ($style->text_align) {
            default:
            case "left":
                foreach ($this->_frame->get_line_boxes() as $line) {
                    if (!$line->left) {
                        continue;
                    }

                    foreach ($line->get_frames() as $frame) {
                        if ($frame instanceof BlockFrameDecorator) {
                            continue;
                        }
                        $frame->set_position($frame->get_position("x") + $line->left);
                    }
                }
                return;

            case "right":
                foreach ($this->_frame->get_line_boxes() as $line) {
                    // Move each child over by $dx
                    $dx = $width - $line->w - $line->right;

                    foreach ($line->get_frames() as $frame) {
                        // Block frames are not aligned by text-align
                        if ($frame instanceof BlockFrameDecorator) {
                            continue;
                        }

                        $frame->set_position($frame->get_position("x") + $dx);
                    }
                }
                break;

            case "justify":
                // We justify all lines except the last one
                $lines = $this->_frame->get_line_boxes(); // needs to be a variable (strict standards)
                $last_line = array_pop($lines);

                foreach ($lines as $i => $line) {
                    if ($line->br) {
                        unset($lines[$i]);
                    }
                }

                // One space character's width. Will be used to get a more accurate spacing
                $space_width = $this->get_dompdf()->getFontMetrics()->getTextWidth(" ", $style->font_family, $style->font_size);

                foreach ($lines as $line) {
                    if ($line->left) {
                        foreach ($line->get_frames() as $frame) {
                            if (!$frame instanceof TextFrameDecorator) {
                                continue;
                            }

                            $frame->set_position($frame->get_position("x") + $line->left);
                        }
                    }

                    // Set the spacing for each child
                    if ($line->wc > 1) {
                        $spacing = ($width - ($line->left + $line->w + $line->right) + $space_width) / ($line->wc - 1);
                    } else {
                        $spacing = 0;
                    }

                    $dx = 0;
                    foreach ($line->get_frames() as $frame) {
                        if (!$frame instanceof TextFrameDecorator) {
                            continue;
                        }

                        $text = $frame->get_text();
                        $spaces = mb_substr_count($text, " ");

                        $char_spacing = (float)$style->length_in_pt($style->letter_spacing);
                        $_spacing = $spacing + $char_spacing;

                        $frame->set_position($frame->get_position("x") + $dx);
                        $frame->set_text_spacing($_spacing);

                        $dx += $spaces * $_spacing;
                    }

                    // The line (should) now occupy the entire width
                    $line->w = $width;
                }

                // Adjust the last line if necessary
                if ($last_line->left) {
                    foreach ($last_line->get_frames() as $frame) {
                        if ($frame instanceof BlockFrameDecorator) {
                            continue;
                        }
                        $frame->set_position($frame->get_position("x") + $last_line->left);
                    }
                }
                break;

            case "center":
            case "centre":
                foreach ($this->_frame->get_line_boxes() as $line) {
                    // Centre each line by moving each frame in the line by:
                    $dx = ($width + $line->left - $line->w - $line->right) / 2;

                    foreach ($line->get_frames() as $frame) {
                        // Block frames are not aligned by text-align
                        if ($frame instanceof BlockFrameDecorator) {
                            continue;
                        }

                        $frame->set_position($frame->get_position("x") + $dx);
                    }
                }
                break;
        }
    }
197651
protected function _collapse_margins() {
    $frame = $this->_frame;
    $cb = $frame->get_containing_block();
    $style = $frame->get_style();
    
    if ( !$frame->is_in_flow() ) {
      return;
    }

    $t = $style->length_in_pt($style->margin_top, $cb["h"]);
    $b = $style->length_in_pt($style->margin_bottom, $cb["h"]);

    // Handle 'auto' values
    if ( $t === "auto" ) {
      $style->margin_top = "0pt";
      $t = 0;
    }

    if ( $b === "auto" ) {
      $style->margin_bottom = "0pt";
      $b = 0;
    }

    // Collapse vertical margins:
    $n = $frame->get_next_sibling();
    if ( $n && !$n->is_block() ) {
      while ( $n = $n->get_next_sibling() ) {
        if ( $n->is_block() ) {
          break;
        }
        
        if ( !$n->get_first_child() ) {
          $n = null;
          break;
        }
      }
    }
    
    if ( $n ) {
      $n_style = $n->get_style();
      $b = max($b, $n_style->length_in_pt($n_style->margin_top, $cb["h"]));
      $n_style->margin_top = "0pt";
      $style->margin_bottom = $b."pt";
    }

    // Collapse our first child's margin
    /*$f = $this->_frame->get_first_child();
    if ( $f && !$f->is_block() ) {
      while ( $f = $f->get_next_sibling() ) {
        if ( $f->is_block() ) {
          break;
        }
        
        if ( !$f->get_first_child() ) {
          $f = null;
          break;
        }
      }
    }

    // Margin are collapsed only between block elements
    if ( $f ) {
      $f_style = $f->get_style();
      $t = max($t, $f_style->length_in_pt($f_style->margin_top, $cb["h"]));
      $style->margin_top = $t."pt";
      $f_style->margin_bottom = "0pt";
    }*/
  }
843873
function setHeader($string,$margin = 0.50)
    {
        if (strlen($string) >= 255) {
            //carp 'Header string must be less than 255 characters';
            return;
        }
        $this->_header      = $string;
        $this->_margin_head = $margin;
    }
260336
function get_margin_height() {
    $style = $this->_frame->get_style();
    
    if ( $style->list_style_type === "none" ) {
      return 0;
    }
    
    return $style->get_font_size() * self::BULLET_SIZE + 2 * self::BULLET_PADDING;
  }
525031
function renderInsideMarginField( $args ) {
		unset( $args['label_for'], $args['class'] );
		$this->renderField(
			[
				'id' => 'pdf_page_margin_inside',
				'name' => 'pressbooks_theme_options_' . $this->getSlug(),
				'option' => 'pdf_page_margin_inside',
				'value' => getset( $this->options, 'pdf_page_margin_inside' ),
				'description' => $args[0],
				'type' => 'text',
				'class' => 'small-text',
			]
		);
	}