1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* JPGraph v4.0.3 |
5
|
|
|
*/ |
6
|
|
|
|
7
|
|
|
namespace Amenadiel\JpGraph\Text; |
8
|
|
|
|
9
|
|
|
//use Amenadiel\JpGraph\Graph\Graph; |
10
|
|
|
use Amenadiel\JpGraph\Util; |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* File: JPGRAPH_TEXT.INC.PHP |
14
|
|
|
* // Description: Class to handle text as object in the graph. |
15
|
|
|
* // The low level text layout engine is handled by the GD class |
16
|
|
|
* // Created: 2001-01-08 (Refactored to separate file 2008-08-01) |
17
|
|
|
* // Ver: $Id: jpgraph_text.inc.php 1844 2009-09-26 17:05:31Z ljp $ |
18
|
|
|
* // |
19
|
|
|
* // Copyright (c) Asial Corporation. All rights reserved. |
20
|
|
|
*/ |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* @class Text |
24
|
|
|
* // Description: Arbitrary text object that can be added to the graph |
25
|
|
|
*/ |
26
|
|
|
class Text //extends Graph |
27
|
|
|
{ |
28
|
|
|
public $t; |
29
|
|
|
public $x = 0; |
30
|
|
|
public $y = 0; |
31
|
|
|
public $halign = 'left'; |
32
|
|
|
public $valign = 'top'; |
33
|
|
|
public $color = [0, 0, 0]; |
34
|
|
|
public $hide = false; |
35
|
|
|
public $dir = 0; |
36
|
|
|
public $iScalePosY; |
37
|
|
|
public $iScalePosX; |
38
|
|
|
public $iWordwrap = 0; |
39
|
|
|
public $font_family = FF_DEFAULT; |
40
|
|
|
public $font_style = FS_NORMAL; // old. FF_FONT1 |
41
|
|
|
public $boxed = false; // Should the text be boxed |
42
|
|
|
protected $paragraph_align = 'left'; |
43
|
|
|
protected $icornerradius = 0; |
44
|
|
|
protected $ishadowwidth = 3; |
45
|
|
|
protected $fcolor = 'white'; |
46
|
|
|
protected $bcolor = 'black'; |
47
|
|
|
protected $shadow = false; |
48
|
|
|
protected $iCSIMarea = ''; |
49
|
|
|
protected $iCSIMalt = ''; |
50
|
|
|
protected $iCSIMtarget = ''; |
51
|
|
|
protected $iCSIMWinTarget = ''; |
52
|
|
|
private $iBoxType = 1; // Which variant of filled box around text we want |
53
|
|
|
|
54
|
|
|
// for __get, __set |
55
|
|
|
private $_margin; |
56
|
|
|
private $_font_size = 8; // old. 12 |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* CONSTRUCTOR. |
60
|
|
|
* |
61
|
|
|
* @param mixed $aTxt |
62
|
|
|
* @param mixed $aXAbsPos |
63
|
|
|
* @param mixed $aYAbsPos |
64
|
|
|
*/ |
65
|
|
|
// Create new text at absolute pixel coordinates |
66
|
21 |
|
public function __construct($aTxt = '', $aXAbsPos = 0, $aYAbsPos = 0) |
67
|
|
|
{ |
68
|
21 |
|
if (!is_string($aTxt)) { |
69
|
|
|
Util\JpGraphError::RaiseL(25050); //('First argument to Text::Text() must be s atring.'); |
70
|
|
|
} |
71
|
21 |
|
$this->t = $aTxt; |
72
|
21 |
|
$this->x = round($aXAbsPos); |
73
|
21 |
|
$this->y = round($aYAbsPos); |
74
|
21 |
|
$this->margin = 0; |
75
|
21 |
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* PUBLIC METHODS. |
79
|
|
|
* |
80
|
|
|
* @param mixed $aTxt |
81
|
|
|
*/ |
82
|
|
|
// Set the string in the text object |
83
|
19 |
|
public function Set($aTxt) |
84
|
|
|
{ |
85
|
19 |
|
$this->t = $aTxt; |
86
|
19 |
|
} |
87
|
|
|
|
88
|
|
|
// Alias for Pos() |
89
|
21 |
|
public function SetPos($aXAbsPos = 0, $aYAbsPos = 0, $aHAlign = 'left', $aVAlign = 'top') |
90
|
|
|
{ |
91
|
|
|
//$this->Pos($aXAbsPos,$aYAbsPos,$aHAlign,$aVAlign); |
92
|
21 |
|
$this->x = $aXAbsPos; |
93
|
21 |
|
$this->y = $aYAbsPos; |
94
|
21 |
|
$this->halign = $aHAlign; |
95
|
21 |
|
$this->valign = $aVAlign; |
96
|
21 |
|
} |
97
|
|
|
|
98
|
|
|
public function SetScalePos($aX, $aY) |
99
|
|
|
{ |
100
|
|
|
$this->iScalePosX = $aX; |
101
|
|
|
$this->iScalePosY = $aY; |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
// Specify alignment for the text |
105
|
21 |
|
public function Align($aHAlign, $aVAlign = 'top', $aParagraphAlign = '') |
106
|
|
|
{ |
107
|
21 |
|
$this->halign = $aHAlign; |
108
|
21 |
|
$this->valign = $aVAlign; |
109
|
21 |
|
if ($aParagraphAlign != '') { |
110
|
|
|
$this->paragraph_align = $aParagraphAlign; |
111
|
|
|
} |
112
|
21 |
|
} |
113
|
|
|
|
114
|
|
|
// Alias |
115
|
21 |
|
public function SetAlign($aHAlign, $aVAlign = 'top', $aParagraphAlign = '') |
116
|
|
|
{ |
117
|
21 |
|
$this->Align($aHAlign, $aVAlign, $aParagraphAlign); |
118
|
21 |
|
} |
119
|
|
|
|
120
|
|
|
// Specifies the alignment for a multi line text |
121
|
21 |
|
public function ParagraphAlign($aAlign) |
122
|
|
|
{ |
123
|
21 |
|
$this->paragraph_align = $aAlign; |
124
|
21 |
|
} |
125
|
|
|
|
126
|
|
|
// Specifies the alignment for a multi line text |
127
|
|
|
public function SetParagraphAlign($aAlign) |
128
|
|
|
{ |
129
|
|
|
$this->paragraph_align = $aAlign; |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
public function SetShadow($aShadowColor = 'gray', $aShadowWidth = 3) |
133
|
|
|
{ |
134
|
|
|
$this->ishadowwidth = $aShadowWidth; |
135
|
|
|
$this->shadow = $aShadowColor; |
136
|
|
|
$this->boxed = true; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
public function SetWordWrap($aCol) |
140
|
|
|
{ |
141
|
|
|
$this->iWordwrap = $aCol; |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
// Specify that the text should be boxed. fcolor=frame color, bcolor=border color, |
145
|
|
|
// $shadow=drop shadow should be added around the text. |
146
|
|
|
public function SetBox($aFrameColor = [255, 255, 255], $aBorderColor = [0, 0, 0], $aShadowColor = false, $aCornerRadius = 4, $aShadowWidth = 3) |
147
|
|
|
{ |
148
|
|
|
if ($aFrameColor === false) { |
149
|
|
|
$this->boxed = false; |
150
|
|
|
} else { |
151
|
|
|
$this->boxed = true; |
152
|
|
|
} |
153
|
|
|
$this->fcolor = $aFrameColor; |
154
|
|
|
$this->bcolor = $aBorderColor; |
155
|
|
|
// For backwards compatibility when shadow was just true or false |
156
|
|
|
if ($aShadowColor === true) { |
157
|
|
|
$aShadowColor = 'gray'; |
158
|
|
|
} |
159
|
|
|
$this->shadow = $aShadowColor; |
160
|
|
|
$this->icornerradius = $aCornerRadius; |
161
|
|
|
$this->ishadowwidth = $aShadowWidth; |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
public function SetBox2($aFrameColor = [255, 255, 255], $aBorderColor = [0, 0, 0], $aShadowColor = false, $aCornerRadius = 4, $aShadowWidth = 3) |
165
|
|
|
{ |
166
|
|
|
$this->iBoxType = 2; |
167
|
|
|
$this->SetBox($aFrameColor, $aBorderColor, $aShadowColor, $aCornerRadius, $aShadowWidth); |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
// Hide the text |
171
|
16 |
|
public function Hide($aHide = true) |
172
|
|
|
{ |
173
|
16 |
|
$this->hide = $aHide; |
174
|
16 |
|
} |
175
|
|
|
|
176
|
|
|
// This looks ugly since it's not a very orthogonal design |
177
|
|
|
// but I added this "inverse" of Hide() to harmonize |
178
|
|
|
// with some classes which I designed more recently (especially) |
179
|
|
|
// jpgraph_gantt |
180
|
|
|
public function Show($aShow = true) |
181
|
|
|
{ |
182
|
|
|
$this->hide = !$aShow; |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
// Specify font |
186
|
21 |
|
public function SetFont($aFamily, $aStyle = FS_NORMAL, $aSize = 10) |
187
|
|
|
{ |
188
|
21 |
|
$this->font_family = $aFamily; |
189
|
21 |
|
$this->font_style = $aStyle; |
190
|
21 |
|
$this->font_size = $aSize; |
191
|
21 |
|
} |
192
|
|
|
|
193
|
|
|
// Center the text between $left and $right coordinates |
194
|
21 |
|
public function Center($aLeft, $aRight, $aYAbsPos = false) |
195
|
|
|
{ |
196
|
21 |
|
$this->x = $aLeft + ($aRight - $aLeft) / 2; |
197
|
21 |
|
$this->halign = 'center'; |
198
|
21 |
|
if (is_numeric($aYAbsPos)) { |
199
|
21 |
|
$this->y = $aYAbsPos; |
200
|
|
|
} |
201
|
21 |
|
} |
202
|
|
|
|
203
|
|
|
// Set text color |
204
|
21 |
|
public function SetColor($aColor) |
205
|
|
|
{ |
206
|
21 |
|
$this->color = $aColor; |
207
|
21 |
|
} |
208
|
|
|
|
209
|
1 |
|
public function SetAngle($aAngle) |
210
|
|
|
{ |
211
|
1 |
|
$this->SetOrientation($aAngle); |
212
|
1 |
|
} |
213
|
|
|
|
214
|
|
|
// Orientation of text. Note only TTF fonts can have an arbitrary angle |
215
|
21 |
|
public function SetOrientation($aDirection = 0) |
216
|
|
|
{ |
217
|
21 |
|
if (is_numeric($aDirection)) { |
218
|
21 |
|
$this->dir = $aDirection; |
219
|
|
|
} elseif ($aDirection == 'h') { |
220
|
|
|
$this->dir = 0; |
221
|
|
|
} elseif ($aDirection == 'v') { |
222
|
|
|
$this->dir = 90; |
223
|
|
|
} else { |
224
|
|
|
Util\JpGraphError::RaiseL(25051); |
225
|
|
|
} |
226
|
|
|
//(" Invalid direction specified for text."); |
227
|
21 |
|
} |
228
|
|
|
|
229
|
|
|
// Total width of text |
230
|
5 |
|
public function GetWidth($aImg) |
231
|
|
|
{ |
232
|
5 |
|
$aImg->SetFont($this->font_family, $this->font_style, $this->raw_font_size); |
233
|
5 |
|
$w = $aImg->GetTextWidth($this->t, $this->dir); |
234
|
|
|
|
235
|
5 |
|
return $w; |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
// Hight of font |
239
|
3 |
|
public function GetFontHeight($aImg) |
240
|
|
|
{ |
241
|
3 |
|
$aImg->SetFont($this->font_family, $this->font_style, $this->raw_font_size); |
242
|
3 |
|
$h = $aImg->GetFontHeight(); |
243
|
|
|
|
244
|
3 |
|
return $h; |
245
|
|
|
} |
246
|
|
|
|
247
|
21 |
|
public function GetTextHeight($aImg) |
248
|
|
|
{ |
249
|
21 |
|
$aImg->SetFont($this->font_family, $this->font_style, $this->raw_font_size); |
250
|
21 |
|
$h = $aImg->GetTextHeight($this->t, $this->dir); |
251
|
|
|
|
252
|
21 |
|
return $h; |
253
|
|
|
} |
254
|
|
|
|
255
|
|
|
public function GetHeight($aImg) |
256
|
|
|
{ |
257
|
|
|
// Synonym for GetTextHeight() |
258
|
|
|
$aImg->SetFont($this->font_family, $this->font_style, $this->raw_font_size); |
259
|
|
|
$h = $aImg->GetTextHeight($this->t, $this->dir); |
260
|
|
|
|
261
|
|
|
return $h; |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
// Set the margin which will be interpretated differently depending |
265
|
|
|
// on the context. |
266
|
21 |
|
public function SetMargin($aMarg) |
267
|
|
|
{ |
268
|
21 |
|
$this->margin = $aMarg; |
269
|
21 |
|
} |
270
|
|
|
|
271
|
1 |
|
public function StrokeWithScale($aImg, $axscale, $ayscale) |
272
|
|
|
{ |
273
|
1 |
|
if ($this->iScalePosX === null || $this->iScalePosY === null) { |
274
|
1 |
|
$this->Stroke($aImg); |
275
|
|
|
} else { |
276
|
|
|
$this->Stroke( |
277
|
|
|
$aImg, |
278
|
|
|
round($axscale->Translate($this->iScalePosX)), |
279
|
|
|
round($ayscale->Translate($this->iScalePosY)) |
280
|
|
|
); |
281
|
|
|
} |
282
|
1 |
|
} |
283
|
|
|
|
284
|
|
|
public function SetCSIMTarget($aURITarget, $aAlt = '', $aWinTarget = '') |
285
|
|
|
{ |
286
|
|
|
$this->iCSIMtarget = $aURITarget; |
287
|
|
|
$this->iCSIMalt = $aAlt; |
288
|
|
|
$this->iCSIMWinTarget = $aWinTarget; |
289
|
|
|
} |
290
|
|
|
|
291
|
|
|
public function GetCSIMareas() |
292
|
|
|
{ |
293
|
|
|
if ($this->iCSIMtarget !== '') { |
294
|
|
|
return $this->iCSIMarea; |
295
|
|
|
} |
296
|
|
|
|
297
|
|
|
return ''; |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
// Display text in image |
301
|
21 |
|
public function Stroke($aImg, $x = null, $y = null) |
302
|
|
|
{ |
303
|
21 |
|
if (is_numeric($x)) { |
304
|
21 |
|
$this->x = round($x); |
305
|
|
|
} |
306
|
|
|
|
307
|
21 |
|
if (is_numeric($y)) { |
308
|
21 |
|
$this->y = round($y); |
309
|
|
|
} |
310
|
|
|
|
311
|
|
|
// Insert newlines |
312
|
21 |
|
if ($this->iWordwrap > 0) { |
313
|
|
|
$this->t = wordwrap($this->t, $this->iWordwrap, "\n"); |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
// If position been given as a fraction of the image size |
317
|
|
|
// calculate the absolute position |
318
|
21 |
|
if ($this->x < 1 && $this->x > 0) { |
319
|
|
|
$this->x *= $aImg->width; |
320
|
|
|
} |
321
|
|
|
|
322
|
21 |
|
if ($this->y < 1 && $this->y > 0) { |
323
|
|
|
$this->y *= $aImg->height; |
324
|
|
|
} |
325
|
|
|
|
326
|
21 |
|
$aImg->PushColor($this->color); |
327
|
21 |
|
$aImg->SetFont($this->font_family, $this->font_style, $this->raw_font_size); |
328
|
21 |
|
$aImg->SetTextAlign($this->halign, $this->valign); |
329
|
|
|
|
330
|
21 |
|
if ($this->boxed) { |
331
|
|
|
if ($this->fcolor == 'nofill') { |
332
|
|
|
$this->fcolor = false; |
333
|
|
|
} |
334
|
|
|
|
335
|
|
|
$oldweight = $aImg->SetLineWeight(1); |
336
|
|
|
|
337
|
|
|
if ($this->iBoxType == 2 && $this->font_family > FF_FONT2 + 2) { |
338
|
|
|
$bbox = $aImg->StrokeBoxedText2( |
339
|
|
|
$this->x, |
340
|
|
|
$this->y, |
341
|
|
|
$this->t, |
342
|
|
|
$this->dir, |
343
|
|
|
$this->fcolor, |
344
|
|
|
$this->bcolor, |
345
|
|
|
$this->shadow, |
346
|
|
|
$this->paragraph_align, |
347
|
|
|
2, |
348
|
|
|
4, |
349
|
|
|
$this->icornerradius, |
350
|
|
|
$this->ishadowwidth |
351
|
|
|
); |
352
|
|
|
} else { |
353
|
|
|
$bbox = $aImg->StrokeBoxedText( |
354
|
|
|
$this->x, |
355
|
|
|
$this->y, |
356
|
|
|
$this->t, |
357
|
|
|
$this->dir, |
358
|
|
|
$this->fcolor, |
359
|
|
|
$this->bcolor, |
360
|
|
|
$this->shadow, |
361
|
|
|
$this->paragraph_align, |
362
|
|
|
3, |
363
|
|
|
3, |
364
|
|
|
$this->icornerradius, |
365
|
|
|
$this->ishadowwidth |
366
|
|
|
); |
367
|
|
|
} |
368
|
|
|
|
369
|
|
|
$aImg->SetLineWeight($oldweight); |
370
|
|
|
} else { |
371
|
21 |
|
$debug = false; |
372
|
21 |
|
$bbox = $aImg->StrokeText($this->x, $this->y, $this->t, $this->dir, $this->paragraph_align, $debug); |
373
|
|
|
} |
374
|
|
|
|
375
|
|
|
// Create CSIM targets |
376
|
21 |
|
$coords = implode(',', [ |
377
|
21 |
|
$bbox[0], $bbox[1], $bbox[2], $bbox[3], $bbox[4], $bbox[5], $bbox[6], $bbox[7], |
378
|
|
|
]); |
379
|
21 |
|
$this->iCSIMarea = "<area shape=\"poly\" coords=\"${coords}\" href=\""; |
380
|
21 |
|
$this->iCSIMarea .= htmlentities($this->iCSIMtarget) . '" '; |
381
|
21 |
|
if (trim($this->iCSIMalt) != '') { |
382
|
|
|
$this->iCSIMarea .= ' alt="' . $this->iCSIMalt . '" '; |
383
|
|
|
$this->iCSIMarea .= ' title="' . $this->iCSIMalt . '" '; |
384
|
|
|
} |
385
|
21 |
|
if (trim($this->iCSIMWinTarget) != '') { |
386
|
|
|
$this->iCSIMarea .= ' target="' . $this->iCSIMWinTarget . '" '; |
387
|
|
|
} |
388
|
21 |
|
$this->iCSIMarea .= " />\n"; |
389
|
|
|
|
390
|
21 |
|
$aImg->PopColor($this->color); |
391
|
21 |
|
} |
392
|
|
|
|
393
|
21 |
|
public function __get($name) |
394
|
|
|
{ |
395
|
21 |
|
if (strpos($name, 'raw_') !== false) { |
396
|
|
|
// if $name == 'raw_left_margin' , return $this->_left_margin; |
397
|
21 |
|
$variable_name = '_' . str_replace('raw_', '', $name); |
398
|
|
|
|
399
|
21 |
|
return $this->{$variable_name}; |
400
|
|
|
} |
401
|
|
|
|
402
|
21 |
|
$variable_name = '_' . $name; |
403
|
|
|
|
404
|
21 |
|
if (isset($this->{$variable_name})) { |
405
|
21 |
|
return $this->{$variable_name} * SUPERSAMPLING_SCALE; |
406
|
|
|
} |
407
|
|
|
Util\JpGraphError::RaiseL('25132', $name); |
408
|
|
|
} |
409
|
|
|
|
410
|
21 |
|
public function __set($name, $value) |
411
|
|
|
{ |
412
|
21 |
|
$this->{'_' . $name} = $value; |
413
|
21 |
|
} |
414
|
|
|
} // @class |
415
|
|
|
|