<?php
/**
 * File containing the ezcGraphCairoOODriver 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 Graph
 * @version //autogentag//
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 */

/**
 * Extension of the basic driver package to utilize the cairo library.
 *
 * This drivers options are defined in the class 
 * {@link ezcGraphCairoDriverOptions} extending the basic driver options class
 * {@link ezcGraphDriverOptions}. 
 *
 * As this is the default driver you do not need to explicitely set anything to
 * use it, but may use some of its advanced features.
 *
 * <code>
 *   $graph = new ezcGraphPieChart();
 *   $graph->background->color = '#FFFFFFFF';
 *   $graph->title = 'Access statistics';
 *   $graph->legend = false;
 *   
 *   $graph->data['Access statistics'] = new ezcGraphArrayDataSet( array(
 *       'Mozilla' => 19113,
 *       'Explorer' => 10917,
 *       'Opera' => 1464,
 *       'Safari' => 652,
 *       'Konqueror' => 474,
 *   ) );
 *   
 *   $graph->renderer = new ezcGraphRenderer3d();
 *   $graph->renderer->options->pieChartShadowSize = 10;
 *   $graph->renderer->options->pieChartGleam = .5;
 *   $graph->renderer->options->dataBorder = false;
 *   $graph->renderer->options->pieChartHeight = 16;
 *   $graph->renderer->options->legendSymbolGleam = .5;
 * 
 *   // Use cairo driver
 *   $graph->driver = new ezcGraphCairoOODriver();
 *   
 *   $graph->render( 400, 200, 'tutorial_driver_cairo.png' );
 * </code>
 *
 * @version //autogentag//
 * @package Graph
 * @mainclass
 */
class ezcGraphCairoOODriver extends ezcGraphDriver
{
    /**
     * Surface for cairo
     * 
     * @var CairoImageSurface
     */
    protected $surface;

    /**
     * Current cairo context.
     * 
     * @var CairoContext
     */
    protected $context;

    /**
     * List of strings to draw
     * array ( array(
     *          'text' => array( 'strings' ),
     *          'options' => ezcGraphFontOptions,
     *      )
     * 
     * @var array
     */
    protected $strings = array();

    /**
     * Constructor
     * 
     * @param array $options Default option array
     * @return void
     * @ignore
     */
    public function __construct( array $options = array() )
    {
        ezcBase::checkDependency( 'Graph', ezcBase::DEP_PHP_EXTENSION, 'cairo' );
        $this->options = new ezcGraphCairoDriverOptions( $options );
    }

    /**
     * Initilize cairo surface
     *
     * Initilize cairo surface from values provided in the options object, if
     * is has not been already initlized.
     * 
     * @return void
     */
    protected function initiliazeSurface()
    {
        // Immediatly exit, if surface already exists
        if ( $this->surface !== null )
        {
            return;
        }

        $this->surface = new CairoImageSurface(
            CairoFormat::ARGB32, 
            $this->options->width, 
            $this->options->height
        );

        $this->context = new CairoContext( $this->surface );
        $this->context->setLineWidth( 1 );
    }

    /**
     * Get SVG style definition
     *
     * Returns a string with SVG style definitions created from color, 
     * fillstatus and line thickness.
     * 
     * @param ezcGraphColor $color Color
     * @param mixed $filled Filled
     * @param float $thickness Line thickness.
     * @return string Formatstring
     */
    protected function getStyle( ezcGraphColor $color, $filled = true, $thickness = 1. )
    {
        switch ( true )
        {
            case $color instanceof ezcGraphLinearGradient:
                $pattern = new CairoLinearGradient(
                    $color->startPoint->x, $color->startPoint->y,
                    $color->endPoint->x, $color->endPoint->y
                );

                $pattern->addColorStopRgba(
                    0,
                    $color->startColor->red / 255,
                    $color->startColor->green / 255,
                    $color->startColor->blue / 255,
                    1 - $color->startColor->alpha / 255
                );

                $pattern->addColorStopRgba(
                    1,
                    $color->endColor->red / 255,
                    $color->endColor->green / 255,
                    $color->endColor->blue / 255,
                    1 - $color->endColor->alpha / 255
                );

                $this->context->setSource( $pattern );
                $this->context->fill();
                break;

            case $color instanceof ezcGraphRadialGradient:
                $pattern = new CairoRadialGradient(
                    0, 0, 0,
                    0, 0, 1
                );

                $pattern->addColorStopRgba(
                    0,
                    $color->startColor->red / 255,
                    $color->startColor->green / 255,
                    $color->startColor->blue / 255,
                    1 - $color->startColor->alpha / 255
                );

                $pattern->addColorStopRgba(
                    1,
                    $color->endColor->red / 255,
                    $color->endColor->green / 255,
                    $color->endColor->blue / 255,
                    1 - $color->endColor->alpha / 255
                );

                // Scale pattern, and move it to the correct position
                $matrix = CairoMatrix::multiply(
                    $move = CairoMatrix::initTranslate( -$color->center->x, -$color->center->y ),
                    $scale = CairoMatrix::initScale( 1 / $color->width, 1 / $color->height )
                );
                $pattern->setMatrix( $matrix );

                $this->context->setSource( $pattern );
                $this->context->fill();
                break;
            default:
                $this->context->setSourceRgba(
                    $color->red / 255,
                    $color->green / 255,
                    $color->blue / 255,
                    1 - $color->alpha / 255
                );
                break;
        }

        // Set line width
         $this->context->setLineWidth( $thickness );

        // Set requested fill state for context
        if ( $filled )
        {
            $this->context->fillPreserve();
        }
    }

    /**
     * Draws a single polygon. 
     * 
     * @param array $points Point array
     * @param ezcGraphColor $color Polygon color
     * @param mixed $filled Filled
     * @param float $thickness Line thickness
     * @return void
     */
    public function drawPolygon( array $points, ezcGraphColor $color, $filled = true, $thickness = 1. )
    {
        $this->initiliazeSurface();

        $this->context->newPath();

        $lastPoint = end( $points );
        $this->context->moveTo( $lastPoint->x, $lastPoint->y );

        foreach ( $points as $point )
        {
            $this->context->lineTo( $point->x, $point->y );
        }

        $this->context->closePath();

        $this->getStyle( $color, $filled, $thickness );
        $this->context->stroke();

        return $points;
    }
    
    /**
     * Draws a line 
     * 
     * @param ezcGraphCoordinate $start Start point
     * @param ezcGraphCoordinate $end End point
     * @param ezcGraphColor $color Line color
     * @param float $thickness Line thickness
     * @return void
     */
    public function drawLine( ezcGraphCoordinate $start, ezcGraphCoordinate $end, ezcGraphColor $color, $thickness = 1. )
    {
        $this->initiliazeSurface();

        $this->context->newPath();

        $this->context->moveTo( $start->x, $start->y );
        $this->context->lineTo( $end->x, $end->y );

        $this->getStyle( $color, false, $thickness );
        $this->context->stroke();

        return array( $start, $end );
    }

    /**
     * Returns boundings of text depending on the available font extension
     * 
     * @param float $size Textsize
     * @param ezcGraphFontOptions $font Font
     * @param string $text Text
     * @return ezcGraphBoundings Boundings of text
     */
    protected function getTextBoundings( $size, ezcGraphFontOptions $font, $text )
    {
        $this->context->selectFontFace( $font->name, CairoFontSlant::NORMAL, CairoFontWeight::NORMAL );
        $this->context->setFontSize( $size );
        $extents = $this->context->textExtents( $text );

        return new ezcGraphBoundings(
            0,
            0,
            $extents['width'],
            $extents['height']
        );
    }

    /**
     * Writes text in a box of desired size
     * 
     * @param string $string Text
     * @param ezcGraphCoordinate $position Top left position
     * @param float $width Width of text box
     * @param float $height Height of text box
     * @param int $align Alignement of text
     * @param ezcGraphRotation $rotation
     * @return void
     */
    public function drawTextBox( $string, ezcGraphCoordinate $position, $width, $height, $align, ezcGraphRotation $rotation = null )
    {
        $this->initiliazeSurface();

        $padding = $this->options->font->padding + ( $this->options->font->border !== false ? $this->options->font->borderWidth : 0 );

        $width -= $padding * 2;
        $height -= $padding * 2;
        $textPosition = new ezcGraphCoordinate(
            $position->x + $padding,
            $position->y + $padding
        );

        // Try to get a font size for the text to fit into the box
        $maxSize = min( $height, $this->options->font->maxFontSize );
        $result = false;
        for ( $size = $maxSize; $size >= $this->options->font->minFontSize; )
        {
            $result = $this->testFitStringInTextBox( $string, $position, $width, $height, $size );
            if ( is_array( $result ) )
            {
                break;
            }
            $size = ( ( $newsize = $size * ( $result ) ) >= $size ? $size - 1 : floor( $newsize ) );
        }
        
        if ( !is_array( $result ) )
        {
            if ( ( $height >= $this->options->font->minFontSize ) &&
                 ( $this->options->autoShortenString ) )
            {
                $result = $this->tryFitShortenedString( $string, $position, $width, $height, $size = $this->options->font->minFontSize );
            } 
            else
            {
                throw new ezcGraphFontRenderingException( $string, $this->options->font->minFontSize, $width, $height );
            }
        }

        $this->options->font->minimalUsedFont = $size;
        $this->strings[] = array(
            'text' => $result,
            'position' => $textPosition,
            'width' => $width,
            'height' => $height,
            'align' => $align,
            'font' => $this->options->font,
            'rotation' => $rotation,
        );

        return array(
            clone $position,
            new ezcGraphCoordinate( $position->x + $width, $position->y ),
            new ezcGraphCoordinate( $position->x + $width, $position->y + $height ),
            new ezcGraphCoordinate( $position->x, $position->y + $height ),
        );
    }
    
    /**
     * Render text depending of font type and available font extensions
     * 
     * @param string $id 
     * @param string $text 
     * @param string $font 
     * @param ezcGraphColor $color 
     * @param ezcGraphCoordinate $position 
     * @param float $size 
     * @param float $rotation 
     * @return void
     */
    protected function renderText( $text, $font, ezcGraphColor $color, ezcGraphCoordinate $position, $size, $rotation = null )
    {
        $this->context->selectFontFace( $font, CairoFontSlant::NORMAL, CairoFontWeight::NORMAL );
        $this->context->setFontSize( $size );
        
        // Store current state of context
        $this->context->save();
        $this->context->moveTo( 0, 0 );

        if ( $rotation !== null )
        {
            // Move to the center
            $this->context->translate(
                $rotation->getCenter()->x, 
                $rotation->getCenter()->y
            );
            // Rotate around text center
            $this->context->rotate(
                deg2rad( $rotation->getRotation() ) 
            );
            // Center the text
            $this->context->translate(
                $position->x - $rotation->getCenter()->x,
                $position->y - $rotation->getCenter()->y - $size * .15
            );
        } else {
            $this->context->translate(
                $position->x,
                $position->y - $size * .15
            );
        }

        $this->context->newPath();
        $this->getStyle( $color, true );
        $this->context->showText( $text );
        $this->context->stroke();

        // Restore state of context
        $this->context->restore();
    }

    /**
     * Draw all collected texts
     *
     * The texts are collected and their maximum possible font size is 
     * calculated. This function finally draws the texts on the image, this
     * delayed drawing has two reasons:
     *
     * 1) This way the text strings are always on top of the image, what 
     *    results in better readable texts
     * 2) The maximum possible font size can be calculated for a set of texts
     *    with the same font configuration. Strings belonging to one chart 
     *    element normally have the same font configuration, so that all texts
     *    belonging to one element will have the same font size.
     * 
     * @access protected
     * @return void
     */
    protected function drawAllTexts()
    {
        $this->initiliazeSurface();

        foreach ( $this->strings as $text )
        {
            $size = $text['font']->minimalUsedFont;

            $completeHeight = count( $text['text'] ) * $size + ( count( $text['text'] ) - 1 ) * $this->options->lineSpacing;

            // Calculate y offset for vertical alignement
            switch ( true )
            {
                case ( $text['align'] & ezcGraph::BOTTOM ):
                    $yOffset = $text['height'] - $completeHeight;
                    break;
                case ( $text['align'] & ezcGraph::MIDDLE ):
                    $yOffset = ( $text['height'] - $completeHeight ) / 2;
                    break;
                case ( $text['align'] & ezcGraph::TOP ):
                default:
                    $yOffset = 0;
                    break;
            }

            $padding = $text['font']->padding + $text['font']->borderWidth / 2;
            if ( $this->options->font->minimizeBorder === true )
            {
                // Calculate maximum width of text rows
                $width = false;
                foreach ( $text['text'] as $line )
                {
                    $string = implode( ' ', $line );
                    $boundings = $this->getTextBoundings( $size, $text['font'], $string );
                    if ( ( $width === false) || ( $boundings->width > $width ) )
                    {
                        $width = $boundings->width;
                    }
                }

                switch ( true )
                {
                    case ( $text['align'] & ezcGraph::CENTER ):
                        $xOffset = ( $text['width'] - $width ) / 2;
                        break;
                    case ( $text['align'] & ezcGraph::RIGHT ):
                        $xOffset = $text['width'] - $width;
                        break;
                    case ( $text['align'] & ezcGraph::LEFT ):
                    default:
                        $xOffset = 0;
                        break;
                }

                $borderPolygonArray = array(
                    new ezcGraphCoordinate(
                        $text['position']->x - $padding + $xOffset,
                        $text['position']->y - $padding + $yOffset
                    ),
                    new ezcGraphCoordinate(
                        $text['position']->x + $padding * 2 + $xOffset + $width,
                        $text['position']->y - $padding + $yOffset
                    ),
                    new ezcGraphCoordinate(
                        $text['position']->x + $padding * 2 + $xOffset + $width,
                        $text['position']->y + $padding * 2 + $yOffset + $completeHeight
                    ),
                    new ezcGraphCoordinate(
                        $text['position']->x - $padding + $xOffset,
                        $text['position']->y + $padding * 2 + $yOffset + $completeHeight
                    ),
                );
            }
            else
            {
                $borderPolygonArray = array(
                    new ezcGraphCoordinate(
                        $text['position']->x - $padding,
                        $text['position']->y - $padding
                    ),
                    new ezcGraphCoordinate(
                        $text['position']->x + $padding * 2 + $text['width'],
                        $text['position']->y - $padding
                    ),
                    new ezcGraphCoordinate(
                        $text['position']->x + $padding * 2 + $text['width'],
                        $text['position']->y + $padding * 2 + $text['height']
                    ),
                    new ezcGraphCoordinate(
                        $text['position']->x - $padding,
                        $text['position']->y + $padding * 2 + $text['height']
                    ),
                );
            }

            if ( $text['rotation'] !==  null )
            {
                foreach ( $borderPolygonArray as $nr => $point )
                {
                    $borderPolygonArray[$nr] = $text['rotation']->transformCoordinate( $point );
                }
            }

            if ( $text['font']->background !== false )
            {
                $this->drawPolygon( 
                    $borderPolygonArray, 
                    $text['font']->background,
                    true
                );
            }

            if ( $text['font']->border !== false )
            {
                $this->drawPolygon( 
                    $borderPolygonArray, 
                    $text['font']->border,
                    false,
                    $text['font']->borderWidth
                );
            }

            // Render text with evaluated font size
            $completeString = '';
            foreach ( $text['text'] as $line )
            {
                $string = implode( ' ', $line );
                $completeString .= $string;
                $boundings = $this->getTextBoundings( $size, $text['font'], $string );
                $text['position']->y += $size;

                switch ( true )
                {
                    case ( $text['align'] & ezcGraph::LEFT ):
                        $position = new ezcGraphCoordinate( 
                            $text['position']->x, 
                            $text['position']->y + $yOffset
                        );
                        break;
                    case ( $text['align'] & ezcGraph::RIGHT ):
                        $position = new ezcGraphCoordinate( 
                            $text['position']->x + ( $text['width'] - $boundings->width ), 
                            $text['position']->y + $yOffset
                        );
                        break;
                    case ( $text['align'] & ezcGraph::CENTER ):
                        $position = new ezcGraphCoordinate( 
                            $text['position']->x + ( ( $text['width'] - $boundings->width ) / 2 ), 
                            $text['position']->y + $yOffset
                        );
                        break;
                }

                // Optionally draw text shadow
                if ( $text['font']->textShadow === true )
                {
                    $this->renderText( 
                        $string,
                        $text['font']->name, 
                        $text['font']->textShadowColor,
                        new ezcGraphCoordinate(
                            $position->x + $text['font']->textShadowOffset,
                            $position->y + $text['font']->textShadowOffset
                        ),
                        $size,
                        $text['rotation']
                    );
                }
                
                // Finally draw text
                $this->renderText( 
                    $string,
                    $text['font']->name, 
                    $text['font']->color, 
                    $position,
                    $size,
                    $text['rotation']
                );

                $text['position']->y += $size * $this->options->lineSpacing;
            }
        }
    }

    /**
     * Draws a sector of cirlce
     * 
     * @param ezcGraphCoordinate $center Center of circle
     * @param mixed $width Width
     * @param mixed $height Height
     * @param mixed $startAngle Start angle of circle sector
     * @param mixed $endAngle End angle of circle sector
     * @param ezcGraphColor $color Color
     * @param mixed $filled Filled;
     * @return void
     */
    public function drawCircleSector( ezcGraphCoordinate $center, $width, $height, $startAngle, $endAngle, ezcGraphColor $color, $filled = true )
    {
        $this->initiliazeSurface();

        // Normalize angles
        if ( $startAngle > $endAngle )
        {
            $tmp = $startAngle;
            $startAngle = $endAngle;
            $endAngle = $tmp;
        }
        
        $this->context->save();
        
        // Draw circular arc path
        $this->context->newPath();
        $this->context->translate(
            $center->x,
            $center->y
        );
        $this->context->scale(
            1, $height / $width
        );

        $this->context->moveTo( 0, 0 );
        $this->context->arc(
            0., 0., 
            $width / 2, 
            deg2rad( $startAngle ),
            deg2rad( $endAngle )
        );
        $this->context->lineTo( 0, 0 );

        $this->context->restore();
        $this->getStyle( $color, $filled );
        $this->context->stroke();

        // Create polygon array to return
        $polygonArray = array( $center );
        for ( $angle = $startAngle; $angle < $endAngle; $angle += $this->options->imageMapResolution )
        {
            $polygonArray[] = new ezcGraphCoordinate(
                $center->x + 
                    ( ( cos( deg2rad( $angle ) ) * $width ) / 2 ),
                $center->y + 
                    ( ( sin( deg2rad( $angle ) ) * $height ) / 2 )
            );
        }
        $polygonArray[] = new ezcGraphCoordinate(
            $center->x + 
                ( ( cos( deg2rad( $endAngle ) ) * $width ) / 2 ),
            $center->y + 
                ( ( sin( deg2rad( $endAngle ) ) * $height ) / 2 )
        );

        return $polygonArray;
    }

    /**
     * Draws a circular arc consisting of several minor steps on the bounding 
     * lines.
     * 
     * @param ezcGraphCoordinate $center 
     * @param mixed $width 
     * @param mixed $height 
     * @param mixed $size 
     * @param mixed $startAngle 
     * @param mixed $endAngle 
     * @param ezcGraphColor $color 
     * @param bool $filled 
     * @return string Element id
     */
    protected function simulateCircularArc( ezcGraphCoordinate $center, $width, $height, $size, $startAngle, $endAngle, ezcGraphColor $color, $filled )
    {
        for ( 
            $tmpAngle = min( ceil ( $startAngle / 180 ) * 180, $endAngle ); 
            $tmpAngle <= $endAngle; 
            $tmpAngle = min( ceil ( $startAngle / 180 + 1 ) * 180, $endAngle ) )
        {
            $this->context->newPath();
            $this->context->moveTo(
                $center->x + cos( deg2rad( $startAngle ) ) * $width / 2, 
                $center->y + sin( deg2rad( $startAngle ) ) * $height / 2
            );

            // @TODO: Use cairo_curve_to()
            for(
                $angle = $startAngle;
                $angle <= $tmpAngle;
                $angle = min( $angle + $this->options->circleResolution, $tmpAngle ) )
            {
                $this->context->lineTo(
                    $center->x + cos( deg2rad( $angle ) ) * $width / 2, 
                    $center->y + sin( deg2rad( $angle ) ) * $height / 2 + $size
                );

                if ( $angle === $tmpAngle )
                {
                    break;
                }
            }

            for(
                $angle = $tmpAngle;
                $angle >= $startAngle;
                $angle = max( $angle - $this->options->circleResolution, $startAngle ) )
            {
                $this->context->lineTo(
                    $center->x + cos( deg2rad( $angle ) ) * $width / 2, 
                    $center->y + sin( deg2rad( $angle ) ) * $height / 2
                );

                if ( $angle === $startAngle )
                {
                    break;
                }
            }

            $this->context->closePath();
            $this->getStyle( $color, $filled );
            $this->context->stroke( );

            $startAngle = $tmpAngle;
            if ( $tmpAngle === $endAngle ) 
            {
                break;
            }
        }
    }

    /**
     * Draws a circular arc
     * 
     * @param ezcGraphCoordinate $center Center of ellipse
     * @param integer $width Width of ellipse
     * @param integer $height Height of ellipse
     * @param integer $size Height of border
     * @param float $startAngle Starting angle of circle sector
     * @param float $endAngle Ending angle of circle sector
     * @param ezcGraphColor $color Color of Border
     * @param bool $filled
     * @return void
     */
    public function drawCircularArc( ezcGraphCoordinate $center, $width, $height, $size, $startAngle, $endAngle, ezcGraphColor $color, $filled = true )
    {
        $this->initiliazeSurface();

        // Normalize angles
        if ( $startAngle > $endAngle )
        {
            $tmp = $startAngle;
            $startAngle = $endAngle;
            $endAngle = $tmp;
        }

        $this->simulateCircularArc( $center, $width, $height, $size, $startAngle, $endAngle, $color, $filled );

        if ( ( $this->options->shadeCircularArc !== false ) &&
             $filled )
        {
            $gradient = new ezcGraphLinearGradient(
                new ezcGraphCoordinate(
                    $center->x - $width,
                    $center->y
                ),
                new ezcGraphCoordinate(
                    $center->x + $width,
                    $center->y
                ),
                ezcGraphColor::fromHex( '#FFFFFF' )->transparent( $this->options->shadeCircularArc * 1.5 ),
                ezcGraphColor::fromHex( '#000000' )->transparent( $this->options->shadeCircularArc * 1.5 )
            );
        
            $this->simulateCircularArc( $center, $width, $height, $size, $startAngle, $endAngle, $gradient, $filled );
        }

        // Create polygon array to return
        $polygonArray = array();
        for ( $angle = $startAngle; $angle < $endAngle; $angle += $this->options->imageMapResolution )
        {
            $polygonArray[] = new ezcGraphCoordinate(
                $center->x + 
                    ( ( cos( deg2rad( $angle ) ) * $width ) / 2 ),
                $center->y + 
                    ( ( sin( deg2rad( $angle ) ) * $height ) / 2 )
            );
        }
        $polygonArray[] = new ezcGraphCoordinate(
            $center->x + 
                ( ( cos( deg2rad( $endAngle ) ) * $width ) / 2 ),
            $center->y + 
                ( ( sin( deg2rad( $endAngle ) ) * $height ) / 2 )
        );

        for ( $angle = $endAngle; $angle > $startAngle; $angle -= $this->options->imageMapResolution )
        {
            $polygonArray[] = new ezcGraphCoordinate(
                $center->x + 
                    ( ( cos( deg2rad( $angle ) ) * $width ) / 2 ) + $size,
                $center->y + 
                    ( ( sin( deg2rad( $angle ) ) * $height ) / 2 )
            );
        }
        $polygonArray[] = new ezcGraphCoordinate(
            $center->x + 
                ( ( cos( deg2rad( $startAngle ) ) * $width ) / 2 ) + $size,
            $center->y + 
                ( ( sin( deg2rad( $startAngle ) ) * $height ) / 2 )
        );

        return $polygonArray;
    }

    /**
     * Draw circle 
     * 
     * @param ezcGraphCoordinate $center Center of ellipse
     * @param mixed $width Width of ellipse
     * @param mixed $height height of ellipse
     * @param ezcGraphColor $color Color
     * @param mixed $filled Filled
     * @return void
     */
    public function drawCircle( ezcGraphCoordinate $center, $width, $height, ezcGraphColor $color, $filled = true )
    {
        $this->initiliazeSurface();
        
        $this->context->save();
        
        // Draw circular arc path
        $this->context->newPath();
        $this->context->translate( 
            $center->x,
            $center->y
        );
        $this->context->scale( 
            1, $height / $width
        );

        $this->context->arc( 
            0., 0., 
            $width / 2, 
            0, 2 * M_PI
        );

        $this->context->restore();
        $this->getStyle( $color, $filled );
        $this->context->stroke();

        // Create polygon array to return
        $polygonArray = array();
        for ( $angle = 0; $angle < ( 2 * M_PI ); $angle += deg2rad( $this->options->imageMapResolution ) )
        {
            $polygonArray[] = new ezcGraphCoordinate(
                $center->x + 
                    ( ( cos( $angle ) * $width ) / 2 ),
                $center->y + 
                    ( ( sin( $angle ) * $height ) / 2 )
            );
        }

        return $polygonArray;
    }

    /**
     * Draw an image 
     *
     * The image will be inlined in the SVG document using data URL scheme. For
     * this the mime type and base64 encoded file content will be merged to 
     * URL.
     * 
     * @param mixed $file Image file
     * @param ezcGraphCoordinate $position Top left position
     * @param mixed $width Width of image in destination image
     * @param mixed $height Height of image in destination image
     * @return void
     */
    public function drawImage( $file, ezcGraphCoordinate $position, $width, $height )
    {
        $this->initiliazeSurface();

        // Ensure given bitmap is a PNG image
        $data = getimagesize( $file );
        if ( $data[2] !== IMAGETYPE_PNG )
        {
            throw new Exception( 'Cairo only has support for PNGs.' );
        }

        // Create new surface from given bitmap
        $imageSurface = CairoImageSurface::createFromPng( $file );

        // Create pattern from source image to be able to transform it
        $pattern = new CairoSurfacePattern( $imageSurface );

        // Scale pattern to defined dimensions and move it to its destination position
        $matrix = CairoMatrix::multiply(
            $move = CairoMatrix::initTranslate( -$position->x, -$position->y ),
            $scale = CairoMatrix::initScale( $data[0] / $width, $data[1] / $height )
        );
        $pattern->setMatrix( $matrix );

        // Merge surfaces
        $this->context->setSource( $pattern );
        $this->context->rectangle( $position->x, $position->y, $width, $height );
        $this->context->fill();
    }

    /**
     * Return mime type for current image format
     * 
     * @return string
     */
    public function getMimeType()
    {
        return 'image/png';
    }

    /**
     * Render image directly to output
     *
     * The method renders the image directly to the standard output. You 
     * normally do not want to use this function, because it makes it harder 
     * to proper cache the generated graphs.
     * 
     * @return void
     */
    public function renderToOutput()
    {
        $this->drawAllTexts();

        header( 'Content-Type: ' . $this->getMimeType() );

        // Write to tmp file, echo and remove tmp file again.
        $fileName = tempnam( '/tmp', 'ezc' );

        // cairo_surface_write_to_png( $this->surface, $file );
        $this->surface->writeToPng( $fileName );
        $contents = file_get_contents( $fileName );
        unlink( $fileName );

        // Directly echo contents
        echo $contents;
    }

    /**
     * Finally save image
     * 
     * @param string $file Destination filename
     * @return void
     */
    public function render( $file )
    {
        $this->drawAllTexts();
        $this->surface->writeToPng( $file );
    }

    /**
     * Get resource of rendered result
     *
     * Return the resource of the rendered result. You should not use this
     * method before you called either renderToOutput() or render(), as the
     * image may not be completely rendered until then.
     *
     * This method returns an array, containing the surface and the context in
     * a structure like:
     * <code>
     *  array(
     *      'surface' => resource,
     *      'context' => resource,
     *  )
     * </code>
     * 
     * @return array
     */
    public function getResource()
    {
        return array( 
            'surface' => $this->surface,
            'context' => $this->context,
        );
    }
}

?>
