function rotate()

in blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/xinha/plugins/ImageManager/Classes/GD.php [157:325]


    function rotate($angle, $options=null)
    {
        if(function_exists('imagerotate')) {
            $white = imagecolorallocate ($this->imageHandle, 255, 255, 255);
			$this->imageHandle = imagerotate($this->imageHandle, $angle, $white);
            return true;
        }

        if ( $options==null ){
            $autoresize = true;
            $color_mask = array(255,255,0);
        } else {
            extract( $options );
        }

        while ($angle <= -45) {
            $angle  += 360;
        }
        while ($angle > 270) {
            $angle  -= 360;
        }

        $t      = deg2rad($angle);

        if( !is_array($color_mask) ){
            if ($color[0]=='#'){
                $this->colorhex2colorarray( $color_mask );
            } else {
                include_once('Image/Transform/Driver/ColorDefs.php');
                $color = isset($colornames[$color_mask])?$colornames[$color_mask]:false;
            }
        }

        // Do not round it, too much lost of quality
        $cosT   = cos($t);
        $sinT   = sin($t);

        $img    =& $this->imageHandle;

        $width  = $max_x  = $this->img_x;
        $height = $max_y  = $this->img_y;
        $min_y  = 0;
        $min_x  = 0;

        $x1     = round($max_x/2,0);
        $y1     = round($max_y/2,0);

        if ( $autoresize ){
            $t      = abs($t);
            $a      = round($angle,0);
            switch((int)($angle)){
                case 0:
                        $width2     = $width;
                        $height2    = $height;
                    break;
                case 90:
                        $width2     = $height;
                        $height2    = $width;
                    break;
                case 180:
                        $width2     = $width;
                        $height2    = $height;
                    break;
                case 270:
                        $width2     = $height;
                        $height2    = $width;
                    break;
                default:
                    $width2     = (int)(abs(sin($t) * $height + cos($t) * $width));
                    $height2    = (int)(abs(cos($t) * $height+sin($t) * $width));
            }

            $width2     -= $width2%2;
            $height2    -= $height2%2;

            $d_width    = abs($width - $width2);
            $d_height   = abs($height - $height2);
            $x_offset   = $d_width/2;
            $y_offset   = $d_height/2;
            $min_x2     = -abs($x_offset);
            $min_y2     = -abs($y_offset);
            $max_x2     = $width2;
            $max_y2     = $height2;
        }

        $img2   = @imagecreate($width2,$height2);

        if ( !is_resource($img2) ){
            return false;/*PEAR::raiseError('Cannot create buffer for the rotataion.',
                                null, PEAR_ERROR_TRIGGER, E_USER_NOTICE);*/
        }

        $this->img_x = $width2;
        $this->img_y = $height2;


        imagepalettecopy($img2,$img);

        $mask   = imagecolorresolve($img2,$color_mask[0],$color_mask[1],$color_mask[2]);

        // use simple lines copy for axes angles
        switch((int)($angle)){
            case 0:
                imagefill ($img2, 0, 0,$mask);
                for ($y=0; $y < $max_y; $y++) {
                    for ($x = $min_x; $x < $max_x; $x++){
                        $c  = @imagecolorat ( $img, $x, $y);
                        imagesetpixel($img2,$x+$x_offset,$y+$y_offset,$c);
                    }
                }
                break;
            case 90:
                imagefill ($img2, 0, 0,$mask);
                for ($x = $min_x; $x < $max_x; $x++){
                    for ($y=$min_y; $y < $max_y; $y++) {
                        $c  = imagecolorat ( $img, $x, $y);
                        imagesetpixel($img2,$max_y-$y-1,$x,$c);
                    }
                }
                break;
            case 180:
                imagefill ($img2, 0, 0,$mask);
                for ($y=0; $y < $max_y; $y++) {
                    for ($x = $min_x; $x < $max_x; $x++){
                        $c  = @imagecolorat ( $img, $x, $y);
                        imagesetpixel($img2, $max_x2-$x-1, $max_y2-$y-1, $c);
                    }
                }
                break;
            case 270:
                imagefill ($img2, 0, 0,$mask);
                for ($y=0; $y < $max_y; $y++) {
                    for ($x = $max_x; $x >= $min_x; $x--){
                        $c  = @imagecolorat ( $img, $x, $y);
                        imagesetpixel($img2,$y,$max_x-$x-1,$c);
                    }
                }
                break;
            // simple reverse rotation algo
            default:
                $i=0;
                for ($y = $min_y2; $y < $max_y2; $y++){

                    // Algebra :)
                    $x2 = round((($min_x2-$x1) * $cosT) + (($y-$y1) * $sinT + $x1),0);
                    $y2 = round((($y-$y1) * $cosT - ($min_x2-$x1) * $sinT + $y1),0);

                    for ($x = $min_x2; $x < $max_x2; $x++){

                        // Check if we are out of original bounces, if we are
                        // use the default color mask
                        if ( $x2>=0 && $x2<$max_x && $y2>=0 && $y2<$max_y ){
                            $c  = imagecolorat ( $img, $x2, $y2);
                        } else {
                            $c  = $mask;
                        }
                        imagesetpixel($img2,$x+$x_offset,$y+$y_offset,$c);

                        // round verboten!
                        $x2  += $cosT;
                        $y2  -= $sinT;
                    }
                }
                break;
        }
        $this->old_image    = $this->imageHandle;
        $this->imageHandle  =  $img2;
        return true;
    }