图片旋转
@param float|int $angle
@param string|int $background
@param int $ignore 如果被设为非零值，则透明色会被忽略（否则会被保留）。
@return bool 失败时返回 FALSE。
426419
public function rotate($angle = 90, $background = '#fff', $ignore = 0) {
		$this->image = imagerotate($this->image, $angle, $this->getColorWithRGB($background), $ignore);
		return $this->image !== false;
	}
848504
public function rotate($degrees, $background = 0xffffff, $alpha = 1.0)
    {
        $this->do_rotate($degrees, $background, $alpha);

        return $this;
    }
99434
public final void setAxisAngle(Vector3D axis, double angle) {
		setAxisAngle(axis.getX(),  axis.getY(), axis.getZ(), angle);
	}
1151902
public function ignore($ignore)
    {
        if (!is_array($ignore)) {
            $ignore = [$ignore];
        }
        $this->ignore = array_unique(array_merge($this->ignore, $ignore));

        return $this;
    }
508716
public function do_rotate($degrees, $background = 0xffffff, $alpha = 1.0)
    {
        $backgroundColor = sprintf('rgba(%u,%u,%u,%f)', ($background >> 16) & 0xFF, ($background >> 8) & 0xFF,
            $background & 0xFF, $alpha);
        $this->_image->rotateImage(new \ImagickPixel($backgroundColor), $degrees);
        $this->_image->setImagePage($this->_width, $this->_height, 0, 0);

        $this->_width = $this->_image->getImageWidth();
        $this->_height = $this->_image->getImageHeight();

        return $this;
    }
728622
public function canvas($width, $height, $background = null)
    {
        return $this->createDriver()->newImage($width, $height, $background);
    }
481130
private function checkConcave($angles)
    {
        try {
            for ($i = 0; $i < count($angles); $i++) {
                if (180 < $angles[$i]->getAngle()) {
                    return $i;
                }

            }

            return false;
        } catch (\Exception $e) {
            throw $e;
        }
    }
1248802
function _fetch($ignore_fields=false)
	{
		# KMN # if ($this->connection->debug) ADOConnection::outp("_fetch()");
		if ($this->fetchMode & ADODB_FETCH_ASSOC) {
			if ($this->fetchMode & ADODB_FETCH_NUM) {
				//# KMN # if ($this->connection->debug) ADOConnection::outp("fetch mode: both");
				$this->fields = @sqlsrv_fetch_array($this->_queryID,SQLSRV_FETCH_BOTH);
			} else {
				//# KMN # if ($this->connection->debug) ADOConnection::outp("fetch mode: assoc");
				$this->fields = @sqlsrv_fetch_array($this->_queryID,SQLSRV_FETCH_ASSOC);
			}

			if (is_array($this->fields)) {
				if (ADODB_ASSOC_CASE == 0) {
					foreach($this->fields as $k=>$v) {
						$this->fields[strtolower($k)] = $v;
					}
				} else if (ADODB_ASSOC_CASE == 1) {
					foreach($this->fields as $k=>$v) {
						$this->fields[strtoupper($k)] = $v;
					}
				}
			}
		} else {
			//# KMN # if ($this->connection->debug) ADOConnection::outp("fetch mode: num");
			$this->fields = @sqlsrv_fetch_array($this->_queryID,SQLSRV_FETCH_NUMERIC);
		}
		if(is_array($this->fields) && array_key_exists(1,$this->fields) && !array_key_exists(0,$this->fields)) {//fix fetch numeric keys since they're not 0 based
			$arrFixed = array();
			foreach($this->fields as $key=>$value) {
				if(is_numeric($key)) {
					$arrFixed[$key-1] = $value;
				} else {
					$arrFixed[$key] = $value;
				}
			}
			//if($this->connection->debug) ADOConnection::outp("<hr>fixing non 0 based return array, old: ".print_r($this->fields,true)." new: ".print_r($arrFixed,true));
			$this->fields = $arrFixed;
		}
		if(is_array($this->fields)) {
			foreach($this->fields as $key=>$value) {
				if (is_object($value) && method_exists($value, 'format')) {//is DateTime object
					$this->fields[$key] = $value->format("Y-m-d\TH:i:s\Z");
				}
			}
		}
		if($this->fields === null) $this->fields = false;
		# KMN # if ($this->connection->debug) ADOConnection::outp("<hr>after _fetch, fields: <pre>".print_r($this->fields,true)." backtrace: ".adodb_backtrace(false));
		return $this->fields;
	}
1300856
public function setOptions($width = 900, $height = 1300, array $ignore = [], $timeout = null)
    {
        $this->width  = $width;
        $this->height = $height;
        $this->ignore = $ignore;
        $this->timeout = $timeout;
    }
1090054
public static function copy($source, $target, $ignore = null)
    {
        $source = rtrim($source, '\\/');
        $target = rtrim($target, '\\/');

        if (!is_dir($source)) {
            throw new \RuntimeException('Cannot copy non-existing folder.');
        }

        // Make sure that path to the target exists before copying.
        self::create($target);

        $success = true;

        // Go through all sub-directories and copy everything.
        $files = self::all($source);
        foreach ($files as $file) {
            if ($ignore && preg_match($ignore, $file)) {
                continue;
            }
            $src = $source .'/'. $file;
            $dst = $target .'/'. $file;

            if (is_dir($src)) {
                // Create current directory (if it doesn't exist).
                if (!is_dir($dst)) {
                    $success &= @mkdir($dst, 0777, true);
                }
            } else {
                // Or copy current file.
                $success &= @copy($src, $dst);
            }
        }

        if (!$success) {
            $error = error_get_last();
            throw new \RuntimeException($error['message'] ?? 'Unknown error');
        }

        // Make sure that the change will be detected when caching.
        @touch(dirname($target));
    }
90901
public function insert($ignore = false)
    {
        $this->validate();

        // Optional ignore string
        if ($ignore) {
            $insertString = "INSERT IGNORE INTO `%s` (%s) VALUES %s";
        } else {
            $insertString = "INSERT INTO `%s` (%s) VALUES %s";
        }

        $query = sprintf(
            $insertString,
            $this->table,
            $this->rowsString,
            $this->bindString
        );

        try {
            $this->db->execute($query, $this->valuesFlattened);
            return $this->db->affectedRows() > 0;
        } catch (PDOException $ex) {
            Di::getDefault()->get(Services::LOGGER)->error(
                'Could not perform bulk insert ' . $ex->getMessage() . '    TRACE: ' . $ex->getTraceAsString()
            );
            throw new BatchInsertException($ex->getMessage());
        }
    }
886693
public function getTextBox($X, $Y, $FontName, $FontSize, $Angle, $Text)
    {
        $coords = imagettfbbox($FontSize, 0, $this->loadFont($FontName, 'fonts'), $Text);

        $a = deg2rad($Angle);
        $ca = cos($a);
        $sa = sin($a);
        $RealPos = [];
        for ($i = 0; $i < 7; $i += 2) {
            $RealPos[$i / 2]["X"] = $X + round($coords[$i] * $ca + $coords[$i + 1] * $sa);
            $RealPos[$i / 2]["Y"] = $Y + round($coords[$i + 1] * $ca - $coords[$i] * $sa);
        }

        $RealPos[TEXT_ALIGN_BOTTOMLEFT]["X"] = $RealPos[0]["X"];
        $RealPos[TEXT_ALIGN_BOTTOMLEFT]["Y"] = $RealPos[0]["Y"];
        $RealPos[TEXT_ALIGN_BOTTOMRIGHT]["X"] = $RealPos[1]["X"];
        $RealPos[TEXT_ALIGN_BOTTOMRIGHT]["Y"] = $RealPos[1]["Y"];
        $RealPos[TEXT_ALIGN_TOPLEFT]["X"] = $RealPos[3]["X"];
        $RealPos[TEXT_ALIGN_TOPLEFT]["Y"] = $RealPos[3]["Y"];
        $RealPos[TEXT_ALIGN_TOPRIGHT]["X"] = $RealPos[2]["X"];
        $RealPos[TEXT_ALIGN_TOPRIGHT]["Y"] = $RealPos[2]["Y"];
        $RealPos[TEXT_ALIGN_BOTTOMMIDDLE]["X"] = ($RealPos[1]["X"] - $RealPos[0]["X"]) / 2 + $RealPos[0]["X"];
        $RealPos[TEXT_ALIGN_BOTTOMMIDDLE]["Y"] = ($RealPos[0]["Y"] - $RealPos[1]["Y"]) / 2 + $RealPos[1]["Y"];
        $RealPos[TEXT_ALIGN_TOPMIDDLE]["X"] = ($RealPos[2]["X"] - $RealPos[3]["X"]) / 2 + $RealPos[3]["X"];
        $RealPos[TEXT_ALIGN_TOPMIDDLE]["Y"] = ($RealPos[3]["Y"] - $RealPos[2]["Y"]) / 2 + $RealPos[2]["Y"];
        $RealPos[TEXT_ALIGN_MIDDLELEFT]["X"] = ($RealPos[0]["X"] - $RealPos[3]["X"]) / 2 + $RealPos[3]["X"];
        $RealPos[TEXT_ALIGN_MIDDLELEFT]["Y"] = ($RealPos[0]["Y"] - $RealPos[3]["Y"]) / 2 + $RealPos[3]["Y"];
        $RealPos[TEXT_ALIGN_MIDDLERIGHT]["X"] = ($RealPos[1]["X"] - $RealPos[2]["X"]) / 2 + $RealPos[2]["X"];
        $RealPos[TEXT_ALIGN_MIDDLERIGHT]["Y"] = ($RealPos[1]["Y"] - $RealPos[2]["Y"]) / 2 + $RealPos[2]["Y"];
        $RealPos[TEXT_ALIGN_MIDDLEMIDDLE]["X"] = ($RealPos[1]["X"] - $RealPos[3]["X"]) / 2 + $RealPos[3]["X"];
        $RealPos[TEXT_ALIGN_MIDDLEMIDDLE]["Y"] = ($RealPos[0]["Y"] - $RealPos[2]["Y"]) / 2 + $RealPos[2]["Y"];

        return $RealPos;
    }
396122
public function return404($notifier = false, \Exception $exception = null)
    {
    	if (!defined('ERROR_404'))
    	{
    	    define('ERROR_404', 'Y');
    	}

        \CHTTP::SetStatus('404 Not Found');

        if ($exception !== false)
        {
            if ($notifier === false)
            {
                $this->exceptionNotifier = false;
            }

            if ($exception instanceof \Exception)
            {
                throw $exception;
            }
            else
            {
                throw new \Exception('Page not found');
            }
        }
    }
21016
public function newImage($width, $height, $background = null)
    {
        $background = new Color($background);

        // create empty core
        $core = new \Imagick;
        $core->newImage($width, $height, $background->getPixel(), 'png');
        $core->setType(\Imagick::IMGTYPE_UNDEFINED);
        $core->setImageType(\Imagick::IMGTYPE_UNDEFINED);
        $core->setColorspace(\Imagick::COLORSPACE_UNDEFINED);

        // build image
        return new Image(new static, $core);
    }
189663
public function populate(array $data, array $ignore = ['createdByUserId', 'createdDate', 'createdReason'])
    {
        if (isset($data['site']) && $data['site'] instanceof Site
            && !in_array(
                'site',
                $ignore
            )
        ) {
            $this->setSite($data['site']);
        }

        if (isset($data['name']) && !in_array('name', $ignore)) {
            $this->setName($data['name']);
        }

        // @bc support
        if (isset($data['pageId']) && !in_array('pageId', $ignore)) {
            $this->setPageId($data['pageId']);
        }

        if (isset($data['pageTitle']) && !in_array('pageTitle', $ignore)) {
            $this->setPageTitle($data['pageTitle']);
        }

        if (isset($data['pageType']) && !in_array('pageType', $ignore)) {
            $this->setPageType($data['pageType']);
        }

        if (isset($data['description']) && !in_array('description', $ignore)) {
            $this->setDescription($data['description']);
        }

        if (isset($data['keywords']) && !in_array('keywords', $ignore)) {
            $this->setKeywords($data['keywords']);
        }

        if (isset($data['author']) && !in_array('author', $ignore)) {
            $this->setAuthor($data['author']);
        }

        if (isset($data['lastPublished'])
            && $data['lastPublished'] instanceof \DateTime
            && !in_array('lastPublished', $ignore)
        ) {
            $this->setLastPublished($data['lastPublished']);
        }

        if (isset($data['createdDate']) && $data['createdDate'] instanceof \DateTime
            && !in_array('createdDate', $ignore)
        ) {
            $this->setLastPublished($data['createdDate']);
        }

        if (isset($data['pageLayout']) && !in_array('pageLayout', $ignore)) {
            $this->setPageLayout($data['pageLayout']);
        }

        if (isset($data['siteLayoutOverride'])
            && !in_array(
                'siteLayoutOverride',
                $ignore
            )
        ) {
            $this->setSiteLayoutOverride($data['siteLayoutOverride']);
        }

        $parent = null;

        if (isset($data['parent']) && !in_array('parent', $ignore)) {
            $parent = $data['parent'];
        }

        if ($parent instanceof Page) {
            $this->setParent($parent);
        }
    }
603301
private static function _readColor($color,$background=false) {
		if (isset($color["rgb"])) {
			return (string)$color["rgb"];
		} else if (isset($color["indexed"])) {
			return PHPExcel_Style_Color::indexedColor($color["indexed"]-7,$background)->getARGB();
		}
	}
835932
public function rotate($degree, $background = 0)
    {
        //argument test
        Argument::i()
            //Argument 1 must be a number
            ->test(1, 'numeric')
            //Argument 2 must be a number
            ->test(2, 'numeric');

        //rotate the image
        $rotate = imagerotate($this->resource, $degree, $background);

        //destroy the original resource
        imagedestroy($this->resource);

        //assign the new resource
        $this->resource = $rotate;

        return $this;
    }