1<?php
2
3/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5/**
6 * Image_Canvas
7 *
8 * Canvas based creation of images to facilitate different output formats
9 *
10 * PHP versions 4 and 5
11 *
12 * LICENSE: This library is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License as published by
14 * the Free Software Foundation; either version 2.1 of the License, or (at your
15 * option) any later version. This library is distributed in the hope that it
16 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
17 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
18 * General Public License for more details. You should have received a copy of
19 * the GNU Lesser General Public License along with this library; if not, write
20 * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 *
23 * @category   Images
24 * @package    Image_Canvas
25 * @author     Jesper Veggerby <pear.nosey@veggerby.dk>
26 * @copyright  Copyright (C) 2003, 2004 Jesper Veggerby Hansen
27 * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
28 * @version    CVS: $Id: Tool.php 287471 2009-08-18 23:12:01Z clockwerx $
29 * @link       http://pear.php.net/package/Image_Canvas
30 */
31
32/**
33 * This class contains a set of tool-functions.
34 *
35 * These functions are all to be called statically
36 *
37 * @category   Images
38 * @package    Image_Canvas
39 * @author     Jesper Veggerby <pear.nosey@veggerby.dk>
40 * @copyright  Copyright (C) 2003, 2004 Jesper Veggerby Hansen
41 * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
42 * @version    Release: @package_version@
43 * @link       http://pear.php.net/package/Image_Canvas
44 * @abstract
45 */
46class Image_Canvas_Tool
47{
48
49    /**
50     * Maps a font name to an actual font file (fx. a .ttf file)
51     *
52     * Used to translate names (i.e. 'Courier New' to 'cour.ttf' or
53     * '/Windows/Fonts/Cour.ttf')
54     *
55     * Font names are translated using the tab-separated file
56     * Image/Canvas/Tool/fontmap.txt.
57     *
58     * The translated font-name (or the original if no translation) exists is
59     * then returned if it is an existing file, otherwise the file is searched
60     * first in the path specified by IMAGE_CANVAS_SYSTEM_FONT_PATH defined in
61     * Image/Canvas.php, then in the Image/Canvas/Fonts folder. If a font is
62     * still not found and the name is not beginning with a '/' the search is
63     * left to the library, otherwise the font is deemed non-existing.
64     *
65     * @param string $name The name of the font
66     * @param string $type The needed file type of the font
67     * @return string The filename of the font
68     * @static
69     */
70    function fontMap($name, $type = '.ttf')
71    {
72        static $_fontMap;
73
74        if (!is_array($_fontMap)) {
75            if (file_exists($fontmap = (dirname(__FILE__) . '/Fonts/fontmap.txt'))) {
76                $file = file($fontmap);
77                foreach($file as $fontmapping) {
78                    list($fontname, $filenames) = explode(',', $fontmapping, 2);
79                    $fontname = trim($fontname);
80                    $filenames = trim($filenames);
81                    $filenames = explode(',', $filenames);
82                    foreach ($filenames as $filename) {
83                        $type_pos = strrpos($filename, '.');
84                        $type = substr($filename, $type_pos);
85                        $_fontMap[$fontname][$type] = $filename;
86                    }
87                }
88            }
89        }
90
91        $type = strtolower($type);
92
93        if ((isset($_fontMap[$name])) && (isset($_fontMap[$name][$type]))) {
94            $filename = $_fontMap[$name][$type];
95        } else {
96            $filename = $name;
97        }
98
99        if (substr($filename, -strlen($type)) !== $type) {
100            $filename .= $type;
101        }
102
103        $result = false;
104        if (file_exists($filename)) {
105            $result = $filename;
106        } elseif (file_exists($file = (IMAGE_CANVAS_SYSTEM_FONT_PATH . $filename))) {
107            $result = $file;
108        } elseif (file_exists($file = (dirname(__FILE__) . '/Fonts/' . $filename))) {
109            $result = $file;
110        } elseif (substr($name, 0, 1) !== '/') {
111            // leave it to the library to find the font
112            $result = $name;
113        }
114
115        return str_replace('\\', '/', $result);
116    }
117
118    /**
119     * Return the average of 2 points
120     *
121     * @param double P1 1st point
122     * @param double P2 2nd point
123     * @return double The average of P1 and P2
124     * @static
125     */
126    function mid($p1, $p2)
127    {
128        return ($p1 + $p2) / 2;
129    }
130
131    /**
132     * Mirrors P1 in P2 by a amount of Factor
133     *
134     * @param double $p1 1st point, point to mirror
135     * @param double $o2 2nd point, mirror point
136     * @param double $factor Mirror factor, 0 returns $p2, 1 returns a pure
137     * mirror, ie $p1 on the exact other side of $p2
138     * @return double $p1 mirrored in $p2 by Factor
139     * @static
140     */
141    function mirror($p1, $p2, $factor = 1)
142    {
143        return $p2 + $factor * ($p2 - $p1);
144    }
145
146    /**
147     * Calculates a Bezier control point, this function must be called for BOTH
148     * X and Y coordinates (will it work for 3D coordinates!?)
149     *
150     * @param double $p1 1st point
151     * @param double $p2 Point to
152     * @param double $factor Mirror factor, 0 returns P2, 1 returns a pure
153     *   mirror, i.e. P1 on the exact other side of P2
154     * @return double P1 mirrored in P2 by Factor
155     * @static
156     */
157    function controlPoint($p1, $p2, $factor, $smoothFactor = 0.75)
158    {
159        $sa = Image_Canvas_Tool::mirror($p1, $p2, $smoothFactor);
160        $sb = Image_Canvas_Tool::mid($p2, $sa);
161
162        $m = Image_Canvas_Tool::mid($p2, $factor);
163
164        $pC = Image_Canvas_Tool::mid($sb, $m);
165
166        return $pC;
167    }
168
169    /**
170     * Calculates a Bezier point, this function must be called for BOTH X and Y
171     * coordinates (will it work for 3D coordinates!?)
172     *
173     * @param double $t A position between $p2 and $p3, value between 0 and 1
174     * @param double $p1 Point to use for calculating control points
175     * @param double $p2 Point 1 to calculate bezier curve between
176     * @param double $p3 Point 2 to calculate bezier curve between
177     * @param double $p4 Point to use for calculating control points
178     * @return double The bezier value of the point t between $p2 and $p3 using
179     * $p1 and $p4 to calculate control points
180     * @static
181     */
182    function bezier($t, $p1, $p2, $p3, $p4)
183    {
184        // (1-t)^3*p1 + 3*(1-t)^2*t*p2 + 3*(1-t)*t^2*p3 + t^3*p4
185        return pow(1 - $t, 3) * $p1 +
186            3 * pow(1 - $t, 2) * $t * $p2 +
187            3 * (1 - $t) * pow($t, 2) * $p3 +
188            pow($t, 3) * $p4;
189    }
190
191    /**
192     * Gets the angle / slope of a line relative to horizontal (left -> right)
193     *
194     * @param double $x0 The starting x point
195     * @param double $y0 The starting y point
196     * @param double $x1 The ending x point
197     * @param double $y1 The ending y point
198     * @param double The angle in degrees of the line
199     * @static
200     */
201    function getAngle($x0, $y0, $x1, $y1)
202    {
203
204        $dx = ($x1 - $x0);
205        $dy = ($y1 - $y0);
206        $l = sqrt($dx * $dx + $dy * $dy);
207        $v = rad2deg(asin(($y0 - $y1) / $l));
208        if ($dx < 0) {
209            $v = 180 - $v;
210        }
211        return $v;
212
213    }
214
215}
216
217?>
218