blob: 7902bdb4bb27b7643f53c5ad479c27249fec3dda [file]
<?php
/**
* File containing the ezcDocumentPdfRenderer class
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* @package Document
* @version //autogen//
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @access private
*/
/**
* Abstract renderer base class
*
* Implements some basic rendering methods, which are required by all
* renderers. Should be extended to render elements in Docbook documents, which
* are not yet handled.
*
* To use a new ccustom renderer one needs to register it in the main renderer,
* which by default is implemented in the class ezcDocumentPdfMainRenderer.
*
* @package Document
* @access private
* @version //autogen//
*/
abstract class ezcDocumentPdfRenderer
{
/**
* Used driver implementation
*
* @var ezcDocumentPdfDriver
*/
protected $driver;
/**
* Used PDF style inferencer for evaluating current styling
*
* @var ezcDocumentPcssStyleInferencer
*/
protected $styles;
/**
* Construct renderer from driver to use
*
* @param ezcDocumentPdfDriver $driver
* @param ezcDocumentPcssStyleInferencer $styles
* @return void
*/
public function __construct( ezcDocumentPdfDriver $driver, ezcDocumentPcssStyleInferencer $styles )
{
$this->driver = $driver;
$this->styles = $styles;
}
/**
* Render box background
*
* Render box background for the given bounding box with the given
* styles.
*
* @param ezcDocumentPdfBoundingBox $space
* @param array $styles
* @return void
*/
protected function renderBoxBackground( ezcDocumentPdfBoundingBox $space, array $styles )
{
if ( isset( $styles['background-color'] ) &&
( $styles['background-color']->value['alpha'] < 1 ) )
{
$this->driver->drawPolygon(
array(
array(
$space->x -
$styles['padding']->value['left'] -
$styles['border']->value['left']['width'],
$space->y -
$styles['padding']->value['top'] -
$styles['border']->value['top']['width'],
),
array(
$space->x +
$styles['padding']->value['right'] +
$styles['border']->value['right']['width'] +
$space->width,
$space->y -
$styles['padding']->value['top'] -
$styles['border']->value['top']['width'],
),
array(
$space->x +
$styles['padding']->value['right'] +
$styles['border']->value['right']['width'] +
$space->width,
$space->y +
$styles['padding']->value['bottom'] +
$styles['border']->value['bottom']['width'] +
$space->height,
),
array(
$space->x -
$styles['padding']->value['left'] -
$styles['border']->value['left']['width'],
$space->y +
$styles['padding']->value['bottom'] +
$styles['border']->value['bottom']['width'] +
$space->height,
),
),
$styles['background-color']->value
);
}
}
/**
* Render box border
*
* Render box border for the given bounding box with the given
* styles.
*
* @param ezcDocumentPdfBoundingBox $space
* @param array $styles
* @param bool $renderTop
* @param bool $renderBottom
* @return void
*/
protected function renderBoxBorder( ezcDocumentPdfBoundingBox $space, array $styles, $renderTop = true, $renderBottom = true )
{
$topLeft = array(
$space->x -
$styles['padding']->value['left'] -
$styles['border']->value['left']['width'] / 2,
$space->y -
$styles['padding']->value['top'] -
$styles['border']->value['top']['width'] / 2,
);
$topRight = array(
$space->x +
$styles['padding']->value['right'] +
$styles['border']->value['right']['width'] / 2 +
$space->width,
$space->y -
$styles['padding']->value['top'] -
$styles['border']->value['top']['width'] / 2,
);
$bottomRight = array(
$space->x +
$styles['padding']->value['right'] +
$styles['border']->value['right']['width'] / 2 +
$space->width,
$space->y +
$styles['padding']->value['bottom'] +
$styles['border']->value['bottom']['width'] / 2 +
$space->height,
);
$bottomLeft = array(
$space->x -
$styles['padding']->value['left'] -
$styles['border']->value['left']['width'] / 2,
$space->y +
$styles['padding']->value['bottom'] +
$styles['border']->value['bottom']['width'] / 2 +
$space->height,
);
if ( $styles['border']->value['left']['width'] > 0 )
{
$this->driver->drawPolyline(
array( $topLeft, $bottomLeft ),
$styles['border']->value['left']['color'],
$styles['border']->value['left']['width']
);
}
if ( $renderTop && $styles['border']->value['top']['width'] > 0 )
{
$this->driver->drawPolyline(
array( $topLeft, $topRight ),
$styles['border']->value['top']['color'],
$styles['border']->value['top']['width']
);
}
if ( $styles['border']->value['right']['width'] > 0 )
{
$this->driver->drawPolyline(
array( $topRight, $bottomRight ),
$styles['border']->value['right']['color'],
$styles['border']->value['right']['width']
);
}
if ( $renderBottom && $styles['border']->value['bottom']['width'] > 0 )
{
$this->driver->drawPolyline(
array( $bottomRight, $bottomLeft ),
$styles['border']->value['bottom']['color'],
$styles['border']->value['bottom']['width']
);
}
}
/**
* Set box covered
*
* Mark rendered space as convered on the page.
*
* @param ezcDocumentPdfPage $page
* @param ezcDocumentPdfBoundingBox $space
* @param array $styles
* @return void
*/
protected function setBoxCovered( ezcDocumentPdfPage $page, ezcDocumentPdfBoundingBox $space, array $styles )
{
// Apply bounding box modifications
$space = clone $space;
$space->x -=
$styles['padding']->value['left'] +
$styles['border']->value['left']['width'] +
$styles['margin']->value['left'];
$space->width +=
$styles['padding']->value['left'] +
$styles['padding']->value['right'] +
$styles['border']->value['left']['width'] +
$styles['border']->value['right']['width'] +
$styles['margin']->value['left'] +
$styles['margin']->value['right'];
$space->y -=
$styles['padding']->value['top'] +
$styles['border']->value['top']['width'] +
$styles['margin']->value['top'];
$space->height +=
$styles['padding']->value['top'] +
$styles['padding']->value['bottom'] +
$styles['border']->value['top']['width'] +
$styles['border']->value['bottom']['width'] +
$styles['margin']->value['top'] +
$styles['margin']->value['bottom'];
$page->setCovered( $space );
$page->y += $space->height;
}
/**
* Evaluate available bounding box
*
* Returns false, if not enough space is available on current
* page, and a bounding box otherwise.
*
* @param ezcDocumentPdfPage $page
* @param array $styles
* @param float $width
* @return mixed
*/
protected function evaluateAvailableBoundingBox( ezcDocumentPdfPage $page, array $styles, $width )
{
// Grap the maximum available vertical space
$space = $page->testFitRectangle( $page->x, $page->y, $width, null );
if ( $space === false )
{
// Could not allocate space, required for even one line
return false;
}
// Apply bounding box modifications
$space->x +=
$styles['padding']->value['left'] +
$styles['border']->value['left']['width'] +
$styles['margin']->value['left'];
$space->width -=
$styles['padding']->value['left'] +
$styles['padding']->value['right'] +
$styles['border']->value['left']['width'] +
$styles['border']->value['right']['width'] +
$styles['margin']->value['left'] +
$styles['margin']->value['right'];
$space->y +=
$styles['padding']->value['top'] +
$styles['border']->value['top']['width'] +
$styles['margin']->value['top'];
$space->height -=
$styles['padding']->value['top'] +
$styles['padding']->value['bottom'] +
$styles['border']->value['top']['width'] +
$styles['border']->value['bottom']['width'] +
$styles['margin']->value['top'] +
$styles['margin']->value['bottom'];
return $space;
}
}
?>