Вход Регистрация
Файл: outs/wideimage/Coordinate.php
Строк: 195
<?php
    
/**
 * @author Gasper Kozak
 * @copyright 2007-2011

    This file is part of WideImage.
        
    WideImage is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 2.1 of the License, or
    (at your option) any later version.
        
    WideImage is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.
        
    You should have received a copy of the GNU Lesser General Public License
    along with WideImage; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    * @package Internals
  **/
    
    
    /**
     * @package Exceptions
     */
    
class WideImage_InvalidCoordinateException extends WideImage_Exception {}
    
    
/**
     * A utility class for smart coordinates
     *  
     * @package Internals
     **/
    
class WideImage_Coordinate
    
{
        static protected 
$coord_align = array("left""center""right""top""middle""bottom");
        static protected 
$coord_numeric = array("[0-9]+""[0-9]+.[0-9]+""[0-9]+%""[0-9]+.[0-9]+%");
        
        
/**
         * Parses a numeric or string representation of a corrdinate into a structure
         * 
         * @param string $coord Smart coordinate
         * @return array Parsed smart coordinate
         */
        
static function parse($c)
        {
            
$tokens = array();
            
$operators = array('+''-');
            
            
$flush_operand false;
            
$flush_operator false;
            
$current_operand '';
            
$current_operator '';
            
$coordinate strval($c);
            
$expr_len strlen($coordinate);
            
            for (
$i 0$i $expr_len$i++)
            {
                
$char $coordinate[$i];
                
                if (
in_array($char$operators))
                {
                    
$flush_operand true;
                    
$flush_operator true;
                    
$current_operator $char;
                }
                else
                {
                    
$current_operand .= $char;
                    if (
$i == $expr_len 1)
                        
$flush_operand true;
                }
                
                if (
$flush_operand)
                {
                    if (
trim($current_operand) != '')
                        
$tokens[] = array('type' => 'operand''value' => trim($current_operand));
                    
                    
$current_operand '';
                    
$flush_operand false;
                }
                
                if (
$flush_operator)
                {
                    
$tokens[] = array('type' => 'operator''value' => $char);
                    
$flush_operator false;
                }
            }
            return 
$tokens;
        }
        
        
/**
         * Evaluates the $coord relatively to $dim
         * 
         * @param string $coord A numeric value or percent string
         * @param int $dim Dimension
         * @param int $sec_dim Secondary dimension (for align)
         * @return int Calculated value
         */
        
static function evaluate($coord$dim$sec_dim null)
        {
            
$comp_regex implode('|'self::$coord_align) . '|' implode('|'self::$coord_numeric);
            if (
preg_match("/^([+-])?({$comp_regex})$/"$coord$matches))
            {
                
$sign intval($matches[1] . "1");
                
$val $matches[2];
                if (
in_array($valself::$coord_align))
                {
                    if (
$sec_dim === null)
                    {
                        switch (
$val)
                        {
                            case 
'left':
                            case 
'top':
                                return 
0;
                                break;
                            case 
'center':
                            case 
'middle':
                                return 
$sign intval($dim 2);
                                break;
                            case 
'right':
                            case 
'bottom':
                                return 
$sign $dim;
                                break;
                            default:
                                return 
null;
                        }
                    }
                    else
                    {
                        switch (
$val)
                        {
                            case 
'left':
                            case 
'top':
                                return 
0;
                                break;
                            case 
'center':
                            case 
'middle':
                                return 
$sign intval($dim $sec_dim 2);
                                break;
                            case 
'right':
                            case 
'bottom':
                                return 
$sign * ($dim $sec_dim);
                                break;
                            default:
                                return 
null;
                        }
                    }
                }
                elseif (
substr($val, -1) === '%')
                    return 
intval(round($sign $dim floatval(str_replace('%'''$val)) / 100));
                else
                    return 
$sign intval(round($val));
            }
        }
        
        
/**
         * Calculates and fixes a smart coordinate into a numeric value
         * 
         * @param mixed $value Smart coordinate, relative to $dim
         * @param int $dim Coordinate to which $value is relative
         * @param int $sec_dim Secondary dimension (for align)
         * @return int Calculated value
         */
        
static function fix($value$dim$sec_dim null)
        {
            
$coord_tokens self::parse($value);
            
            if (
count($coord_tokens) == || $coord_tokens[count($coord_tokens) - 1]['type'] != 'operand')
                throw new 
WideImage_InvalidCoordinateException("Couldn't parse coordinate '$value' properly.");
            
            
$value 0;
            
$operation 1;
            foreach (
$coord_tokens as $token)
            {
                if (
$token['type'] == 'operand')
                {
                    
$operand_value self::evaluate($token['value'], $dim$sec_dim);
                    if (
$operation == 1)
                        
$value $value $operand_value;
                    elseif (
$operation == -1)
                        
$value $value $operand_value;
                    else
                        throw new 
WideImage_InvalidCoordinateException("Invalid coordinate syntax.");
                    
                    
$operation 0;
                }
                elseif (
$token['type'] == 'operator')
                {
                    if (
$token['value'] == '-')
                    {
                        if (
$operation == 0)
                            
$operation = -1;
                        else
                            
$operation $operation * -1;
                    }
                    elseif (
$token['value'] == '+')
                    {
                        if (
$operation == 0)
                            
$operation '1';
                    }
                }
            }
            return 
$value;
        }
    }
Онлайн: 0
Реклама