3 * Copyright © 1999,2000,2001,2002,2007 $ThePhpWikiProgrammingTeam
5 * This file is part of PhpWiki.
7 * PhpWiki is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * PhpWiki is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with PhpWiki; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 * SPDX-License-Identifier: GPL-2.0-or-later
26 * File loading and saving diagnostic messages, to see whether an
27 * image was saved to or loaded from the cache and what the path is.
29 * Convert text into a png image using GD without using [WikiPluginCached|Help:WikiPlugin].
30 * The images are stored in a private <PHPWIKI_DIR>/images/<LANG> subdirectory instead,
31 * which are not timestamp checked at all. Delete the .png file(s) if you change anything.
33 * This is a really simple and stupid plugin, which needs some work.
34 * No size and color options, no change check.
36 * We'd need a ButtonCreator for the MacOSX theme buttons also.
37 * Via svg => png, or is gd2 good enough?
39 * PHP must be compiled with support for the GD library version 1.6 or
40 * later to create PNG image files:
42 * ./configure --with-gd
44 * See <https://www.php.net/manual/pl/ref.image.php> for more info.
47 // define('text2png_debug', DEBUG & _DEBUG_VERBOSE);
49 class WikiPlugin_text2png
52 function getDescription()
54 return _("Convert text into a PNG image using GD.");
57 function getDefaultArguments()
60 // TODO: add fixed size and center.
61 return array('text' => "text2png testtext",
64 'fontsize' => 18, // with GD1 it's the pixelsize, with GD2 the pointsize
66 'fontcolor' => '#000000',
67 'shadowcolor' => '#AFAFAF',
68 'backcolor' => '#ffffff');
73 * @param string $argstr
74 * @param WikiRequest $request
75 * @param string $basepage
78 function run($dbi, $argstr, &$request, $basepage)
80 if (imagetypes() & IMG_PNG) {
81 // we have gd & png so go ahead.
82 $args = $this->getArgs($argstr, $request);
83 return $this->text2png($args);
85 // we don't have png and/or gd.
86 $error_html = _("Sorry, this version of PHP cannot create PNG image files.");
88 $error_html .= _("See") . _(": ");
89 $url = "https://www.php.net/manual/en/ref.image.php";
90 $link = HTML::a(array('href' => $url), $url);
91 return HTML::span(array('class' => 'error'), $error_html, $link);
96 * Parse hexcolor into ordinal rgb array.
97 * '#000' => array(0,0,0)
98 * '#000000' => array(0,0,0)
100 function hexcolor($h, $default = array())
102 if ($h[0] != '#') return $default;
103 $rgb = substr($h, 1);
104 if (strlen($rgb) == 3)
105 return array(hexdec($rgb[0]), hexdec($rgb[1]), hexdec($rgb[2]));
106 elseif (strlen($rgb) == 6)
107 return array(hexdec(substr($rgb, 0, 2)), hexdec(substr($rgb, 2, 2)), hexdec(substr($rgb, 4, 2)));
111 function text2png($args)
115 * Basic image creation and caching
117 * You MUST delete the image cache yourself in /images if you
118 * change the drawing routines!
121 $filename = urlencode($text) . ".png"; // protect by urlencode!!!
124 * FIXME: need something more elegant, and a way to gettext a
125 * different language depending on any individual
126 * user's locale preferences.
129 $basedir = "text2png-image";
130 $filepath = getUploadFilePath() . "$basedir";
131 if ($_force or !file_exists($filepath . $filename)) {
132 if (!file_exists($filepath)) {
133 $oldumask = umask(0);
134 // permissions affected by user the www server is running as
135 mkdir(getUploadFilePath() . $basedir);
141 * prepare a new image
143 * FIXME: needs a dynamic image size depending on text
147 // got this logic from GraphViz
148 if (defined('TTFONT'))
150 elseif (PHP_OS == "Darwin") // Mac OS X
151 $ttfont = "/System/Library/Frameworks/JavaVM.framework/Versions/1.3.1/Home/lib/fonts/LucidaSansRegular.ttf";
152 elseif (isWindows()) {
153 $ttfont = $_ENV['windir'] . '\Fonts\Arial.ttf';
155 $ttfont = 'luximr'; // This is the only what sourceforge offered.
156 //$ttfont = 'Helvetica';
159 /* http://download.php.net/manual/en/function.imagettftext.php
160 * array imagettftext (int im, int size, int angle, int x, int y,
161 * int col, string fontfile, string text)
166 $error_html = _("PHP was unable to create a new GD image stream. Read 'lib/plugin/text2png.php' for details.");
168 $error_html .= _("See") . _(": ");
169 $url = "https://www.php.net/manual/en/function.imagecreate.php";
170 $link = HTML::a(array('href' => $url), $url);
172 $s = imagettfbbox($fontsize, 0, $ttfont, $text);
174 return HTML::span(array('class' => 'error'), $error_html, $link);
176 $im = imagecreate(abs($s[4]) + 20, abs($s[7]) + 10);
178 return HTML::span(array('class' => 'error'), $error_html, $link);
180 $rgb = $this->hexcolor($backcolor, array(255, 255, 255));
181 $bg_color = imagecolorallocate($im, $rgb[0], $rgb[1], $rgb[2]);
183 $rgb = $this->hexcolor($shadowcolor, array(175, 175, 175));
184 $text_color = imagecolorallocate($im, $rgb[0], $rgb[1], $rgb[2]);
185 // shadow is 1 pixel down and 2 pixels right
186 imagettftext($im, $fontsize, 0, 12, abs($s[7]) + 6, $text_color, $ttfont, $text);
189 $rgb = $this->hexcolor($fontcolor, array(0, 0, 0));
190 $text_color = imagecolorallocate($im, $rgb[0], $rgb[1], $rgb[2]);
191 imagettftext($im, $fontsize, 0, 10, abs($s[7]) + 5, $text_color, $ttfont, $text);
194 * An alternate text drawing method in case imagettftext
197 //imagestring($im, 2, 10, 40, $text, $text_color);
199 // To dump directly to browser:
200 //header("Content-type: image/png");
204 $success = imagepng($im, $filepath . $filename);
211 // create an <img src= tag to show the image!
214 if (defined('text2png_debug')) {
217 trigger_error(sprintf(_("Image saved to cache file: %s"),
218 $filepath . $filename));
220 trigger_error(sprintf(_("Image loaded from cache file: %s"),
221 $filepath . $filename));
224 $url = getUploadDataPath() . "$basedir/" . urlencode($filename);
225 $html->pushContent(HTML::img(array('src' => $url,
227 'title' => '"' . $text . '"' . _(" produced by ") . $this->getName())));
229 return HTML::span(array('class' => 'error'),
230 sprintf(_("couldn't open file “%s” for writing"),
231 $filepath . $filename));