/**
  * Rotate the image clockwise
  *
  * @param Asido_TMP &$tmp
  * @param float $angle
  * @param Asido_Color &$color
  * @return boolean
  * @access protected
  */
 function __rotate(&$tmp, $angle, &$color)
 {
     // skip full loops
     //
     if ($angle % 360 == 0) {
         return true;
     }
     $a = $tmp->image_height;
     $b = $tmp->image_width;
     // do the virtual `border`
     //
     $c = $a * cos(deg2rad($angle)) * sin(deg2rad($angle));
     $d = $b * cos(deg2rad($angle)) * sin(deg2rad($angle));
     // do the rest of the math
     //
     $a2 = $b * sin(deg2rad($angle)) + $a * cos(deg2rad($angle));
     $b2 = $a * sin(deg2rad($angle)) + $b * cos(deg2rad($angle));
     $a3 = 2 * $d + $a;
     $b3 = 2 * $c + $b;
     $a4 = $b3 * sin(deg2rad($angle)) + $a3 * cos(deg2rad($angle));
     $b4 = $a3 * sin(deg2rad($angle)) + $b3 * cos(deg2rad($angle));
     // create the `border` canvas
     //
     $t = $this->__canvas($b + 2 * $c, $a + 2 * $d, $color);
     // copy the image
     //
     imagick_composite($t->target, IMAGICK_COMPOSITE_OP_OVER, $tmp->target, $c, $d);
     // rotate the whole thing
     //
     imagick_rotate($t->target, $angle);
     // `final` result
     //
     $f = $this->__canvas($b2, $a2, $color);
     imagick_composite($f->target, IMAGICK_COMPOSITE_OP_OVER, $t->target, -(floor($b4) - $b2) / 2, -(floor($a4) - $a2) / 2);
     $this->__destroy_target($t);
     $this->__destroy_target($tmp);
     $tmp->target = $f->target;
     $tmp->image_width = $b2;
     $tmp->image_height = $a2;
     return true;
 }
 /**
  * Copy one image to another
  *
  * @param Asido_TMP &$tmp_target
  * @param Asido_TMP &$tmp_source
  * @param integer $destination_x
  * @param integer $destination_y
  * @return boolean
  * @access protected
  */
 function __copy(&$tmp_target, &$tmp_source, $destination_x, $destination_y)
 {
     return imagick_composite($tmp_target->target, IMAGICK_COMPOSITE_OP_OVER, $tmp_source->source, $destination_x, $destination_y);
 }