eZ Publish  [trunk]
ezimageobject.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZImageObject class.
00004  *
00005  * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
00006  * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
00007  * @version //autogentag//
00008  * @package lib
00009  */
00010 
00011 /*!
00012   \class eZImageObject ezimageobject.php
00013   \ingroup eZImageObject
00014   \brief Image object which handles image layers
00015 
00016 */
00017 
00018 class eZImageObject extends eZImageInterface
00019 {
00020     /// Alignment values @{
00021     const ALIGN_AXIS_NONE = 0x00;
00022     const ALIGN_AXIS_START = 0x01;
00023     const ALIGN_AXIS_STOP = 0x02;
00024     const ALIGN_AXIS_CENTER = 0x03; // ALIGN_AXIS_START | ALIGN_AXIS_STOP
00025     const ALIGN_AXIS_MASK = 0x03; // ALIGN_AXIS_START | ALIGN_AXIS_STOP
00026     ///@}
00027 
00028     /// Placement types @{
00029     /// Places the layer absolutely from on the axis.
00030     const PLACE_CONSTANT = 1;
00031     /// Places the layer relative to the axis size.
00032     const PLACE_RELATIVE = 2;
00033     ///@}
00034 
00035     function eZImageObject( $imageObjectRef = null, $imageObject = null, $width = false, $height = false )
00036     {
00037         $this->eZImageInterface( $imageObjectRef, $imageObject, $width, $height );
00038         $this->TemplateURI = 'design:image/imageobject.tpl';
00039         $this->ImageLayers = array();
00040         $this->ImageLayerCounter = 0;
00041     }
00042 
00043     /*!
00044      A definition which tells the template engine which template to use
00045      for displaying the image.
00046     */
00047     function templateData()
00048     {
00049         return array( 'type' => 'template',
00050                       'template_variable_name' => 'image',
00051                       'uri' => $this->TemplateURI );
00052     }
00053 
00054     /*!
00055      Sets the URI of the template to use for displaying it using the template engine to \a $uri.
00056     */
00057     function setTemplateURI( $uri )
00058     {
00059         $this->TemplateURI = $uri;
00060     }
00061 
00062     /*!
00063      Figures out the absolute axis placement and returns it.
00064      The variable \a $type determines how \a $value is used, it can either
00065      be a constant value (self::PLACE_CONSTANT) or a relative value
00066      (self::PLACE_RELATIVE) where input value is placed relative to the length
00067      of the axis (\a $axisStop - \a $axisStart).
00068      \a $alignment determines where the axis should start, self::ALIGN_AXIS_NONE
00069      and self::ALIGN_AXIS_START will return the position from \a $axisStart towards \a $axisStop,
00070      self::ALIGN_AXIS_STOP returns the position from the \a $axisStop towards \a $axisStart
00071      while self::ALIGN_AXIS_CENTER returns the middle of \a $axisStart and \a $axisStop.
00072     */
00073     function calculateAxisPlacement( $value, $type, $alignment, $axisStart, $axisStop, $currentLength )
00074     {
00075         $pos = 0;
00076         if ( $type == self::PLACE_CONSTANT )
00077             $pos = $value;
00078         else if ( $type == self::PLACE_RELATIVE )
00079         {
00080             $length = $axisStop - $axisStart;
00081             $pos = $value * $length;
00082         }
00083         $alignment = $alignment & self::ALIGN_AXIS_MASK;
00084         if ( $alignment == self::ALIGN_AXIS_NONE or
00085              $alignment == self::ALIGN_AXIS_START )
00086             return $axisStart + $pos;
00087         if ( $alignment == self::ALIGN_AXIS_CENTER )
00088         {
00089             $length = $axisStop - $axisStart;
00090             $halfLength = (int)(($length - $currentLength) / 2);
00091             return $axisStart + $halfLength + $value;
00092         }
00093         else // Align to stop
00094         {
00095             $pos = $axisStop - $pos - $currentLength;
00096             return $pos;
00097         }
00098     }
00099 
00100     /*!
00101      Initializes the axis from the parameter value \a $name filling
00102      in any missing values with defaults.
00103     */
00104     function initializeAxis( $parameters, $name )
00105     {
00106         $axis = array();
00107         if ( isset( $parameters[$name] ) )
00108             $axis = $parameters[$name];
00109         if ( !isset( $axis['alignment'] ) )
00110             $axis['alignment'] = self::ALIGN_AXIS_NONE;
00111         if ( !isset( $axis['placement'] ) )
00112             $axis['placement'] = self::PLACE_CONSTANT;
00113         if ( !isset( $axis['value'] ) )
00114             $axis['value'] = 0;
00115         return $axis;
00116     }
00117 
00118     /*!
00119      Calculates the position for \c x and \c y parameters in \a $parameters and returns
00120      an absolute position in an array.
00121      The returned array will contain the \c x and \c y key.
00122     */
00123     function calculatePosition( $parameters, $width, $height )
00124     {
00125         $xAxis = eZImageObject::initializeAxis( $parameters, 'x' );
00126         $yAxis = eZImageObject::initializeAxis( $parameters, 'y' );
00127         $x = eZImageObject::calculateAxisPlacement( $xAxis['value'], $xAxis['placement'], $xAxis['alignment'],
00128                                                     0, $this->width(), $width );
00129         $y = eZImageObject::calculateAxisPlacement( $yAxis['value'], $yAxis['placement'], $yAxis['alignment'],
00130                                                     0, $this->height(), $height );
00131         return array( 'x' => $x,
00132                       'y' => $y );
00133     }
00134 
00135     /*!
00136      \return the transparency value found in the parameters or 0 if no value is found.
00137     */
00138     function getTransparency( $parameters )
00139     {
00140         if ( !isset( $parameters['transparency'] ) )
00141         {
00142             return 0.0;
00143         }
00144         $transparency = max( 0.0, min( 1.0, $parameters['transparency'] ) );
00145         return $transparency;
00146     }
00147 
00148     /*!
00149      \return the transparency percentage found in the parameters or 0 if no percentage is found.
00150     */
00151     function getTransparencyPercent( $parameters )
00152     {
00153         $transparency = eZImageObject::getTransparency( $parameters );
00154         return (int)($transparency * 100.0);
00155     }
00156 
00157     /*!
00158      Adds the image layer object \a $imageLayer to the end of the layer list with optional parameters \a $parameters
00159      \return the ID of the layer, the ID is unique per image object.
00160      \sa prependLayer
00161     */
00162     function appendLayer( &$imageLayer, $parameters = array() )
00163     {
00164         if ( !$imageLayer instanceof eZImageLayer )
00165         {
00166             eZDebug::writeWarning( 'Only eZImageLayer objects may be added as layer items', __METHOD__ );
00167             return false;
00168         }
00169         ++$this->ImageLayerCounter;
00170         $layerID = $this->ImageLayerCounter;
00171         $this->ImageLayers[] = $layerID;
00172         $this->ImageLayerIndex[$layerID] = array( 'image' => &$imageLayer,
00173                                                   'parameters' => $parameters );
00174         return $layerID;
00175     }
00176 
00177     /*!
00178      Adds the image layer object \a $imageLayer to the beginning of the layer list with optional parameters \a $parameters
00179      \return the ID of the layer, the ID is unique per image object.
00180      \sa appendLayer
00181     */
00182     function prependLayer( &$imageLayer, $parameters = array() )
00183     {
00184         if ( !$imageLayer instanceof eZImageLayer )
00185         {
00186             eZDebug::writeWarning( 'Only eZImageLayer objects may be added as layer items', __METHOD__ );
00187             return false;
00188         }
00189         ++$this->ImageLayerCounter;
00190         $layerID = $this->ImageLayerCounter;
00191         $this->ImageLayers = array_merge( array( $layerID ),
00192                                           $this->ImageLayers );
00193         $this->ImageLayerIndex[$layerID] = array( 'image' => &$imageLayer,
00194                                                   'parameters' => $parameters );
00195         return $layerID;
00196     }
00197 
00198     /*!
00199      \return true if the layer with ID \a $layerID exists in this image object.
00200     */
00201     function hasLayer( $layerID )
00202     {
00203         return ( in_array( $layerID, $this->ImageLayers ) and
00204                  array_key_exists( $layerID, $this->ImageLayerIndex ) );
00205     }
00206 
00207     /*!
00208      Cleans up the current image object if it is set.
00209     */
00210     function destroy()
00211     {
00212         if ( is_array( $this->ImageLayers ) )
00213         {
00214             foreach( $this->ImageLayers as $item )
00215             {
00216                 if ( $this->ImageLayerIndex[$item]['image'] instanceof eZImageLayer )
00217                 {
00218                     $this->ImageLayerIndex[$item]['image']->destroy();
00219                 }
00220             }
00221         }
00222         parent::destroy();
00223     }
00224 
00225     /*!
00226      Removes the layer with ID \a $layerID.
00227      \return true if succesful
00228      \sa hasLayer, appendLayer
00229     */
00230     function removeLayer( $layerID )
00231     {
00232         if ( !in_array( $layerID, $this->ImageLayers ) or
00233              !array_key_exists( $layerID, $this->ImageLayerIndex ) )
00234             return false;
00235         $layerData = $this->ImageLayerIndex[$layerID];
00236         unset( $this->ImageLayerIndex[$layerID] );
00237         $imageLayers = array();
00238         foreach ( $this->ImageLayers as $imageLayerID )
00239         {
00240             if ( $imageLayerID != $layerID )
00241                 $imageLayers[] = $imageLayerID;
00242         }
00243         $this->ImageLayers = $imageLayers;
00244         return true;
00245     }
00246 
00247     /*!
00248      Flattens the image so that it can be displayed.
00249     */
00250     function processImage()
00251     {
00252         $this->flatten();
00253         return true;
00254     }
00255 
00256     /*!
00257      Goes trough all layers and merges them together into a single image.
00258      This image can then be displayed on the webpage.
00259     */
00260     function flatten()
00261     {
00262         $i = 0;
00263         $hasFirst = false;
00264         $firstImageLayer = null;
00265         $firstImageLayerData = null;
00266         while ( $i < count( $this->ImageLayers ) and
00267                 !$hasFirst )
00268         {
00269             $layerID = $this->ImageLayers[$i];
00270             $layerData =& $this->ImageLayerIndex[$layerID];
00271             $layer = $layerData['image'];
00272             if ( $layer instanceof eZImageLayer )
00273             {
00274                 $firstImageLayerData = $layerData;
00275                 $firstImageLayer = $layer;
00276                 $hasFirst = true;
00277             }
00278             else
00279                 eZDebug::writeWarning( 'Wrong image type ' . gettype( $layer ), __METHOD__ );
00280             ++$i;
00281         }
00282         if ( $hasFirst )
00283         {
00284             $lastImageLayerData = null;
00285             $firstImageLayer->imageObject();
00286             if ( !$this->width() )
00287             {
00288                 $this->setWidth( $firstImageLayer->width() );
00289             }
00290             if ( !$this->height() )
00291             {
00292                 $this->setHeight( $firstImageLayer->height() );
00293             }
00294             $firstImageLayer->mergeLayer( $this,
00295                                           $firstImageLayerData,
00296                                           $lastImageLayerData );
00297             $lastImageLayerData = null;
00298             while ( $i < count( $this->ImageLayers ) )
00299             {
00300                 $layerID = $this->ImageLayers[$i];
00301                 $layerData =& $this->ImageLayerIndex[$layerID];
00302                 $layer = $layerData['image'];
00303                 unset( $imageObject );
00304                 if ( $layer instanceof eZImageLayer )
00305                 {
00306                     $layer->mergeLayer( $this,
00307                                         $layerData,
00308                                         $lastImageLayerData );
00309                     $lastImageLayerData = $layerData;
00310                 }
00311                 else
00312                 {
00313                     eZDebug::writeWarning( 'Wrong image type ' . gettype( $layer ), __METHOD__ );
00314                 }
00315                 ++$i;
00316             }
00317             return true;
00318         }
00319         return false;
00320     }
00321 
00322     /// \privatesection
00323     public $ImageLayers;
00324     public $TemplateURI;
00325     public $ImageLayerIndex;
00326 }
00327 
00328 ?>