1<?php
2/*
3 * This work is hereby released into the Public Domain.
4 * To view a copy of the public domain dedication,
5 * visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
6 * Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
7 *
8 */
9
10
11/* <php4> */
12
13define("LABEL_LEFT", 1);
14define("LABEL_RIGHT", 2);
15define("LABEL_CENTER", 3);
16define("LABEL_TOP", 4);
17define("LABEL_BOTTOM", 5);
18define("LABEL_MIDDLE", 6);
19
20/* </php4> */
21
22/**
23 * Draw labels
24 *
25 * @package Artichow
26 */
27class awLabel implements awPositionable {
28
29	/**
30	 * Label border
31	 *
32	 * @var int
33	 */
34	public $border;
35
36	/**
37	 * Label texts
38	 *
39	 * @var array
40	 */
41	protected $texts;
42
43	/**
44	 * Text font
45	 *
46	 * @var int
47	 */
48	protected $font;
49
50	/**
51	 * Text angle
52	 *
53	 * @var int
54	 */
55	protected $angle = 0;
56
57	/**
58	 * Text color
59	 *
60	 * @var Color
61	 */
62	protected $color;
63
64	/**
65	 * Text background
66	 *
67	 * @var Color, Gradient
68	 */
69	private $background;
70
71	/**
72	 * Callback function
73	 *
74	 * @var string
75	 */
76	private $function;
77
78	/**
79	 * Callback function to format output
80	 *
81	 * @var string
82	 */
83	private $formatFunction;
84
85	/**
86	 * Padding
87	 *
88	 * @var int
89	 */
90	private $padding;
91
92	/**
93	 * Move position from this vector
94	 *
95	 * @var Point
96	 */
97	protected $move;
98
99	/**
100	 * Label interval
101	 *
102	 * @var int
103	 */
104	protected $interval = 1;
105
106	/**
107	 * Horizontal align
108	 *
109	 * @var int
110	 */
111	protected $hAlign = awLabel::CENTER;
112
113	/**
114	 * Vertical align
115	 *
116	 * @var int
117	 */
118	protected $vAlign = awLabel::MIDDLE;
119
120	/**
121	 * Hide all labels ?
122	 *
123	 * @var bool
124	 */
125	protected $hide = FALSE;
126
127	/**
128	 * Keys to hide
129	 *
130	 * @var array
131	 */
132	protected $hideKey = array();
133
134	/**
135	 * Values to hide
136	 *
137	 * @var array
138	 */
139	protected $hideValue = array();
140
141	/**
142	 * Hide first label
143	 *
144	 * @var bool
145	 */
146	protected $hideFirst = FALSE;
147
148	/**
149	 * Hide last label
150	 *
151	 * @var bool
152	 */
153	protected $hideLast = FALSE;
154
155	/**
156	 * Build the label
157	 *
158	 * @param string $label First label
159	 */
160	public function __construct($label = NULL, $font = NULL, $color = NULL, $angle = 0) {
161
162		if(is_array($label)) {
163			$this->set($label);
164		} else if(is_string($label)) {
165			$this->set(array($label));
166		}
167
168		if($font === NULL) {
169			$font = new awFont2;
170		}
171
172		$this->setFont($font);
173		$this->setAngle($angle);
174
175		if($color instanceof awColor) {
176			$this->setColor($color);
177		} else {
178			$this->setColor(new awColor(0, 0, 0));
179		}
180
181		$this->move = new awPoint(0, 0);
182
183		$this->border = new awBorder;
184		$this->border->hide();
185
186	}
187
188	/**
189	 * Get an element of the label from its key
190	 *
191	 * @param int $key Element key
192	 * @return string A value
193	 */
194	public function get($key) {
195		return array_key_exists($key, $this->texts) ? $this->texts[$key] : NULL;
196	}
197
198	/**
199	 * Get all labels
200	 *
201	 * @return array
202	 */
203	public function all() {
204		return $this->texts;
205	}
206
207	/**
208	 * Set one or several labels
209	 *
210	 * @param array $labels Array of string or a string
211	 */
212	public function set($labels) {
213
214		if(is_string($labels)) {
215			$this->texts = array($labels);
216		} else if(is_array($labels)) {
217			$this->texts = $labels;
218		}
219
220	}
221
222	/**
223	 * Count number of texts in the label
224	 *
225	 * @return int
226	 */
227	public function count() {
228		return is_array($this->texts) ? count($this->texts) : 0;
229	}
230
231	/**
232	 * Set a callback function for labels
233	 *
234	 * @param string $function
235	 */
236	public function setCallbackFunction($function) {
237		$this->function = is_null($function) ? $function : (string)$function;
238	}
239
240	/**
241	 * Return the callback function for labels
242	 *
243	 * @return string
244	 */
245	public function getCallbackFunction() {
246		return $this->function;
247	}
248
249	/**
250	 * Set a callback function to format the labels
251	 *
252	 * @param string $function
253	 */
254	public function setCallbackFormatFunction($function) {
255		$this->formatFunction =& $function;
256	}
257
258	/**
259	 * Change labels format
260	 *
261	 * @param string $format New format (printf style: %.2f for example)
262	 */
263	public function setFormat($format) {
264		$function = 'label'.time().'_'.(microtime() * 1000000);
265		eval('function '.$function.'($value) {
266			return sprintf("'.addcslashes($format, '"').'", $value);
267		}');
268		$this->setCallbackFunction($function);
269	}
270
271	/**
272	 * Change font for label
273	 *
274	 * @param awFont $font New font
275	 * @param awColor $color Font color (can be NULL)
276	 */
277	public function setFont(awFont $font, $color = NULL) {
278		$this->font = $font;
279		if($color instanceof awColor) {
280			$this->setColor($color);
281		}
282	}
283
284	/**
285	 * Change font angle
286	 *
287	 * @param int $angle New angle
288	 */
289	public function setAngle($angle) {
290		$this->angle = (int)$angle;
291	}
292
293	/**
294	 * Change font color
295	 *
296	 * @param awColor $color
297	 */
298	public function setColor($color) {
299		$this->color = $color;
300	}
301
302	/**
303	 * Change text background
304	 *
305	 * @param mixed $background
306	 */
307	public function setBackground($background) {
308		$this->background = $background;
309	}
310
311	/**
312	 * Change text background color
313	 *
314	 * @param Color
315	 */
316	public function setBackgroundColor(awColor $color) {
317		$this->background = $color;
318	}
319
320	/**
321	 * Change text background gradient
322	 *
323	 * @param Gradient
324	 */
325	public function setBackgroundGradient(awGradient $gradient) {
326		$this->background = $gradient;
327	}
328
329	/**
330	 * Change padding
331	 *
332	 * @param int $left Left padding
333	 * @param int $right Right padding
334	 * @param int $top Top padding
335	 * @param int $bottom Bottom padding
336	 */
337	public function setPadding($left, $right, $top, $bottom) {
338		$this->padding = array((int)$left, (int)$right, (int)$top, (int)$bottom);
339	}
340
341	/**
342	 * Hide all labels ?
343	 *
344	 * @param bool $hide
345	 */
346	public function hide($hide = TRUE) {
347		$this->hide = (bool)$hide;
348	}
349
350	/**
351	 * Show all labels ?
352	 *
353	 * @param bool $show
354	 */
355	public function show($show = TRUE) {
356		$this->hide = (bool)!$show;
357	}
358
359	/**
360	 * Hide a key
361	 *
362	 * @param int $key The key to hide
363	 */
364	public function hideKey($key) {
365		$this->hideKey[$key] = TRUE;
366	}
367
368	/**
369	 * Hide a value
370	 *
371	 * @param int $value The value to hide
372	 */
373	public function hideValue($value) {
374		$this->hideValue[] = $value;
375	}
376
377	/**
378	 * Hide first label
379	 *
380	 * @param bool $hide
381	 */
382	public function hideFirst($hide) {
383		$this->hideFirst = (bool)$hide;
384	}
385
386	/**
387	 * Hide last label
388	 *
389	 * @param bool $hide
390	 */
391	public function hideLast($hide) {
392		$this->hideLast = (bool)$hide;
393	}
394
395	/**
396	 * Set label interval
397	 *
398	 * @param int
399	 */
400	public function setInterval($interval) {
401
402		$this->interval = (int)$interval;
403
404	}
405
406	/**
407	 * Change label position
408	 *
409	 * @param int $x Add this interval to X coord
410	 * @param int $y Add this interval to Y coord
411	 */
412	public function move($x, $y) {
413
414		$this->move = $this->move->move($x, $y);
415
416	}
417
418	/**
419	 * Change alignment
420	 *
421	 * @param int $h Horizontal alignment
422	 * @param int $v Vertical alignment
423	 */
424	public function setAlign($h = NULL, $v = NULL) {
425		if($h !== NULL) {
426			$this->hAlign = (int)$h;
427		}
428		if($v !== NULL) {
429			$this->vAlign = (int)$v;
430		}
431	}
432
433	/**
434	 * Get a text from the labele
435	 *
436	 * @param mixed $key Key in the array text
437	 * @return Text
438	 */
439	public function getText($key) {
440
441		if(is_array($this->texts) and array_key_exists($key, $this->texts)) {
442
443			$value = $this->texts[$key];
444
445			if(is_string($this->function)) {
446				$value = call_user_func($this->function, $value);
447			}
448			if(!is_null($this->formatFunction)) {
449				$value = call_user_func($this->formatFunction, $value);
450			}
451
452			$text = new awText($value);
453			$text->setFont($this->font);
454			$text->setAngle($this->angle);
455			$text->setColor($this->color);
456
457			if($this->background instanceof awColor) {
458				$text->setBackgroundColor($this->background);
459			} else if($this->background instanceof awGradient) {
460				$text->setBackgroundGradient($this->background);
461			}
462
463			$text->border = $this->border;
464
465			if($this->padding !== NULL) {
466				call_user_func_array(array(&$text, 'setPadding'), $this->padding);
467			}
468
469			return $text;
470
471		} else {
472			return NULL;
473		}
474
475	}
476
477	/**
478	 * Get max width of all texts
479	 *
480	 * @param awDrawer $drawer A drawer
481	 * @return int
482	 */
483	public function getMaxWidth(awDrawer $drawer) {
484
485		return $this->getMax($drawer, 'getTextWidth');
486
487	}
488
489	/**
490	 * Get max height of all texts
491	 *
492	 * @param awDrawer $drawer A drawer
493	 * @return int
494	 */
495	public function getMaxHeight(awDrawer $drawer) {
496
497		return $this->getMax($drawer, 'getTextHeight');
498
499	}
500
501	/**
502	 * Draw the label
503	 *
504	 * @param awDrawer $drawer
505	 * @param awPoint $p Label center
506	 * @param int $key Text position in the array of texts (default to zero)
507	 */
508	public function draw(awDrawer $drawer, awPoint $p, $key = 0) {
509
510		if(($key % $this->interval) !== 0) {
511			return;
512		}
513
514		// Hide all labels
515		if($this->hide) {
516			return;
517		}
518
519		// Key is hidden
520		if(array_key_exists($key, $this->hideKey)) {
521			return;
522		}
523
524		// Hide first label
525		if($key === 0 and $this->hideFirst) {
526			return;
527		}
528
529		// Hide last label
530		if($key === count($this->texts) - 1 and $this->hideLast) {
531			return;
532		}
533
534		$text = $this->getText($key);
535
536		if($text !== NULL) {
537
538			// Value must be hidden
539			if(in_array($text->getText(), $this->hideValue)) {
540				return;
541			}
542
543			$x = $p->x;
544			$y = $p->y;
545
546			// Get padding
547			list($left, $right, $top, $bottom) = $text->getPadding();
548
549			$font = $text->getFont();
550			$width = $font->getTextWidth($text);
551			$height = $font->getTextHeight($text);
552
553			switch($this->hAlign) {
554
555				case awLabel::RIGHT :
556					$x -= ($width + $right);
557					break;
558
559				case awLabel::CENTER :
560					$x -= ($width - $left + $right) / 2;
561					break;
562
563				case awLabel::LEFT :
564					$x += $left;
565					break;
566
567			}
568
569			switch($this->vAlign) {
570
571				case awLabel::TOP :
572					$y -= ($height + $bottom);
573					break;
574
575				case awLabel::MIDDLE :
576					$y -= ($height - $top + $bottom) / 2;
577					break;
578
579				case awLabel::BOTTOM :
580					$y += $top;
581					break;
582
583			}
584
585			$drawer->string($text, $this->move->move($x, $y));
586
587		}
588
589	}
590
591	protected function getMax(awDrawer $drawer, $function) {
592
593		$max = NULL;
594
595		foreach($this->texts as $key => $text) {
596
597			$text = $this->getText($key);
598			$font = $text->getFont();
599
600			if(is_null($max)) {
601				$max = $font->{$function}($text);
602			} else {
603				$max = max($max, $font->{$function}($text));
604			}
605
606		}
607
608		return $max;
609
610	}
611
612}
613
614registerClass('Label');
615?>