Issues (459)

src/text/TTF.php (4 issues)

1
<?php
2
3
/**
4
 * JPGraph v4.0.3
5
 */
6
7
namespace Amenadiel\JpGraph\Text;
8
9
use Amenadiel\JpGraph\Util;
10
11
/**
12
 * @class TTF
13
 * // Description: Handle TTF font names and mapping and loading of
14
 * //              font files
15
 */
16
class TTF
17
{
18
    private $font_files;
19
    private $style_names;
20
    public static $FONT_BASEPATH;
21
22 21
    public function __construct()
23
    {
24 21
        self::$FONT_BASEPATH = getenv('JPGRAPH_FONT_BASEPATH') ?
25
        getenv('JPGRAPH_FONT_BASEPATH') :
26 21
        dirname(__DIR__) . '/fonts/';
27
        // String names for font styles to be used in error messages
28 21
        $this->style_names = [
29 21
            FS_NORMAL     => 'normal',
30 21
            FS_BOLD       => 'bold',
31 21
            FS_ITALIC     => 'italic',
32 21
            FS_BOLDITALIC => 'bolditalic',
33
        ];
34
35
        // File names for available fonts
36 21
        $this->font_files = [
37 21
            FF_COURIER          => [
38 21
                FS_NORMAL     => 'cour.ttf',
39 21
                FS_BOLD       => 'courbd.ttf',
40 21
                FS_ITALIC     => 'couri.ttf',
41 21
                FS_BOLDITALIC => 'courbi.ttf',
42
            ],
43 21
            FF_GEORGIA          => [
44 21
                FS_NORMAL     => 'georgia.ttf',
45 21
                FS_BOLD       => 'georgiab.ttf',
46 21
                FS_ITALIC     => 'georgiai.ttf',
47 21
                FS_BOLDITALIC => '',
48
            ],
49 21
            FF_TREBUCHE         => [
50 21
                FS_NORMAL     => 'trebuc.ttf',
51 21
                FS_BOLD       => 'trebucbd.ttf',
52 21
                FS_ITALIC     => 'trebucit.ttf',
53 21
                FS_BOLDITALIC => 'trebucbi.ttf',
54
            ],
55 21
            FF_VERDANA          => [
56 21
                FS_NORMAL     => 'verdana.ttf',
57 21
                FS_BOLD       => 'verdanab.ttf',
58 21
                FS_ITALIC     => 'verdanai.ttf',
59 21
                FS_BOLDITALIC => '',
60
            ],
61 21
            FF_TIMES            => [
62 21
                FS_NORMAL     => 'times.ttf',
63 21
                FS_BOLD       => 'timesbd.ttf',
64 21
                FS_ITALIC     => 'timesi.ttf',
65 21
                FS_BOLDITALIC => 'timesbi.ttf',
66
            ],
67 21
            FF_COMIC            => [
68 21
                FS_NORMAL     => 'comic.ttf',
69 21
                FS_BOLD       => 'comicbd.ttf',
70 21
                FS_ITALIC     => '',
71 21
                FS_BOLDITALIC => '',
72
            ],
73
            /*FF_ARIAL => array(FS_NORMAL => 'arial.ttf',
74
            FS_BOLD => 'arialbd.ttf',
75
            FS_ITALIC => 'ariali.ttf',
76
            FS_BOLDITALIC => 'arialbi.ttf'),
77
             */
78 21
            FF_ARIAL            => [
79 21
                FS_NORMAL     => 'arial.ttf',
80 21
                FS_BOLD       => 'msttcorefonts/Arial_Black.ttf',
81 21
                FS_ITALIC     => 'ariali.ttf',
82 21
                FS_BOLDITALIC => 'arialbi.ttf',
83
            ],
84 21
            FF_VERA             => [
85 21
                FS_NORMAL     => 'Vera.ttf',
86 21
                FS_BOLD       => 'VeraBd.ttf',
87 21
                FS_ITALIC     => 'VeraIt.ttf',
88 21
                FS_BOLDITALIC => 'VeraBI.ttf',
89
            ],
90 21
            FF_VERAMONO         => [
91 21
                FS_NORMAL     => 'VeraMono.ttf',
92 21
                FS_BOLD       => 'VeraMoBd.ttf',
93 21
                FS_ITALIC     => 'VeraMoIt.ttf',
94 21
                FS_BOLDITALIC => 'VeraMoBI.ttf',
95
            ],
96 21
            FF_VERASERIF        => [
97 21
                FS_NORMAL     => 'VeraSe.ttf',
98 21
                FS_BOLD       => 'VeraSeBd.ttf',
99 21
                FS_ITALIC     => '',
100 21
                FS_BOLDITALIC => '',
101
            ],
102
103
            /* Chinese fonts */
104 21
            FF_SIMSUN           => [
105 21
                FS_NORMAL     => 'simsun.ttc',
106 21
                FS_BOLD       => 'simhei.ttf',
107 21
                FS_ITALIC     => '',
108 21
                FS_BOLDITALIC => '',
109
            ],
110 21
            FF_CHINESE          => [
111 21
                FS_NORMAL     => CHINESE_TTF_FONT,
112 21
                FS_BOLD       => '',
113 21
                FS_ITALIC     => '',
114 21
                FS_BOLDITALIC => '',
115
            ],
116 21
            FF_BIG5             => [
117 21
                FS_NORMAL     => CHINESE_TTF_FONT,
118 21
                FS_BOLD       => '',
119 21
                FS_ITALIC     => '',
120 21
                FS_BOLDITALIC => '',
121
            ],
122
123
            /* Japanese fonts */
124 21
            FF_MINCHO           => [
125 21
                FS_NORMAL     => MINCHO_TTF_FONT,
126 21
                FS_BOLD       => '',
127 21
                FS_ITALIC     => '',
128 21
                FS_BOLDITALIC => '',
129
            ],
130
131 21
            FF_PMINCHO          => [
132 21
                FS_NORMAL     => PMINCHO_TTF_FONT,
133 21
                FS_BOLD       => '',
134 21
                FS_ITALIC     => '',
135 21
                FS_BOLDITALIC => '',
136
            ],
137
138 21
            FF_GOTHIC           => [
139 21
                FS_NORMAL     => GOTHIC_TTF_FONT,
140 21
                FS_BOLD       => '',
141 21
                FS_ITALIC     => '',
142 21
                FS_BOLDITALIC => '',
143
            ],
144
145 21
            FF_PGOTHIC          => [
146 21
                FS_NORMAL     => PGOTHIC_TTF_FONT,
147 21
                FS_BOLD       => '',
148 21
                FS_ITALIC     => '',
149 21
                FS_BOLDITALIC => '',
150
            ],
151
152
            /* Hebrew fonts */
153 21
            FF_DAVID            => [
154 21
                FS_NORMAL     => 'DAVIDNEW.TTF',
155 21
                FS_BOLD       => '',
156 21
                FS_ITALIC     => '',
157 21
                FS_BOLDITALIC => '',
158
            ],
159
160 21
            FF_MIRIAM           => [
161 21
                FS_NORMAL     => 'MRIAMY.TTF',
162 21
                FS_BOLD       => '',
163 21
                FS_ITALIC     => '',
164 21
                FS_BOLDITALIC => '',
165
            ],
166
167 21
            FF_AHRON            => [
168 21
                FS_NORMAL     => 'ahronbd.ttf',
169 21
                FS_BOLD       => '',
170 21
                FS_ITALIC     => '',
171 21
                FS_BOLDITALIC => '',
172
            ],
173
174
            /* Misc fonts */
175 21
            FF_DIGITAL          => [
176 21
                FS_NORMAL     => 'DIGIRU__.TTF',
177 21
                FS_BOLD       => 'Digirtu_.ttf',
178 21
                FS_ITALIC     => 'Digir___.ttf',
179 21
                FS_BOLDITALIC => 'DIGIRT__.TTF',
180
            ],
181
182
            /* This is an experimental font for the speedometer development
183
            FF_SPEEDO =>    array(
184
            FS_NORMAL =>'Speedo.ttf',
185
            FS_BOLD =>'',
186
            FS_ITALIC =>'',
187
            FS_BOLDITALIC =>''
188
            ),
189
             */
190
191 21
            FF_COMPUTER         => [
192 21
                FS_NORMAL     => 'COMPUTER.TTF',
193 21
                FS_BOLD       => '',
194 21
                FS_ITALIC     => '',
195 21
                FS_BOLDITALIC => '',
196
            ],
197
198 21
            FF_CALCULATOR       => [
199 21
                FS_NORMAL     => 'Triad_xs.ttf',
200 21
                FS_BOLD       => '',
201 21
                FS_ITALIC     => '',
202 21
                FS_BOLDITALIC => '',
203
            ],
204
205
            /* Dejavu fonts */
206 21
            FF_DV_SANSSERIF     => [
207 21
                FS_NORMAL     => ['DejaVuSans.ttf'],
208 21
                FS_BOLD       => ['DejaVuSans-Bold.ttf', 'DejaVuSansBold.ttf'],
209 21
                FS_ITALIC     => ['DejaVuSans-Oblique.ttf', 'DejaVuSansOblique.ttf'],
210 21
                FS_BOLDITALIC => ['DejaVuSans-BoldOblique.ttf', 'DejaVuSansBoldOblique.ttf'],
211
            ],
212
213 21
            FF_DV_SANSSERIFMONO => [
214 21
                FS_NORMAL     => ['DejaVuSansMono.ttf', 'DejaVuMonoSans.ttf'],
215 21
                FS_BOLD       => ['DejaVuSansMono-Bold.ttf', 'DejaVuMonoSansBold.ttf'],
216 21
                FS_ITALIC     => ['DejaVuSansMono-Oblique.ttf', 'DejaVuMonoSansOblique.ttf'],
217 21
                FS_BOLDITALIC => ['DejaVuSansMono-BoldOblique.ttf', 'DejaVuMonoSansBoldOblique.ttf'],
218
            ],
219
220 21
            FF_DV_SANSSERIFCOND => [
221 21
                FS_NORMAL     => ['DejaVuSansCondensed.ttf', 'DejaVuCondensedSans.ttf'],
222 21
                FS_BOLD       => ['DejaVuSansCondensed-Bold.ttf', 'DejaVuCondensedSansBold.ttf'],
223 21
                FS_ITALIC     => ['DejaVuSansCondensed-Oblique.ttf', 'DejaVuCondensedSansOblique.ttf'],
224 21
                FS_BOLDITALIC => ['DejaVuSansCondensed-BoldOblique.ttf', 'DejaVuCondensedSansBoldOblique.ttf'],
225
            ],
226
227 21
            FF_DV_SERIF         => [
228 21
                FS_NORMAL     => ['DejaVuSerif.ttf'],
229 21
                FS_BOLD       => ['DejaVuSerif-Bold.ttf', 'DejaVuSerifBold.ttf'],
230 21
                FS_ITALIC     => ['DejaVuSerif-Italic.ttf', 'DejaVuSerifItalic.ttf'],
231 21
                FS_BOLDITALIC => ['DejaVuSerif-BoldItalic.ttf', 'DejaVuSerifBoldItalic.ttf'],
232
            ],
233
234 21
            FF_DV_SERIFCOND     => [
235 21
                FS_NORMAL     => ['DejaVuSerifCondensed.ttf', 'DejaVuCondensedSerif.ttf'],
236 21
                FS_BOLD       => ['DejaVuSerifCondensed-Bold.ttf', 'DejaVuCondensedSerifBold.ttf'],
237 21
                FS_ITALIC     => ['DejaVuSerifCondensed-Italic.ttf', 'DejaVuCondensedSerifItalic.ttf'],
238 21
                FS_BOLDITALIC => ['DejaVuSerifCondensed-BoldItalic.ttf', 'DejaVuCondensedSerifBoldItalic.ttf'],
239
            ],
240
241
            /* Placeholders for defined fonts */
242 21
            FF_USERFONT1        => [
243 21
                FS_NORMAL     => '',
244 21
                FS_BOLD       => '',
245 21
                FS_ITALIC     => '',
246 21
                FS_BOLDITALIC => '',
247
            ],
248
249 21
            FF_USERFONT2        => [
250 21
                FS_NORMAL     => '',
251 21
                FS_BOLD       => '',
252 21
                FS_ITALIC     => '',
253 21
                FS_BOLDITALIC => '',
254
            ],
255
256 21
            FF_USERFONT3        => [
257 21
                FS_NORMAL     => '',
258 21
                FS_BOLD       => '',
259 21
                FS_ITALIC     => '',
260 21
                FS_BOLDITALIC => '',
261
            ],
262
        ];
263 21
    }
264
265
    /**
266
     * Encapsulates the logic to check for a file existance
267
     * If it exists and it's readable, return full path. Otherwise return false.
268
     *
269
     * @param <type> $file      The file
0 ignored issues
show
Documentation Bug introduced by
The doc comment <type> at position 0 could not be parsed: Unknown type name '<' at position 0 in <type>.
Loading history...
270
     * @param bool   $folder    The folder
271
     * @param mixed  $font_file
272
     * @param mixed  $font_path
273
     *
274
     * @return bool the full path if exists
275
     */
276 21
    private static function getFullPathIfExists($font_file, $font_path = '')
277
    {
278 21
        $full_path = sprintf('%s%s', $font_path, $font_file);
279
280 21
        if (file_exists($full_path) && is_readable($full_path)) {
281 21
            return $full_path;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $full_path returns the type string which is incompatible with the documented return type boolean.
Loading history...
282
        }
283
        // kdump('Not found: ' . $font_path);
284 21
        return false;
285
    }
286
287
    /**
288
     * Given a font family and a style, returns the full path to the font
289
     * Please check your DoxyDoxygen user configuration file.
290
     *
291
     * @param mixed  $family    font family (e.g. FF_COURIER, FF_VERDANA)
292
     * @param mixed  $style     optional font style, defaults to  FS_NORMAL
293
     * @param string $font_path optional font_path. If set, it takes precedence over other paths
294
     *
295
     * @example ` $ttf->File(FF_DV_SANSSERIF, FS_BOLD); // would return <self::LIBRARY ROOT>/self::src/fonts/DejaVuSans-Bold-ttf
296
     * ` */
297 21
    public function File($family, $style = FS_NORMAL, $font_path = null)
298
    {
299 21
        $fam = @$this->font_files[$family];
300 21
        if (!$fam) {
301
            Util\JpGraphError::RaiseL(25046, $family); //("Specified TTF font family (id=$family) is unknown or does not exist. Please note that TTF fonts are not distributed with JpGraph for copyright reasons. You can find the MS TTF WEB-fonts (arial, courier etc) for download at http://corefonts.sourceforge.net/");
302
        }
303 21
        $ff = @$fam[$style];
304
305
        // There are several optional file names. They are tried in order
306
        // and the first one found is used
307 21
        if (!is_array($ff)) {
308 14
            $ff = [$ff];
309
        }
310
311 21
        $jpgraph_font_dir = dirname(dirname(__FILE__)) . '/fonts/';
0 ignored issues
show
The assignment to $jpgraph_font_dir is dead and can be removed.
Loading history...
312
313 21
        foreach ($ff as $font_file) {
314
            // All font families are guaranteed to have the normal style
315
316 21
            if ($font_file === '') {
317
                Util\JpGraphError::RaiseL(25047, $this->style_names[$style], $this->font_files[$family][FS_NORMAL]);
318
            }
319
            //('Style "'.$this->style_names[$style].'" is not available for font family '.$this->font_files[$family][FS_NORMAL].'.');
320 21
            if (!$font_file) {
321
                Util\JpGraphError::RaiseL(25048, $fam); //("Unknown font style specification [$fam].");
322
            }
323
324 21
            if ($font_candidate = self::getFullPathIfExists($font_file, $font_path)) {
325
                $font_file = $font_candidate;
326
327
                break;
328
            }
329 21
            if ($font_candidate = self::getFullPathIfExists($font_file, self::$FONT_BASEPATH)) {
330 21
                $font_file = $font_candidate;
331
332 21
                break;
333
            }
334
335
            // check OS font dir
336 14
            if ($family >= FF_MINCHO && $family <= FF_PGOTHIC) {
337
                $font_file = MBTTF_DIR . $font_file;
338
            } else {
339 14
                $font_file = TTF_DIR . $font_file;
340
            }
341 14
            if (file_exists($font_file) === true && is_readable($font_file) === true) {
342 14
                break;
343
            }
344
        }
345
346 21
        if (!file_exists($font_file)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $font_file seems to be defined by a foreach iteration on line 313. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
347
            //Util\JpGraphError::RaiseL(25049, $font_file); //("Font file \"$font_file\" is not readable or does not exist.");
348 14
            return $this->File(FF_DV_SANSSERIF, $style);
349
        }
350
351 21
        return $font_file;
352
    }
353
354
    public function SetUserFont($aNormal, $aBold = '', $aItalic = '', $aBoldIt = '')
355
    {
356
        $this->font_files[FF_USERFONT] =
357
            [FS_NORMAL    => $aNormal,
358
            FS_BOLD       => $aBold,
359
            FS_ITALIC     => $aItalic,
360
            FS_BOLDITALIC => $aBoldIt,
361
        ];
362
    }
363
364
    public function SetUserFont1($aNormal, $aBold = '', $aItalic = '', $aBoldIt = '')
365
    {
366
        $this->font_files[FF_USERFONT1] =
367
            [FS_NORMAL    => $aNormal,
368
            FS_BOLD       => $aBold,
369
            FS_ITALIC     => $aItalic,
370
            FS_BOLDITALIC => $aBoldIt,
371
        ];
372
    }
373
374
    public function SetUserFont2($aNormal, $aBold = '', $aItalic = '', $aBoldIt = '')
375
    {
376
        $this->font_files[FF_USERFONT2] =
377
            [FS_NORMAL    => $aNormal,
378
            FS_BOLD       => $aBold,
379
            FS_ITALIC     => $aItalic,
380
            FS_BOLDITALIC => $aBoldIt,
381
        ];
382
    }
383
384
    public function SetUserFont3($aNormal, $aBold = '', $aItalic = '', $aBoldIt = '')
385
    {
386
        $this->font_files[FF_USERFONT3] =
387
            [FS_NORMAL    => $aNormal,
388
            FS_BOLD       => $aBold,
389
            FS_ITALIC     => $aItalic,
390
            FS_BOLDITALIC => $aBoldIt,
391
        ];
392
    }
393
} // @class
394