1<?php
2/***************************************************************************
3 *   copyright            : (C) 2005 by Pascal Brachet - France            *
4 *   pbrachet_NOSPAM_xm1math.net (replace _NOSPAM_ by @)                   *
5 *   http://www.xm1math.net/phpmathpublisher/                              *
6 *                                                                         *
7 *   This program 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.                                   *
11 *                                                                         *
12 ***************************************************************************/
13
14/********* HOW TO USE PHPMATHPUBLISHER ****************************
151) Fix the path to the fonts and the images directory (see PARAMETERS TO MODIFY below)
162) Include this script in your php page :
17include("mathpublisher.php") ;
183) Just call the mathfilter($text,$size,$pathtoimg) function in your php page.
19$text is the text with standard html tags and mathematical expressions (defined by the <m>...</m> tag).
20$size is the size of the police used for the formulas.
21$pathtoimg is the relative path between the html pages and the images directory.
22With a simple "echo mathfilter($text,$size,$pathtoimg);", you can display text with mathematical formulas.
23The mathfilter function will replace all the math tags (<m>formula</m>) in $text by <img src=the formula image >.
24Example :
25mathfilter("A math formula : <m>f(x)=sqrt{x}</m>,12,"img/") will return :
26"A math formula : <img src=\"img/math_988.5_903b2b36fc716cfb87ff76a65911a6f0.png\" style=\"vertical-align:-11.5px; display: inline-block ;\" alt=\"f(x)=sqrt{x}\" title=\"f(x)=sqrt{x}\">"
27The image corresponding to a formula is created only once. Then the image is stocked into the image directories.
28The first time that mathfilter is called, the images corresponding to the formulas are created, but the next times mathfilter will only return the html code.
29
30NOTE : if the free latex fonts furnished with this script don't work well (very tiny formulas - that's could happened with some GD configurations), you should try to use the bakoma versions of these fonts (downloadable here : http://www.ctan.org/tex-archive/fonts/cm/ps-type1/bakoma/ttf/ )
31*******************************************************************/
32
33//********* PARAMETERS TO MODIFY *********************************
34// The four global variables. Uncomment the line if you need it.
35global $dirfonts,$dirimg,$symboles,$fontesmath;
36
37// choose the type of the declaration according to your server settings (some servers don't accept the dirname(__FILE__) command for security reasons).
38
39// NEW in 0.3 version : no more / at the end of $dirfonts and $dirimg
40
41// absolute path to the fonts directory
42if (!isset($dirfonts)) $dirfonts=$_SERVER["DOCUMENT_ROOT"]."/phpmathpublisher/fonts";
43// or $dirfonts=dirname(__FILE__)."/phpmathpublisher/fonts";
44
45// absolute path to the images directory
46if (!isset($dirimg)) $dirimg=$_SERVER["DOCUMENT_ROOT"]."/phpmathpublisher/img";
47// or $dirfonts=dirname(__FILE__)."/phpmathpublisher/img";
48
49
50//******************************************************************
51$symboles = array(
52'~'=>' ',
53'alpha'=>'&#174;',
54'beta'=>'&#175;',
55'gamma'=>'&#176;',
56'delta'=>'&#177;',
57'epsilon'=>'&#178;',
58'varepsilon'=>'&#34;',
59'zeta'=>'&#179;',
60'eta'=>'&#180;',
61'theta'=>'&#181;',
62'vartheta'=>'&#35;',
63'iota'=>'&#182;',
64'kappa'=>'&#183;',
65'lambda'=>'&#184;',
66'mu'=>'&#185;',
67'nu'=>'&#186;',
68'xi'=>'&#187;',
69'pi'=>'&#188;',
70'varpi'=>'&#36;',
71'rho'=>'&#189;',
72'varrho'=>'&#37;',
73'sigma'=>'&#190;',
74'varsigma'=>'&#38;',
75'tau'=>'&#191;',
76'upsilon'=>'&#192;',
77'phi'=>'&#193;',
78'varphi'=>'&#39;',
79'chi'=>'&#194;',
80'psi'=>'&#195;',
81'omega'=>'&#33;',
82'Gamma'=>'&#161;',
83'Lambda'=>'&#164;',
84'Sigma'=>'&#167;',
85'Psi'=>'&#170;',
86'Delta'=>'&#162;',
87'Xi'=>'&#165;',
88'Upsilon'=>'&#168;',
89'Omega'=>'&#173;',
90'Theta'=>'&#163;',
91'Pi'=>'&#166;',
92'Phi'=>'&#169;',
93'infty'=>'&#8734;',
94'ne'=>'&#8800;',
95'*'=>'&#215;',
96'in'=>'&#8712;',
97'notin'=>'&#8713;',
98'forall'=>'&#8704;',
99'exists'=>'&#8707;',
100'notexists'=>'&#8708;',
101'partial'=>'&#8706;',
102'approx'=>'&#8776;',
103'left'=>'&#8592;',
104'right'=>'&#8594;',
105'leftright'=>'&#8596;',
106'doubleleft'=>'&#8656;',
107'doubleright'=>'&#8658;',
108'doubleleftright'=>'&#8660;',
109'nearrow'=>'&#8599;',
110'searrow'=>'&#8601;',
111'pm'=>'&#177;',
112'bbR'=>'&#8477;',
113'bbN'=>'&#8469;',
114'bbZ'=>'&#8484;',
115'bbC'=>'&#8450;',
116'inter'=>'&#8898;',
117'union'=>'&#8899;',
118'ortho'=>'&#8869;',
119'parallel'=>'&#8741;',
120'backslash'=>'&#92;',
121'prime'=>'&#39;',
122'wedge'=>'&#8896;',
123'vert'=>'&#8741;',
124'subset'=>'&#8834;',
125'notsubset'=>'&#8836;',
126'circ'=>'&#8728;',
127'varnothing'=>'&#248;',
128'cdots'=>'&#8943;',
129'vdots'=>'&#8942;',
130'ddots'=>'&#8945;',
131//operateurs
132'le'=>'&#54;',
133'ge'=>'&#62;',
134'<'=>'&#60;',
135'>'=>'&#62;',
136//parentheses
137'('=>'&#179;',
138')'=>'&#180;',
139'['=>'&#104;',
140']'=>'&#105;',
141'lbrace'=>'&#40;',
142'rbrace'=>'&#41;',
143//autres
144'_hat'=>'&#99;',
145'_racine'=>'&#113;',
146'_integrale'=>'&#82;',
147'_dintegrale'=>'&#8748;',
148'_tintegrale'=>'&#8749;',
149'_ointegrale'=>'&#72;',
150'_produit'=>'&#81;',
151'_somme'=>'&#80;',
152'_intersection'=>'&#84;',
153'_reunion'=>'&#83;',
154'_lim'=>'lim',
155//fonctions
156'arccos'=>'arccos',
157'ker'=>'ker',
158'arcsin'=>'arcsin',
159'lg'=>'lg',
160'arctan'=>'arctan',
161'arg'=>'arg',
162'cos'=>'cos',
163'cosh'=>'cosh',
164'ln'=>'ln',
165'cot'=>'cot',
166'log'=>'log',
167'coth'=>'coth',
168'max'=>'max',
169'csc'=>'csc',
170'min'=>'min',
171'deg'=>'deg',
172'det'=>'det',
173'sec'=>'sec',
174'dim'=>'dim',
175'sin'=>'sin',
176'exp'=>'exp',
177'sinh'=>'sinh',
178'gcd'=>'gcd',
179'sup'=>'sup',
180'hom'=>'hom',
181'tan'=>'tan',
182'inf'=>'inf',
183'tanh'=>'tanh'
184);
185$fontesmath = array(
186'~'=>'FreeSerif',
187'alpha'=>'cmmi10',
188'beta'=>'cmmi10',
189'gamma'=>'cmmi10',
190'delta'=>'cmmi10',
191'epsilon'=>'cmmi10',
192'varepsilon'=>'cmmi10',
193'zeta'=>'cmmi10',
194'eta'=>'cmmi10',
195'theta'=>'cmmi10',
196'vartheta'=>'cmmi10',
197'iota'=>'cmmi10',
198'kappa'=>'cmmi10',
199'lambda'=>'cmmi10',
200'mu'=>'cmmi10',
201'nu'=>'cmmi10',
202'xi'=>'cmmi10',
203'pi'=>'cmmi10',
204'varpi'=>'cmmi10',
205'rho'=>'cmmi10',
206'varrho'=>'cmmi10',
207'sigma'=>'cmmi10',
208'varsigma'=>'cmmi10',
209'tau'=>'cmmi10',
210'upsilon'=>'cmmi10',
211'phi'=>'cmmi10',
212'varphi'=>'cmmi10',
213'chi'=>'cmmi10',
214'psi'=>'cmmi10',
215'omega'=>'cmmi10',
216'Gamma'=>'cmr10',
217'Lambda'=>'cmr10',
218'Sigma'=>'cmr10',
219'Psi'=>'cmr10',
220'Delta'=>'cmr10',
221'Xi'=>'cmr10',
222'Upsilon'=>'cmr10',
223'Omega'=>'cmr10',
224'Theta'=>'cmr10',
225'Pi'=>'cmr10',
226'Phi'=>'cmr10',
227'infty'=>'FreeSerif',
228'ne'=>'FreeSerif',
229'*'=>'FreeSerif',
230'in'=>'FreeSerif',
231'notin'=>'FreeSerif',
232'forall'=>'FreeSerif',
233'exists'=>'FreeSerif',
234'notexists'=>'FreeSerif',
235'partial'=>'FreeSerif',
236'approx'=>'FreeSerif',
237'left'=>'FreeSerif',
238'right'=>'FreeSerif',
239'leftright'=>'FreeSerif',
240'doubleleft'=>'FreeSerif',
241'doubleright'=>'FreeSerif',
242'doubleleftright'=>'FreeSerif',
243'nearrow'=>'FreeSerif',
244'searrow'=>'FreeSerif',
245'pm'=>'FreeSerif',
246'bbR'=>'FreeSerif',
247'bbN'=>'FreeSerif',
248'bbZ'=>'FreeSerif',
249'bbC'=>'FreeSerif',
250'inter'=>'FreeSerif',
251'union'=>'FreeSerif',
252'ortho'=>'FreeSerif',
253'parallel'=>'FreeSerif',
254'backslash'=>'FreeSerif',
255'prime'=>'FreeSerif',
256'wedge'=>'FreeSerif',
257'vert'=>'FreeSerif',
258'subset'=>'FreeSerif',
259'notsubset'=>'FreeSerif',
260'circ'=>'FreeSerif',
261'varnothing'=>'FreeSerif',
262'cdots'=>'FreeSerif',
263'vdots'=>'FreeSerif',
264'ddots'=>'FreeSerif',
265//operateurs
266'le'=>'msam10',
267'ge'=>'msam10',
268'<'=>'cmmi10',
269'>'=>'cmmi10',
270//parentheses
271'('=>'cmex10',
272')'=>'cmex10',
273'['=>'cmex10',
274']'=>'cmex10',
275'lbrace'=>'cmex10',
276'rbrace'=>'cmex10',
277//autres
278'_hat'=>'cmex10',
279'_racine'=>'cmex10',
280'_integrale'=>'cmex10',
281'_dintegrale'=>'FreeSerif',
282'_tintegrale'=>'FreeSerif',
283'_ointegrale'=>'cmex10',
284'_produit'=>'cmex10',
285'_somme'=>'cmex10',
286'_intersection'=>'cmex10',
287'_reunion'=>'cmex10',
288'_lim'=>'cmr10',
289//fonctions
290'arccos'=>'cmr10',
291'ker'=>'cmr10',
292'arcsin'=>'cmr10',
293'lg'=>'cmr10',
294'arctan'=>'cmr10',
295'arg'=>'cmr10',
296'cos'=>'cmr10',
297'cosh'=>'cmr10',
298'ln'=>'cmr10',
299'cot'=>'cmr10',
300'log'=>'cmr10',
301'coth'=>'cmr10',
302'max'=>'cmr10',
303'csc'=>'cmr10',
304'min'=>'cmr10',
305'deg'=>'cmr10',
306'det'=>'cmr10',
307'sec'=>'cmr10',
308'dim'=>'cmr10',
309'sin'=>'cmr10',
310'exp'=>'cmr10',
311'sinh'=>'cmr10',
312'gcd'=>'cmr10',
313'sup'=>'cmr10',
314'hom'=>'cmr10',
315'tan'=>'cmr10',
316'inf'=>'cmr10',
317'tanh'=>'cmr10'
318);
319
320function est_nombre($str)
321{
322return ereg("^[0-9]", $str);
323}
324
325function tableau_expression($expression)
326{
327$e = str_replace('_', ' _ ', $expression);
328$e = str_replace('{(}', '{ }', $e);
329$e = str_replace('{)}', '{ }', $e);
330$t = token_get_all("<"."?php \$formula=$e ?".">");
331$extraits = array();
332$result=array();
333//stupid code but token_get_all bug in some php versions
334$d=0;
335for($i = 0; $i < count($t); $i++)
336	{
337	if(is_array($t[$i])) $t[$i] = $t[$i][1];
338	if (ereg("formula", $t[$i]))
339		{
340		$d=$i+2;
341		break;
342		}
343	}
344for($i = $d; $i < count($t) - 1; $i++)
345	{
346	if(is_array($t[$i])) $t[$i] = $t[$i][1];
347	if($t[$i] == '<=') $t[$i] = 'le';
348	elseif($t[$i] == '!=') $t[$i] = 'ne';
349	elseif($t[$i] == '<>') $t[$i] = 'ne';
350	elseif($t[$i] == '>=') $t[$i] = 'ge';
351	elseif($t[$i] == '--')
352		{
353		$t[$i] = '-';
354		$t[$i+1] = '-' . $t[$i+1];
355		}
356	elseif($t[$i] == '++') $t[$i] = '+';
357	elseif($t[$i] == '-')
358		{
359		if($t[$i - 1] == '^' || $t[$i - 1] == '_' || $t[$i - 1] == '*' || $t[$i - 1] == '/' || $t[$i - 1] == '+' || $t[$i - 1] == '(')
360			{
361			$t[$i] = '';
362			if(is_array($t[$i+1])) $t[$i+1][1] = '-' . $t[$i+1][1];
363            		else $t[$i+1] = '-' . $t[$i+1];
364			}
365		}
366	if(trim($t[$i]) != '') $extraits[] = $t[$i];
367	}
368for($i = 0; $i < count($extraits); $i++)
369	{
370	$result[]=new expression_texte($extraits[$i]);
371	}
372return $result;
373}
374
375
376// ugly hack, but GD is not very good with truetype fonts (especially with latex fonts)
377function affiche_symbol($texte,$haut)
378{
379global $symboles, $fontesmath, $dirfonts;
380$texte=trim(stripslashes($texte));
381switch($texte)
382	{
383	case '':
384	$img = ImageCreate(1, max($haut,1));
385	$blanc=ImageColorAllocate($img,255,255,255);
386	$blanc=imagecolortransparent($img,$blanc);
387	ImageFilledRectangle($img,0,0,1,$haut,$blanc);
388	break;
389	case '~':
390	$img = ImageCreate(1, max($haut,1));
391	$blanc=ImageColorAllocate($img,255,255,255);
392	$blanc=imagecolortransparent($img,$blanc);
393	ImageFilledRectangle($img,0,0,1,$haut,$blanc);
394	break;
395	case 'vert':
396	$img = ImageCreate(6, max($haut,1));
397	$blanc=ImageColorAllocate($img,255,255,255);
398	$blanc=imagecolortransparent($img,$blanc);
399	$noir=ImageColorAllocate($img,0,0,0);
400	ImageFilledRectangle($img,0,0,6,$haut,$blanc);
401	ImageFilledRectangle($img,2,0,2,$haut,$noir);
402	ImageFilledRectangle($img,4,0,4,$haut,$noir);
403	break;
404	case '|':
405	$img = ImageCreate(5, max($haut,1));
406	$blanc=ImageColorAllocate($img,255,255,255);
407	$blanc=imagecolortransparent($img,$blanc);
408	$noir=ImageColorAllocate($img,0,0,0);
409	ImageFilledRectangle($img,0,0,5,$haut,$blanc);
410	ImageFilledRectangle($img,2,0,2,$haut,$noir);
411	break;
412	case 'right':
413	$font =$dirfonts."/".$fontesmath[$texte].".ttf";
414	$t=16;
415	$texte = $symboles[$texte];
416	$tmp_dim = ImageTTFBBox($t, 0, $font , $texte);
417	$tmp_largeur = abs($tmp_dim[2] - $tmp_dim[0])+2;
418	$tmp_hauteur = abs($tmp_dim[3] - $tmp_dim[5])+2;
419	$tmp_img = ImageCreate(max($tmp_largeur,1), max($tmp_hauteur,1));
420	$tmp_noir=ImageColorAllocate($tmp_img,0,0,0);
421	$tmp_blanc=ImageColorAllocate($tmp_img,255,255,255);
422	$tmp_blanc=imagecolortransparent($tmp_img,$tmp_blanc);
423	ImageFilledRectangle($tmp_img,0,0,$tmp_largeur,$tmp_hauteur,$tmp_blanc);
424	ImageTTFText($tmp_img, $t, 0,0,$tmp_hauteur,$tmp_noir, $font,$texte);
425	$toutblanc=true;
426	$sx = $sy = $ex = $ey = -1;
427	for ($y = 0; $y < $tmp_hauteur; $y++)
428	{
429		for ($x = 0; $x < $tmp_largeur; $x++)
430		{
431			$rgb = ImageColorAt($tmp_img, $x, $y);
432			if ($rgb !=$tmp_blanc)
433			{
434				$toutblanc=false;
435				if ($sy == -1) $sy = $y;
436				else $ey = $y;
437
438				if ($sx == -1) $sx = $x;
439				else
440				{
441					if ($x < $sx) $sx = $x;
442					else if ($x > $ex) $ex = $x;
443				}
444			}
445		}
446	}
447	$nx = abs($ex - $sx);
448	$ny = abs($ey - $sy);
449	$img = ImageCreate(max($nx+4,1),max($ny+4,1));
450	$blanc=ImageColorAllocate($img,255,255,255);
451	$blanc=imagecolortransparent($img,$blanc);
452	ImageFilledRectangle($img,0,0,$nx+4,$ny+4,$blanc);
453	ImageCopy($img,$tmp_img,2,2,$sx,$sy,min($nx+2,$tmp_largeur-$sx),min($ny+2,$tmp_hauteur-$sy));
454	break;
455	case '_hat':
456	$font =$dirfonts."/".$fontesmath[$texte].".ttf";
457	$t=$haut;
458	$texte = $symboles[$texte];
459	$tmp_dim = ImageTTFBBox($t, 0, $font , $texte);
460	$tmp_largeur = abs($tmp_dim[2] - $tmp_dim[0]);
461	$tmp_hauteur = abs($tmp_dim[3] - $tmp_dim[5])*4;
462	$tmp_img = ImageCreate(max($tmp_largeur,1), max($tmp_hauteur,1));
463	$tmp_noir=ImageColorAllocate($tmp_img,0,0,0);
464	$tmp_blanc=ImageColorAllocate($tmp_img,255,255,255);
465	$tmp_blanc=imagecolortransparent($tmp_img,$tmp_blanc);
466	ImageFilledRectangle($tmp_img,0,0,$tmp_largeur,$tmp_hauteur,$tmp_blanc);
467	ImageTTFText($tmp_img, $t, 0,0,$tmp_hauteur,$tmp_noir, $font,$texte);
468	$toutblanc=true;
469	$img=$tmp_img;
470	$sx = $sy = $ex = $ey = -1;
471	for ($y = 0; $y < $tmp_hauteur; $y++)
472	{
473		for ($x = 0; $x < $tmp_largeur; $x++)
474		{
475			$rgb = ImageColorAt($tmp_img, $x, $y);
476			if ($rgb !=$tmp_blanc)
477			{
478				$toutblanc=false;
479				if ($sy == -1) $sy = $y;
480				else $ey = $y;
481
482				if ($sx == -1) $sx = $x;
483				else
484				{
485					if ($x < $sx) $sx = $x;
486					else if ($x > $ex) $ex = $x;
487				}
488			}
489		}
490	}
491	$nx = abs($ex - $sx);
492	$ny = abs($ey - $sy);
493	$img = ImageCreate(max($nx+4,1),max($ny+4,1));
494	$blanc=ImageColorAllocate($img,255,255,255);
495	$blanc=imagecolortransparent($img,$blanc);
496	ImageFilledRectangle($img,0,0,$nx+4,$ny+4,$blanc);
497	ImageCopy($img,$tmp_img,2,2,$sx,$sy,min($nx+2,$tmp_largeur-$sx),min($ny+2,$tmp_hauteur-$sy));
498	break;
499	case '_dintegrale':
500	case '_tintegrale':
501	if(isset($fontesmath[$texte])) $font = $dirfonts."/".$fontesmath[$texte].".ttf";
502	elseif (est_nombre($texte)) $font = $dirfonts."/cmr10.ttf";
503	else $font = $dirfonts."/cmmi10.ttf";
504	$t=6;
505	if(isset($symboles[$texte])) $texte = $symboles[$texte];
506	do
507		{
508		$tmp_dim = ImageTTFBBox($t, 0, $font , $texte);
509		$t+=1;
510		}
511	while ((abs($tmp_dim[3] - $tmp_dim[5])<1.2*$haut));
512	$tmp_largeur = abs($tmp_dim[2] - $tmp_dim[0])*2;
513	$tmp_hauteur = abs($tmp_dim[3] - $tmp_dim[5])*2;
514	$tmp_img = ImageCreate(max($tmp_largeur,1), max($tmp_hauteur,1));
515	$tmp_noir=ImageColorAllocate($tmp_img,0,0,0);
516	$tmp_blanc=ImageColorAllocate($tmp_img,255,255,255);
517	$tmp_blanc=imagecolortransparent($tmp_img,$tmp_blanc);
518	ImageFilledRectangle($tmp_img,0,0,$tmp_largeur,$tmp_hauteur,$tmp_blanc);
519	ImageTTFText($tmp_img, $t,0,5,$tmp_hauteur/2,$tmp_noir, $font,$texte);
520	$img=$tmp_img;
521	$toutblanc=true;
522	$sx = $sy = $ex = $ey = -1;
523	for ($y = 0; $y < $tmp_hauteur; $y++)
524	{
525		for ($x = 0; $x < $tmp_largeur; $x++)
526		{
527			$rgb = ImageColorAt($tmp_img, $x, $y);
528			if ($rgb !=$tmp_blanc)
529			{
530				$toutblanc=false;
531				if ($sy == -1) $sy = $y;
532				else $ey = $y;
533
534				if ($sx == -1) $sx = $x;
535				else
536				{
537					if ($x < $sx) $sx = $x;
538					else if ($x > $ex) $ex = $x;
539				}
540			}
541		}
542	}
543	$nx = abs($ex - $sx);
544	$ny = abs($ey - $sy);
545	if ($toutblanc)
546		{
547		$img = ImageCreate(1, max($haut,1));
548		$blanc=ImageColorAllocate($img,255,255,255);
549		$blanc=imagecolortransparent($img,$blanc);
550		ImageFilledRectangle($img,0,0,1,$haut,$blanc);
551		}
552	else
553		{
554		$img = ImageCreate(max($nx+4,1),max($ny+4,1));
555		$blanc=ImageColorAllocate($img,255,255,255);
556		$blanc=imagecolortransparent($img,$blanc);
557		ImageFilledRectangle($img,0,0,$nx+4,$ny+4,$blanc);
558		ImageCopy($img,$tmp_img,2,2,$sx,$sy,min($nx+2,$tmp_largeur-$sx),min($ny+2,$tmp_hauteur-$sy));
559		}
560	break;
561	default:
562	if(isset($fontesmath[$texte])) $font = $dirfonts."/".$fontesmath[$texte].".ttf";
563	elseif (est_nombre($texte)) $font = $dirfonts."/cmr10.ttf";
564	else $font = $dirfonts."/cmmi10.ttf";
565	$t=6;
566	if(isset($symboles[$texte])) $texte = $symboles[$texte];
567	do
568		{
569		$tmp_dim = ImageTTFBBox($t, 0, $font , $texte);
570		$t+=1;
571		}
572	while ((abs($tmp_dim[3] - $tmp_dim[5])<$haut));
573	$tmp_largeur = abs($tmp_dim[2] - $tmp_dim[0])*2;
574	$tmp_hauteur = abs($tmp_dim[3] - $tmp_dim[5])*2;
575	$tmp_img = ImageCreate(max($tmp_largeur,1), max($tmp_hauteur,1));
576	$tmp_noir=ImageColorAllocate($tmp_img,0,0,0);
577	$tmp_blanc=ImageColorAllocate($tmp_img,255,255,255);
578	$tmp_blanc=imagecolortransparent($tmp_img,$tmp_blanc);
579	ImageFilledRectangle($tmp_img,0,0,$tmp_largeur,$tmp_hauteur,$tmp_blanc);
580	ImageTTFText($tmp_img, $t, 0,0,$tmp_hauteur/4,$tmp_noir, $font,$texte);
581// 	ImageTTFText($tmp_img, $t, 0,5,5,$tmp_noir, $font,$texte);
582//	$img=$tmp_img;
583	$toutblanc=true;
584	$sx = $sy = $ex = $ey = -1;
585	for ($y = 0; $y < $tmp_hauteur; $y++)
586	{
587		for ($x = 0; $x < $tmp_largeur; $x++)
588		{
589			$rgb = ImageColorAt($tmp_img, $x, $y);
590			if ($rgb !=$tmp_blanc)
591			{
592				$toutblanc=false;
593				if ($sy == -1) $sy = $y;
594				else $ey = $y;
595
596				if ($sx == -1) $sx = $x;
597				else
598				{
599					if ($x < $sx) $sx = $x;
600					else if ($x > $ex) $ex = $x;
601				}
602			}
603		}
604	}
605	$nx = abs($ex - $sx);
606	$ny = abs($ey - $sy);
607	if ($toutblanc)
608		{
609		$img = ImageCreate(1, max($haut,1));
610		$blanc=ImageColorAllocate($img,255,255,255);
611		$blanc=imagecolortransparent($img,$blanc);
612		ImageFilledRectangle($img,0,0,1,$haut,$blanc);
613		}
614	else
615		{
616		$img = ImageCreate(max($nx+4,1),max($ny+4,1));
617		$blanc=ImageColorAllocate($img,255,255,255);
618		$blanc=imagecolortransparent($img,$blanc);
619		ImageFilledRectangle($img,0,0,$nx+4,$ny+4,$blanc);
620		ImageCopy($img,$tmp_img,2,2,$sx,$sy,min($nx+2,$tmp_largeur-$sx),min($ny+2,$tmp_hauteur-$sy));
621		}
622	break;
623	}
624//$rouge=ImageColorAllocate($img,255,0,0);
625//ImageRectangle($img,0,0,ImageSX($img)-1,ImageSY($img)-1,$rouge);
626return $img;
627}
628
629function affiche_texte($texte, $taille)
630{
631global $dirfonts;
632$taille=max($taille,6);
633$texte=stripslashes($texte);
634$font = $dirfonts."/cmr10.ttf";
635$htexte = 'dg'.$texte;
636$hdim = ImageTTFBBox($taille, 0, $font, $htexte);
637$wdim = ImageTTFBBox($taille, 0, $font, $texte);
638$dx = max($wdim[2], $wdim[4]) - min($wdim[0], $wdim[6])+ceil($taille /8);
639$dy = max($hdim[1], $hdim[3]) - min($hdim[5], $hdim[7])+ ceil($taille /8);
640$img = ImageCreate(max($dx,1), max($dy,1));
641$noir=ImageColorAllocate($img,0,0,0);
642$blanc=ImageColorAllocate($img,255,255,255);
643$blanc=imagecolortransparent($img,$blanc);
644ImageFilledRectangle($img,0,0,$dx,$dy,$blanc);
645//ImageRectangle($img,0,0,$dx-1,$dy-1,$noir);
646ImageTTFText($img, $taille, $angle, 0, -min($hdim[5], $hdim[7]), $noir, $font, $texte);
647return $img;
648}
649
650function affiche_math($texte, $taille)
651{
652global $dirfonts;
653$taille=max($taille,6);
654global $symboles, $fontesmath;
655$texte=stripslashes($texte);
656if(isset($fontesmath[$texte])) $font = $dirfonts."/".$fontesmath[$texte].".ttf";
657elseif (ereg("[a-zA-Z]", $texte)) $font = $dirfonts."/FreeSerifItalic.ttf";
658else $font = $dirfonts."/FreeSerif.ttf";
659if(isset($symboles[$texte])) $texte = $symboles[$texte];
660$htexte = 'dg'.$texte;
661$hdim = ImageTTFBBox($taille, 0, $font, $htexte);
662$wdim = ImageTTFBBox($taille, 0, $font, $texte);
663$dx = max($wdim[2], $wdim[4]) - min($wdim[0], $wdim[6])+ceil($taille /8);
664$dy = max($hdim[1], $hdim[3]) - min($hdim[5], $hdim[7])+ ceil($taille /8);
665$img = ImageCreate(max($dx,1), max($dy,1));
666$noir=ImageColorAllocate($img,0,0,0);
667$blanc=ImageColorAllocate($img,255,255,255);
668$blanc=imagecolortransparent($img,$blanc);
669ImageFilledRectangle($img,0,0,$dx,$dy,$blanc);
670//ImageRectangle($img,0,0,$dx-1,$dy-1,$noir);
671ImageTTFText($img, $taille, 0, 0, -min($hdim[5], $hdim[7]), $noir, $font, $texte);
672return $img;
673}
674
675function parenthese($hauteur, $style)
676{
677$image=affiche_symbol($style,$hauteur);
678return $image;
679}
680
681function alignement2($image1,$base1,$image2,$base2)
682{
683$largeur1=imagesx($image1);
684$hauteur1=imagesy($image1);
685$largeur2=imagesx($image2);
686$hauteur2=imagesy($image2);
687$dessus=max($base1,$base2);
688$dessous=max($hauteur1-$base1,$hauteur2-$base2);
689$largeur=$largeur1+$largeur2;
690$hauteur=$dessus+$dessous;
691$result = ImageCreate(max($largeur,1), max($hauteur,1));
692$noir=ImageColorAllocate($result,0,0,0);
693$blanc=ImageColorAllocate($result,255,255,255);
694$blanc=imagecolortransparent($result,$blanc);
695ImageFilledRectangle($result,0,0,$largeur-1,$hauteur-1,$blanc);
696ImageCopy($result, $image1,0,$dessus - $base1, 0, 0,$largeur1,$hauteur1);
697ImageCopy($result, $image2,$largeur1,$dessus - $base2, 0, 0,$largeur2,$hauteur2);
698//ImageRectangle($result,0,0,$largeur-1,$hauteur-1,$noir);
699return $result;
700}
701
702function alignement3($image1,$base1,$image2,$base2,$image3,$base3)
703{
704$largeur1=imagesx($image1);
705$hauteur1=imagesy($image1);
706$largeur2=imagesx($image2);
707$hauteur2=imagesy($image2);
708$largeur3=imagesx($image3);
709$hauteur3=imagesy($image3);
710$dessus=max($base1,$base2,$base3);
711$dessous=max($hauteur1-$base1,$hauteur2-$base2,$hauteur3-$base3);
712$largeur=$largeur1+$largeur2+$largeur3;
713$hauteur=$dessus+$dessous;
714$result = ImageCreate(max($largeur,1), max($hauteur,1));
715$noir=ImageColorAllocate($result,0,0,0);
716$blanc=ImageColorAllocate($result,255,255,255);
717$blanc=imagecolortransparent($result,$blanc);
718ImageFilledRectangle($result,0,0,$largeur-1,$hauteur-1,$blanc);
719ImageCopy($result, $image1,0,$dessus - $base1, 0, 0,$largeur1,$hauteur1);
720ImageCopy($result, $image2,$largeur1,$dessus - $base2, 0, 0,$largeur2,$hauteur2);
721ImageCopy($result, $image3,$largeur1+$largeur2,$dessus - $base3, 0, 0,$largeur3,$hauteur3);
722//ImageRectangle($result,0,0,$largeur-1,$hauteur-1,$noir);
723return $result;
724}
725
726//*****************************************************************
727class expression
728{
729var $texte;
730var $image;
731var $base_verticale;
732}
733//*****************************************************************
734class expression_texte extends  expression
735{
736function expression_texte($exp)
737{
738$this->texte = $exp;
739}
740function dessine($taille)
741{
742$this->image = affiche_math($this->texte,$taille);
743$this->base_verticale = imagesy($this->image) / 2;
744}
745}
746//*****************************************************************
747class expression_math extends  expression
748{
749var $noeuds;
750function expression_math($exp)
751{
752$this->texte = "&$";
753$this->noeuds = $exp;
754$this->noeuds = $this->parse();
755}
756
757function parse()
758{
759if(count($this->noeuds) <= 3) return $this->noeuds;
760$ret = array();
761$parentheses = array();
762for($i = 0; $i < count($this->noeuds); $i++)
763	{
764	if($this->noeuds[$i]->texte == '(' || $this->noeuds[$i]->texte == '{') array_push($parentheses, $i);
765	elseif($this->noeuds[$i]->texte == ')' || $this->noeuds[$i]->texte == '}')
766		{
767		$pos = array_pop($parentheses);
768		if(count($parentheses) == 0)
769			{
770			$sub = array_slice($this->noeuds, $pos + 1, $i - $pos - 1);
771			if($this->noeuds[$i]->texte == ')')
772				{
773				$ret[] = new expression_math(array(new expression_texte("("), new expression_math($sub), new expression_texte(")")));
774				}
775			else $ret[] = new expression_math($sub);
776			}
777		}
778	elseif(count($parentheses) == 0) $ret[] = $this->noeuds[$i];
779	}
780$ret = $this->traite_fonction($ret, 'sqrt', 1);
781$ret = $this->traite_fonction($ret, 'vec', 1);
782$ret = $this->traite_fonction($ret, 'overline', 1);
783$ret = $this->traite_fonction($ret, 'underline', 1);
784$ret = $this->traite_fonction($ret, 'hat', 1);
785$ret = $this->traite_fonction($ret, 'int', 3);
786$ret = $this->traite_fonction($ret, 'doubleint', 3);
787$ret = $this->traite_fonction($ret, 'tripleint', 3);
788$ret = $this->traite_fonction($ret, 'oint', 3);
789$ret = $this->traite_fonction($ret, 'prod', 3);
790$ret = $this->traite_fonction($ret, 'sum', 3);
791$ret = $this->traite_fonction($ret, 'bigcup', 3);
792$ret = $this->traite_fonction($ret, 'bigcap', 3);
793$ret = $this->traite_fonction($ret, 'delim', 3);
794$ret = $this->traite_fonction($ret, 'lim', 2);
795$ret = $this->traite_fonction($ret, 'root', 2);
796$ret = $this->traite_fonction($ret, 'matrix', 3);
797$ret = $this->traite_fonction($ret, 'tabular', 3);
798
799$ret = $this->traite_operation($ret, '^');
800$ret = $this->traite_operation($ret, 'over');
801$ret = $this->traite_operation($ret, '_');
802$ret = $this->traite_operation($ret, 'under');
803$ret = $this->traite_operation($ret, '*');
804$ret = $this->traite_operation($ret, '/');
805$ret = $this->traite_operation($ret, '+');
806$ret = $this->traite_operation($ret, '-');
807return $ret;
808}
809
810function traite_operation($noeuds, $operation)
811{
812do
813	{
814	$change = false;
815	if(count($noeuds) <= 3) return $noeuds;
816	$ret = array();
817	for($i = 0; $i < count($noeuds); $i++)
818		{
819		if(!$change && $i < count($noeuds) - 2 && $noeuds[$i+1]->texte == $operation)
820			{
821			$ret[] = new expression_math(array($noeuds[$i], $noeuds[$i+1], $noeuds[$i+2]));
822			$i += 2;
823			$change = true;
824			}
825		else
826		$ret[] = $noeuds[$i];
827		}
828	$noeuds = $ret;
829	}
830while($change);
831return $ret;
832}
833
834function traite_fonction($noeuds, $fonction, $nbarg)
835{
836if(count($noeuds) <= $nbarg + 1) return $noeuds;
837$ret = array();
838for($i = 0; $i < count($noeuds); $i++)
839{
840if($i < count($noeuds) - $nbarg && $noeuds[$i]->texte == $fonction)
841{
842	$a = array();
843	for($j = $i; $j <= $i + $nbarg; $j++)
844	$a[] = $noeuds[$j];
845	$ret[] = new expression_math($a);
846	$i += $nbarg;
847}
848else
849	$ret[] = $noeuds[$i];
850}
851return $ret;
852}
853
854
855function dessine($taille)
856{
857switch(count($this->noeuds))
858{
859case 1:
860	$this->noeuds[0]->dessine($taille);
861	$this->image = $this->noeuds[0]->image;
862	$this->base_verticale = $this->noeuds[0]->base_verticale;
863	break;
864case 2:
865	switch($this->noeuds[0]->texte)
866		{
867		case 'sqrt':
868		$this->dessine_racine($taille);
869		break;
870		case 'vec':
871		$this->dessine_vecteur($taille);
872		break;
873		case 'overline':
874		$this->dessine_overline($taille);
875		break;
876		case 'underline':
877		$this->dessine_underline($taille);
878		break;
879		case 'hat':
880		$this->dessine_chapeau($taille);
881		break;
882		default:
883		$this->dessine_expression($taille);
884		break;
885		}
886	break;
887case 3:
888	if ($this->noeuds[0]->texte=="lim")
889		{
890		$this->dessine_limite($taille);
891		}
892	elseif ($this->noeuds[0]->texte=="root")
893		{
894		$this->dessine_root($taille);
895		}
896	else
897	{
898	switch($this->noeuds[1]->texte)
899		{
900		case '/':
901		$this->dessine_fraction($taille);
902		break;
903		case '^':
904		$this->dessine_exposant($taille);
905		break;
906		case 'over':
907		$this->dessine_dessus($taille);
908		break;
909		case '_':
910		$this->dessine_indice($taille);
911		break;
912		case 'under':
913		$this->dessine_dessous($taille);
914		break;
915		default:
916		$this->dessine_expression($taille);
917		break;
918		}
919	}
920	break;
921case 4:
922	switch($this->noeuds[0]->texte)
923		{
924		case 'int':
925		$this->dessine_grandoperateur($taille,'_integrale');
926		break;
927		case 'doubleint':
928		$this->dessine_grandoperateur($taille,'_dintegrale');
929		break;
930		case 'tripleint':
931		$this->dessine_grandoperateur($taille,'_tintegrale');
932		break;
933		case 'oint':
934		$this->dessine_grandoperateur($taille,'_ointegrale');
935		break;
936		case 'sum':
937		$this->dessine_grandoperateur($taille,'_somme');
938		break;
939		case 'prod':
940		$this->dessine_grandoperateur($taille,'_produit');
941		break;
942		case 'bigcap':
943		$this->dessine_grandoperateur($taille,'_intersection');
944		break;
945		case 'bigcup':
946		$this->dessine_grandoperateur($taille,'_reunion');
947		break;
948		case 'delim':
949		$this->dessine_delimiteur($taille);
950		break;
951		case 'matrix':
952		$this->dessine_matrice($taille);
953		break;
954		case 'tabular':
955		$this->dessine_tableau($taille);
956		break;
957		default:
958		$this->dessine_expression($taille);
959		break;
960		}
961	break;
962default:
963	$this->dessine_expression($taille);
964	break;
965}
966}
967
968function dessine_expression($taille)
969{
970$largeur=1;
971$hauteur=1;
972$dessus=1;
973$dessous=1;
974for($i = 0; $i < count($this->noeuds); $i++)
975	{
976	if ($this->noeuds[$i]->texte != '(' && $this->noeuds[$i]->texte != ')')
977		{
978		$this->noeuds[$i]->dessine($taille);
979		$img[$i] = $this->noeuds[$i]->image;
980		$base[$i] = $this->noeuds[$i]->base_verticale;
981		$dessus = max($base[$i], $dessus);
982		$dessous = max(imagesy($img[$i]) - $base[$i], $dessous);
983		}
984	}
985$hauteur=$dessus+$dessous;
986$paro=parenthese(max($dessus,$dessous)*2,"(");
987$parf=parenthese(max($dessus,$dessous)*2,")");
988for($i = 0; $i < count($this->noeuds); $i++)
989        {
990	if(!isset($img[$i]))
991		{
992		if ($this->noeuds[$i]->texte == "(") $img[$i] = $paro;
993		else $img[$i] = $parf;
994		$dessus=max(imagesy($img[$i])/2,$dessus);
995		$base[$i]=imagesy($img[$i])/2;
996		$dessous = max(imagesy($img[$i]) - $base[$i], $dessous);
997		$hauteur=max(imagesy($img[$i]),$hauteur);
998		}
999	$largeur+=imagesx($img[$i]);
1000       	}
1001$this->base_verticale = $dessus;
1002$result = ImageCreate(max($largeur,1), max($hauteur,1));
1003$noir=ImageColorAllocate($result,0,0,0);
1004$blanc=ImageColorAllocate($result,255,255,255);
1005$blanc=imagecolortransparent($result,$blanc);
1006ImageFilledRectangle($result,0,0,$largeur-1,$hauteur-1,$blanc);
1007$pos = 0;
1008for($i = 0; $i < count($img); $i++)
1009	{
1010	if(isset($img[$i]))
1011		{
1012		ImageCopy($result, $img[$i],$pos,$dessus-$base[$i], 0, 0,imagesx($img[$i]),imagesy($img[$i]));
1013		$pos += imagesx($img[$i]);
1014		}
1015	}
1016$this->image=$result;
1017}
1018
1019function dessine_fraction($taille)
1020{
1021$this->noeuds[0]->dessine($taille*0.9);
1022$img1=$this->noeuds[0]->image;
1023$base1=$this->noeuds[0]->base_verticale;
1024$this->noeuds[2]->dessine($taille*0.9);
1025$img2=$this->noeuds[2]->image;
1026$base2=$this->noeuds[2]->base_verticale;
1027$hauteur1=imagesy($img1);
1028$hauteur2=imagesy($img2);
1029$largeur1=imagesx($img1);
1030$largeur2=imagesx($img2);
1031$largeur = max($largeur1,$largeur2);
1032$hauteur = $hauteur1+$hauteur2+4;
1033$result = ImageCreate(max($largeur+5,1), max($hauteur,1));
1034$noir=ImageColorAllocate($result,0,0,0);
1035$blanc=ImageColorAllocate($result,255,255,255);
1036$blanc=imagecolortransparent($result,$blanc);
1037$this->base_verticale=$hauteur1+2;
1038ImageFilledRectangle($result,0,0,$largeur+4,$hauteur-1,$blanc);
1039ImageCopy($result, $img1, ($largeur - $largeur1)/2, 0, 0, 0,$largeur1,$hauteur1);
1040imageline($result, 0,$this->base_verticale, $largeur,$this->base_verticale, $noir);
1041ImageCopy($result, $img2, ($largeur - $largeur2)/2,$hauteur1+4, 0, 0,$largeur2,$hauteur2);
1042$this->image=$result;
1043}
1044
1045function dessine_exposant($taille)
1046{
1047$this->noeuds[0]->dessine($taille);
1048$img1=$this->noeuds[0]->image;
1049$base1=$this->noeuds[0]->base_verticale;
1050$this->noeuds[2]->dessine($taille*0.8);
1051$img2=$this->noeuds[2]->image;
1052$base2=$this->noeuds[2]->base_verticale;
1053$hauteur1=imagesy($img1);
1054$hauteur2=imagesy($img2);
1055$largeur1=imagesx($img1);
1056$largeur2=imagesx($img2);
1057$largeur =$largeur1 + $largeur2;
1058if ($hauteur1 >= $hauteur2)
1059	{
1060	$hauteur = ceil($hauteur2/2+$hauteur1);
1061	$this->base_verticale=$hauteur2/2+ $base1;
1062	$result = ImageCreate(max($largeur,1), max($hauteur,1));
1063	$noir=ImageColorAllocate($result,0,0,0);
1064	$blanc=ImageColorAllocate($result,255,255,255);
1065	$blanc=imagecolortransparent($result,$blanc);
1066	ImageFilledRectangle($result,0,0,$largeur-1,$hauteur-1,$blanc);
1067	ImageCopy($result, $img1, 0, ceil($hauteur2/2), 0, 0, $largeur1, $hauteur1);
1068	ImageCopy($result, $img2, $largeur1, 0, 0, 0, $largeur2,$hauteur2);
1069	}
1070else
1071	{
1072	$hauteur = ceil($hauteur1/2+$hauteur2);
1073	$this->base_verticale=$hauteur2-$base1+$hauteur1/2;
1074	$result = ImageCreate(max($largeur,1), max($hauteur,1));
1075	$noir=ImageColorAllocate($result,0,0,0);
1076	$blanc=ImageColorAllocate($result,255,255,255);
1077	$blanc=imagecolortransparent($result,$blanc);
1078	ImageFilledRectangle($result,0,0,$largeur-1,$hauteur-1,$blanc);
1079	ImageCopy($result, $img1, 0, ceil($hauteur2-$hauteur1/2), 0, 0, $largeur1, $hauteur1);
1080	ImageCopy($result, $img2, $largeur1, 0, 0, 0, $largeur2,$hauteur2);
1081	}
1082$this->image=$result;
1083}
1084
1085function dessine_indice($taille)
1086{
1087$this->noeuds[0]->dessine($taille);
1088$img1=$this->noeuds[0]->image;
1089$base1=$this->noeuds[0]->base_verticale;
1090$this->noeuds[2]->dessine($taille*0.8);
1091$img2=$this->noeuds[2]->image;
1092$base2=$this->noeuds[2]->base_verticale;
1093$hauteur1=imagesy($img1);
1094$hauteur2=imagesy($img2);
1095$largeur1=imagesx($img1);
1096$largeur2=imagesx($img2);
1097$largeur =$largeur1 + $largeur2;
1098if ($hauteur1 >= $hauteur2)
1099	{
1100	$hauteur = ceil($hauteur2/2+$hauteur1);
1101	$this->base_verticale=$base1;
1102	$result = ImageCreate(max($largeur,1), max($hauteur,1));
1103	$noir=ImageColorAllocate($result,0,0,0);
1104	$blanc=ImageColorAllocate($result,255,255,255);
1105	$blanc=imagecolortransparent($result,$blanc);
1106	ImageFilledRectangle($result,0,0,$largeur-1,$hauteur-1,$blanc);
1107	ImageCopy($result, $img1, 0, 0, 0, 0, $largeur1, $hauteur1);
1108	ImageCopy($result, $img2, $largeur1,ceil($hauteur1-$hauteur2/2) , 0, 0, $largeur2,$hauteur2);
1109	}
1110else
1111	{
1112	$hauteur = ceil($hauteur1/2+$hauteur2);
1113	$this->base_verticale=$base1;
1114	$result = ImageCreate(max($largeur,1), max($hauteur,1));
1115	$noir=ImageColorAllocate($result,0,0,0);
1116	$blanc=ImageColorAllocate($result,255,255,255);
1117	$blanc=imagecolortransparent($result,$blanc);
1118	ImageFilledRectangle($result,0,0,$largeur-1,$hauteur-1,$blanc);
1119	ImageCopy($result, $img1, 0, 0, 0, 0, $largeur1, $hauteur1);
1120	ImageCopy($result, $img2, $largeur1,ceil($hauteur1/2), 0, 0, $largeur2,$hauteur2);
1121	}
1122$this->image=$result;
1123}
1124
1125function dessine_racine($taille)
1126{
1127$this->noeuds[1]->dessine($taille);
1128$imgexp=$this->noeuds[1]->image;
1129$baseexp=$this->noeuds[1]->base_verticale;
1130$largeurexp=imagesx($imgexp);
1131$hauteurexp=imagesy($imgexp);
1132
1133$imgrac=affiche_symbol("_racine",$hauteurexp+2);
1134$largeurrac=imagesx($imgrac);
1135$hauteurrac=imagesy($imgrac);
1136$baserac=$hauteurrac/2;
1137
1138$largeur=$largeurrac+$largeurexp;
1139$hauteur=max($hauteurexp,$hauteurrac);
1140$result = ImageCreate(max($largeur,1), max($hauteur,1));
1141$noir=ImageColorAllocate($result,0,0,0);
1142$blanc=ImageColorAllocate($result,255,255,255);
1143$blanc=imagecolortransparent($result,$blanc);
1144ImageFilledRectangle($result,0,0,$largeur-1,$hauteur-1,$blanc);
1145ImageCopy($result, $imgrac,0,0, 0, 0,$largeurrac,$hauteurrac);
1146ImageCopy($result, $imgexp,$largeurrac,$hauteur-$hauteurexp, 0, 0,$largeurexp,$hauteurexp);
1147imagesetthickness($result,1);
1148imageline($result, $largeurrac-2,2, $largeurrac+$largeurexp+2,2, $noir);
1149$this->base_verticale=$hauteur-$hauteurexp+$baseexp;
1150$this->image=$result;
1151}
1152
1153function dessine_root($taille)
1154{
1155$this->noeuds[1]->dessine($taille*0.6);
1156$imgroot=$this->noeuds[1]->image;
1157$baseroot=$this->noeuds[1]->base_verticale;
1158$largeurroot=imagesx($imgroot);
1159$hauteurroot=imagesy($imgroot);
1160
1161$this->noeuds[2]->dessine($taille);
1162$imgexp=$this->noeuds[2]->image;
1163$baseexp=$this->noeuds[2]->base_verticale;
1164$largeurexp=imagesx($imgexp);
1165$hauteurexp=imagesy($imgexp);
1166
1167$imgrac=affiche_symbol("_racine",$hauteurexp+2);
1168$largeurrac=imagesx($imgrac);
1169$hauteurrac=imagesy($imgrac);
1170$baserac=$hauteurrac/2;
1171
1172//$largeur=$largeurrac+$largeurexp;
1173$netwidthroot = max($largeurroot-0.3*$hauteurrac,0);
1174$largeur=$largeurrac+$largeurexp+$netwidthroot;
1175$hauteur=max($hauteurexp,$hauteurrac);
1176$result = ImageCreate(max($largeur,1), max($hauteur,1));
1177$noir=ImageColorAllocate($result,0,0,0);
1178$blanc=ImageColorAllocate($result,255,255,255);
1179$blanc=imagecolortransparent($result,$blanc);
1180ImageFilledRectangle($result,0,0,$largeur-1,$hauteur-1,$blanc);
1181ImageCopy($result, $imgrac,$netwidthroot,0, 0, 0,$largeurrac,$hauteurrac);
1182ImageCopy($result, $imgexp,$largeurrac+$netwidthroot,$hauteur-$hauteurexp, 0, 0,$largeurexp,$hauteurexp);
1183imagesetthickness($result,1);
1184imageline($result, $largeurrac+$netwidthroot-2,2, $largeurrac+$netwidthroot+$largeurexp+2,2, $noir);
1185ImageCopy($result, $imgroot,0,0, 0, 0,$largeurroot,$hauteurroot);
1186$this->base_verticale=$hauteur-$hauteurexp+$baseexp;
1187$this->image=$result;
1188}
1189
1190function dessine_grandoperateur($taille,$caractere)
1191{
1192$this->noeuds[1]->dessine($taille*0.8);
1193$img1=$this->noeuds[1]->image;
1194$base1=$this->noeuds[1]->base_verticale;
1195$this->noeuds[2]->dessine($taille*0.8);
1196$img2=$this->noeuds[2]->image;
1197$base2=$this->noeuds[2]->base_verticale;
1198$this->noeuds[3]->dessine($taille);
1199$imgexp=$this->noeuds[3]->image;
1200$baseexp=$this->noeuds[3]->base_verticale;
1201//borneinf
1202$largeur1=imagesx($img1);
1203$hauteur1=imagesy($img1);
1204//bornesup
1205$largeur2=imagesx($img2);
1206$hauteur2=imagesy($img2);
1207//expression
1208$hauteurexp=imagesy($imgexp);
1209$largeurexp=imagesx($imgexp);
1210//caractere
1211$imgsymbole=affiche_symbol($caractere,$baseexp*1.8);//max($baseexp,$hauteurexp-$baseexp)*2);
1212$largeursymbole=imagesx($imgsymbole);
1213$hauteursymbole=imagesy($imgsymbole);
1214$basesymbole=$hauteursymbole/2;
1215
1216$hauteurgauche=$hauteursymbole+$hauteur1+$hauteur2;
1217$largeurgauche=max($largeursymbole,$largeur1,$largeur2);
1218$imggauche=ImageCreate(max($largeurgauche,1), max($hauteurgauche,1));
1219$noir=ImageColorAllocate($imggauche,0,0,0);
1220$blanc=ImageColorAllocate($imggauche,255,255,255);
1221$blanc=imagecolortransparent($imggauche,$blanc);
1222ImageFilledRectangle($imggauche,0,0,$largeurgauche-1,$hauteurgauche-1,$blanc);
1223ImageCopy($imggauche, $imgsymbole,($largeurgauche-$largeursymbole)/2, $hauteur2, 0, 0,$largeursymbole,$hauteursymbole);
1224ImageCopy($imggauche, $img2,($largeurgauche-$largeur2)/2,0, 0, 0,$largeur2,$hauteur2);
1225ImageCopy($imggauche, $img1,($largeurgauche-$largeur1)/2, $hauteur2+$hauteursymbole, 0, 0,$largeur1,$hauteur1);
1226$imgfin=alignement2($imggauche,$basesymbole+$hauteur2,$imgexp,$baseexp);
1227$this->image=$imgfin;
1228$this->base_verticale=max($basesymbole+$hauteur2,$baseexp+$hauteur2);
1229}
1230
1231function dessine_dessus($taille)
1232{
1233$this->noeuds[2]->dessine($taille*0.8);
1234$imgsup=$this->noeuds[2]->image;
1235$basesup=$this->noeuds[2]->base_verticale;
1236$this->noeuds[0]->dessine($taille);
1237$imgexp=$this->noeuds[0]->image;
1238$baseexp=$this->noeuds[0]->base_verticale;
1239//expression
1240$largeurexp=imagesx($imgexp);
1241$hauteurexp=imagesy($imgexp);
1242//bornesup
1243$largeursup=imagesx($imgsup);
1244$hauteursup=imagesy($imgsup);
1245//fin
1246$hauteur=$hauteurexp+$hauteursup;
1247$largeur=max($largeursup,$largeurexp)+ceil($taille/8);
1248$imgfin = ImageCreate(max($largeur,1), max($hauteur,1));
1249$noir=ImageColorAllocate($imgfin,0,0,0);
1250$blanc=ImageColorAllocate($imgfin,255,255,255);
1251$blanc=imagecolortransparent($imgfin,$blanc);
1252ImageFilledRectangle($imgfin,0,0,$largeur-1,$hauteur-1,$blanc);
1253ImageCopy($imgfin, $imgsup,($largeur-$largeursup)/2, 0, 0, 0,$largeursup,$hauteursup);
1254ImageCopy($imgfin, $imgexp,($largeur-$largeurexp)/2, $hauteursup, 0, 0,$largeurexp,$hauteurexp);
1255$this->image=$imgfin;
1256$this->base_verticale=$baseexp+$hauteursup;
1257}
1258
1259function dessine_dessous($taille)
1260{
1261$this->noeuds[2]->dessine($taille*0.8);
1262$imginf=$this->noeuds[2]->image;
1263$baseinf=$this->noeuds[2]->base_verticale;
1264$this->noeuds[0]->dessine($taille);
1265$imgexp=$this->noeuds[0]->image;
1266$baseexp=$this->noeuds[0]->base_verticale;
1267//expression
1268$largeurexp=imagesx($imgexp);
1269$hauteurexp=imagesy($imgexp);
1270//borneinf
1271$largeurinf=imagesx($imginf);
1272$hauteurinf=imagesy($imginf);
1273//fin
1274$hauteur=$hauteurexp+$hauteurinf;
1275$largeur=max($largeurinf,$largeurexp)+ceil($taille/8);
1276$imgfin = ImageCreate(max($largeur,1), max($hauteur,1));
1277$noir=ImageColorAllocate($imgfin,0,0,0);
1278$blanc=ImageColorAllocate($imgfin,255,255,255);
1279$blanc=imagecolortransparent($imgfin,$blanc);
1280ImageFilledRectangle($imgfin,0,0,$largeur-1,$hauteur-1,$blanc);
1281ImageCopy($imgfin, $imgexp,($largeur-$largeurexp)/2, 0, 0, 0,$largeurexp,$hauteurexp);
1282ImageCopy($imgfin, $imginf,($largeur-$largeurinf)/2, $hauteurexp, 0, 0,$largeurinf,$hauteurinf);
1283$this->image=$imgfin;
1284$this->base_verticale=$baseexp;
1285}
1286
1287function dessine_matrice($taille)
1288{
1289$padding=8;
1290$nbligne=$this->noeuds[1]->noeuds[0]->texte;
1291$nbcolonne=$this->noeuds[2]->noeuds[0]->texte;
1292$largeur_case=0;
1293$hauteur_case=0;
1294
1295for($ligne = 0; $ligne <$nbligne; $ligne++)
1296	{
1297	$hauteur_ligne[$ligne]=0;
1298	$dessus_ligne[$ligne]=0;
1299	}
1300for($col = 0; $col <$nbcolonne; $col++)
1301	{
1302	$largeur_colonne[$col]=0;
1303	}
1304$i=0;
1305for($ligne = 0; $ligne <$nbligne; $ligne++)
1306	{
1307	for($col = 0; $col <$nbcolonne; $col++)
1308		{
1309		if ($i< count($this->noeuds[3]->noeuds))
1310			{
1311			$this->noeuds[3]->noeuds[$i]->dessine($taille*0.9);
1312			$img[$i]=$this->noeuds[3]->noeuds[$i]->image;
1313			$base[$i]=$this->noeuds[3]->noeuds[$i]->base_verticale;
1314			$dessus_ligne[$ligne] = max($base[$i],$dessus_ligne[$ligne]);
1315			$largeur[$i]=imagesx($img[$i]);
1316			$hauteur[$i]=imagesy($img[$i]);
1317			$hauteur_ligne[$ligne]=max($hauteur_ligne[$ligne],$hauteur[$i]);
1318			$largeur_colonne[$col]=max($largeur_colonne[$col],$largeur[$i]);
1319			}
1320		$i++;
1321		}
1322 	}
1323
1324$hauteurfin=0;
1325$largeurfin=0;
1326for($ligne = 0; $ligne <$nbligne; $ligne++)
1327	{
1328	$hauteurfin+=$hauteur_ligne[$ligne]+$padding;
1329	}
1330for($col = 0; $col <$nbcolonne; $col++)
1331	{
1332	$largeurfin+=$largeur_colonne[$col]+$padding;
1333	}
1334$hauteurfin-=$padding;
1335$largeurfin-=$padding;
1336$imgfin = ImageCreate(max($largeurfin,1), max($hauteurfin,1));
1337$noir=ImageColorAllocate($imgfin,0,0,0);
1338$blanc=ImageColorAllocate($imgfin,255,255,255);
1339$blanc=imagecolortransparent($imgfin,$blanc);
1340ImageFilledRectangle($imgfin,0,0,$largeurfin-1,$hauteurfin-1,$blanc);
1341$i=0;
1342$h=$padding/2-1;
1343for($ligne = 0; $ligne <$nbligne; $ligne++)
1344	{
1345	$l=$padding/2-1;
1346	for($col = 0; $col <$nbcolonne; $col++)
1347		{
1348		if ($i< count($this->noeuds[3]->noeuds))
1349			{
1350			ImageCopy($imgfin,$img[$i],$l+ceil($largeur_colonne[$col]-$largeur[$i])/2,$h+$dessus_ligne[$ligne]-$base[$i], 0, 0,$largeur[$i],$hauteur[$i]);
1351			//ImageRectangle($imgfin,$l,$h,$l+$largeur_colonne[$col],$h+$hauteur_ligne[$ligne],$noir);
1352			}
1353		$l+=$largeur_colonne[$col]+$padding;
1354		$i++;
1355		}
1356	$h+=$hauteur_ligne[$ligne]+$padding;
1357 	}
1358//ImageRectangle($imgfin,0,0,$largeurfin-1,$hauteurfin-1,$noir);
1359$this->image=$imgfin;
1360$this->base_verticale=imagesy($imgfin)/2;
1361}
1362
1363function dessine_tableau($taille)
1364{
1365$padding=8;
1366$typeligne=$this->noeuds[1]->noeuds[0]->texte;
1367$typecolonne=$this->noeuds[2]->noeuds[0]->texte;
1368$nbligne=strlen($typeligne)-1;
1369$nbcolonne=strlen($typecolonne)-1;
1370$largeur_case=0;
1371$hauteur_case=0;
1372
1373for($ligne = 0; $ligne <$nbligne; $ligne++)
1374	{
1375	$hauteur_ligne[$ligne]=0;
1376	$dessus_ligne[$ligne]=0;
1377	}
1378for($col = 0; $col <$nbcolonne; $col++)
1379	{
1380	$largeur_colonne[$col]=0;
1381	}
1382$i=0;
1383for($ligne = 0; $ligne <$nbligne; $ligne++)
1384	{
1385	for($col = 0; $col <$nbcolonne; $col++)
1386		{
1387		if ($i< count($this->noeuds[3]->noeuds))
1388			{
1389			$this->noeuds[3]->noeuds[$i]->dessine($taille*0.9);
1390			$img[$i]=$this->noeuds[3]->noeuds[$i]->image;
1391			$base[$i]=$this->noeuds[3]->noeuds[$i]->base_verticale;
1392			$dessus_ligne[$ligne] = max($base[$i],$dessus_ligne[$ligne]);
1393			$largeur[$i]=imagesx($img[$i]);
1394			$hauteur[$i]=imagesy($img[$i]);
1395			$hauteur_ligne[$ligne]=max($hauteur_ligne[$ligne],$hauteur[$i]);
1396			$largeur_colonne[$col]=max($largeur_colonne[$col],$largeur[$i]);
1397			}
1398		$i++;
1399		}
1400 	}
1401
1402$hauteurfin=0;
1403$largeurfin=0;
1404for($ligne = 0; $ligne <$nbligne; $ligne++)
1405	{
1406	$hauteurfin+=$hauteur_ligne[$ligne]+$padding;
1407	}
1408for($col = 0; $col <$nbcolonne; $col++)
1409	{
1410	$largeurfin+=$largeur_colonne[$col]+$padding;
1411	}
1412$imgfin = ImageCreate(max($largeurfin,1), max($hauteurfin,1));
1413$noir=ImageColorAllocate($imgfin,0,0,0);
1414$blanc=ImageColorAllocate($imgfin,255,255,255);
1415$blanc=imagecolortransparent($imgfin,$blanc);
1416ImageFilledRectangle($imgfin,0,0,$largeurfin-1,$hauteurfin-1,$blanc);
1417$i=0;
1418$h=$padding/2-1;
1419if (substr($typeligne,0,1)=="1") ImageLine($imgfin,0,0,$largeurfin-1,0,$noir);
1420for($ligne = 0; $ligne <$nbligne; $ligne++)
1421	{
1422	$l=$padding/2-1;
1423	if (substr($typecolonne,0,1)=="1") ImageLine($imgfin,0,$h-$padding/2,0,$h+$hauteur_ligne[$ligne]+$padding/2,$noir);
1424	for($col = 0; $col <$nbcolonne; $col++)
1425		{
1426		if ($i< count($this->noeuds[3]->noeuds))
1427			{
1428			ImageCopy($imgfin,$img[$i],$l+ceil($largeur_colonne[$col]-$largeur[$i])/2,$h+$dessus_ligne[$ligne]-$base[$i], 0, 0,$largeur[$i],$hauteur[$i]);
1429			if (substr($typecolonne,$col+1,1)=="1") ImageLine($imgfin,$l+$largeur_colonne[$col]+$padding/2,$h-$padding/2,$l+$largeur_colonne[$col]+$padding/2,$h+$hauteur_ligne[$ligne]+$padding/2,$noir);
1430			}
1431		$l+=$largeur_colonne[$col]+$padding;
1432		$i++;
1433		}
1434	if (substr($typeligne,$ligne+1,1)=="1") ImageLine($imgfin,0,$h+$hauteur_ligne[$ligne]+$padding/2,$largeurfin-1,$h+$hauteur_ligne[$ligne]+$padding/2,$noir);
1435	$h+=$hauteur_ligne[$ligne]+$padding;
1436 	}
1437$this->image=$imgfin;
1438$this->base_verticale=imagesy($imgfin)/2;
1439}
1440
1441function dessine_vecteur($taille)
1442{
1443//expression
1444$this->noeuds[1]->dessine($taille);
1445$imgexp=$this->noeuds[1]->image;
1446$baseexp=$this->noeuds[1]->base_verticale;
1447$largeurexp=imagesx($imgexp);
1448$hauteurexp=imagesy($imgexp);
1449//fleche
1450$imgsup=affiche_symbol("right",16);
1451$largeursup=imagesx($imgsup);
1452$hauteursup=imagesy($imgsup);
1453//fin
1454$hauteur=$hauteurexp+$hauteursup;
1455$largeur=$largeurexp;
1456$imgfin = ImageCreate(max($largeur,1), max($hauteur,1));
1457$noir=ImageColorAllocate($imgfin,0,0,0);
1458$blanc=ImageColorAllocate($imgfin,255,255,255);
1459$blanc=imagecolortransparent($imgfin,$blanc);
1460ImageFilledRectangle($imgfin,0,0,$largeur-1,$hauteur-1,$blanc);
1461ImageCopy($imgfin, $imgsup,$largeur-6, 0,$largeursup-6, 0,$largeursup,$hauteursup);
1462imagesetthickness($imgfin,1);
1463imageline($imgfin,0,6, $largeur-4,6, $noir);
1464ImageCopy($imgfin, $imgexp,($largeur-$largeurexp)/2, $hauteursup, 0, 0,$largeurexp,$hauteurexp);
1465$this->image=$imgfin;
1466$this->base_verticale=$baseexp+$hauteursup;
1467}
1468
1469function dessine_overline($taille)
1470{
1471//expression
1472$this->noeuds[1]->dessine($taille);
1473$imgexp=$this->noeuds[1]->image;
1474$baseexp=$this->noeuds[1]->base_verticale;
1475$largeurexp=imagesx($imgexp);
1476$hauteurexp=imagesy($imgexp);
1477
1478$hauteur=$hauteurexp+2;
1479$largeur=$largeurexp;
1480$imgfin = ImageCreate(max($largeur,1), max($hauteur,1));
1481$noir=ImageColorAllocate($imgfin,0,0,0);
1482$blanc=ImageColorAllocate($imgfin,255,255,255);
1483$blanc=imagecolortransparent($imgfin,$blanc);
1484ImageFilledRectangle($imgfin,0,0,$largeur-1,$hauteur-1,$blanc);
1485imagesetthickness($imgfin,1);
1486imageline($imgfin,0,1, $largeur,1, $noir);
1487ImageCopy($imgfin, $imgexp,0,2, 0, 0,$largeurexp,$hauteurexp);
1488$this->image=$imgfin;
1489$this->base_verticale=$baseexp+2;
1490}
1491
1492function dessine_underline($taille)
1493{
1494//expression
1495$this->noeuds[1]->dessine($taille);
1496$imgexp=$this->noeuds[1]->image;
1497$baseexp=$this->noeuds[1]->base_verticale;
1498$largeurexp=imagesx($imgexp);
1499$hauteurexp=imagesy($imgexp);
1500
1501$hauteur=$hauteurexp+2;
1502$largeur=$largeurexp;
1503$imgfin = ImageCreate(max($largeur,1), max($hauteur,1));
1504$noir=ImageColorAllocate($imgfin,0,0,0);
1505$blanc=ImageColorAllocate($imgfin,255,255,255);
1506$blanc=imagecolortransparent($imgfin,$blanc);
1507ImageFilledRectangle($imgfin,0,0,$largeur-1,$hauteur-1,$blanc);
1508imagesetthickness($imgfin,1);
1509imageline($imgfin,0,$hauteurexp+1, $largeur,$hauteurexp+1, $noir);
1510ImageCopy($imgfin, $imgexp,0,0, 0, 0,$largeurexp,$hauteurexp);
1511$this->image=$imgfin;
1512$this->base_verticale=$baseexp;
1513}
1514
1515function dessine_chapeau($taille)
1516{
1517
1518$imgsup=affiche_symbol("_hat",$taille);
1519
1520$this->noeuds[1]->dessine($taille);
1521$imgexp=$this->noeuds[1]->image;
1522$baseexp=$this->noeuds[1]->base_verticale;
1523//expression
1524$largeurexp=imagesx($imgexp);
1525$hauteurexp=imagesy($imgexp);
1526//bornesup
1527$largeursup=imagesx($imgsup);
1528$hauteursup=imagesy($imgsup);
1529//fin
1530$hauteur=$hauteurexp+$hauteursup;
1531$largeur=max($largeursup,$largeurexp)+ceil($taille/8);
1532$imgfin = ImageCreate(max($largeur,1), max($hauteur,1));
1533$noir=ImageColorAllocate($imgfin,0,0,0);
1534$blanc=ImageColorAllocate($imgfin,255,255,255);
1535$blanc=imagecolortransparent($imgfin,$blanc);
1536ImageFilledRectangle($imgfin,0,0,$largeur-1,$hauteur-1,$blanc);
1537ImageCopy($imgfin, $imgsup,($largeur-$largeursup)/2, 0, 0, 0,$largeursup,$hauteursup);
1538ImageCopy($imgfin, $imgexp,($largeur-$largeurexp)/2, $hauteursup, 0, 0,$largeurexp,$hauteurexp);
1539$this->image=$imgfin;
1540$this->base_verticale=$baseexp+$hauteursup;
1541}
1542
1543function dessine_limite($taille)
1544{
1545$imglim=affiche_math("_lim",$taille);
1546$largeurlim=imagesx($imglim);
1547$hauteurlim=imagesy($imglim);
1548$baselim=$hauteurlim/2;
1549
1550$this->noeuds[1]->dessine($taille*0.8);
1551$imginf=$this->noeuds[1]->image;
1552$baseinf=$this->noeuds[1]->base_verticale;
1553$largeurinf=imagesx($imginf);
1554$hauteurinf=imagesy($imginf);
1555
1556$this->noeuds[2]->dessine($taille);
1557$imgexp=$this->noeuds[2]->image;
1558$baseexp=$this->noeuds[2]->base_verticale;
1559$largeurexp=imagesx($imgexp);
1560$hauteurexp=imagesy($imgexp);
1561
1562$hauteur=$hauteurlim+$hauteurinf;
1563$largeur=max($largeurinf,$largeurlim)+ceil($taille/8);
1564$imgfin = ImageCreate(max($largeur,1), max($hauteur,1));
1565$noir=ImageColorAllocate($imgfin,0,0,0);
1566$blanc=ImageColorAllocate($imgfin,255,255,255);
1567$blanc=imagecolortransparent($imgfin,$blanc);
1568ImageFilledRectangle($imgfin,0,0,$largeur-1,$hauteur-1,$blanc);
1569ImageCopy($imgfin, $imglim,($largeur-$largeurlim)/2, 0, 0, 0,$largeurlim,$hauteurlim);
1570ImageCopy($imgfin, $imginf,($largeur-$largeurinf)/2, $hauteurlim, 0, 0,$largeurinf,$hauteurinf);
1571
1572$this->image=alignement2($imgfin,$baselim,$imgexp,$baseexp);
1573$this->base_verticale=max($baselim,$baseexp);
1574}
1575
1576function dessine_delimiteur($taille)
1577{
1578$this->noeuds[2]->dessine($taille);
1579$imgexp=$this->noeuds[2]->image;
1580$baseexp=$this->noeuds[2]->base_verticale;
1581$hauteurexp=imagesy($imgexp);
1582if ($this->noeuds[1]->texte=="&$") $imggauche=parenthese($hauteurexp,$this->noeuds[1]->noeuds[0]->texte);
1583else $imggauche=parenthese($hauteurexp,$this->noeuds[1]->texte);
1584$basegauche=imagesy($imggauche)/2;
1585if ($this->noeuds[3]->texte=="&$") $imgdroit=parenthese($hauteurexp,$this->noeuds[3]->noeuds[0]->texte);
1586else $imgdroit=parenthese($hauteurexp,$this->noeuds[3]->texte);
1587$basedroit=imagesy($imgdroit)/2;
1588$this->image=alignement3($imggauche,$basegauche,$imgexp,$baseexp,$imgdroit,$basedroit);
1589$this->base_verticale=max($basegauche,$baseexp,$basedroit);
1590}
1591}
1592//******************************************************************************************
1593
1594function detectimg($n)
1595{
1596/*
1597Detects if the formula image already exists in the $dirimg cache directory.
1598In that case, the function returns a parameter (recorded in the name of the image file) which allows to align correctly the image with the text.
1599*/
1600global $dirimg;
1601$ret=0;
1602$handle=opendir($dirimg);
1603while ($fi = readdir($handle))
1604	{
1605	$info=pathinfo($fi);
1606	if ($fi!="." && $fi!=".." && $info["extension"]=="png" && ereg("^math",$fi))
1607		{
1608		list($math,$v,$name)=explode("_",$fi);
1609		if ($name==$n)
1610			{
1611			$ret=$v;
1612			break;
1613			}
1614		}
1615	}
1616closedir($handle);
1617return $ret;
1618}
1619
1620function mathimage($text,$size,$pathtoimg)
1621{
1622/*
1623Creates the formula image (if the image is not in the cache) and returns the <img src=...></img> html code.
1624*/
1625global $dirimg;
1626$nameimg = md5(trim($text).$size).'.png';
1627$v=detectimg($nameimg);
1628if ($v==0)
1629	{
1630	//the image doesn't exist in the cache directory. we create it.
1631	$formula=new expression_math(tableau_expression(trim($text)));
1632	$formula->dessine($size);
1633	$v=1000-imagesy($formula->image)+$formula->base_verticale+3;
1634	//1000+baseline ($v) is recorded in the name of the image
1635	ImagePNG($formula->image,$dirimg."/math_".$v."_".$nameimg);
1636	}
1637$valign=$v-1000;
1638return '<img src="'.$pathtoimg."math_".$v."_".$nameimg.'" style="vertical-align:'.$valign.'px;'.' display: inline-block ;" alt="'.$text.'" title="'.$text.'"/>';
1639}
1640
1641
1642function mathfilter($text,$size,$pathtoimg)
1643{
1644/* THE MAIN FUNCTION
16451) the content of the math tags (<m></m>) are extracted in the $t variable (you can replace <m></m> by your own tag).
16462) the "mathimage" function replaces the $t code by <img src=...></img> according to this method :
1647- if the image corresponding to the formula doesn't exist in the $dirimg cache directory (detectimg($nameimg)=0), the script creates the image and returns the "<img src=...></img>" code.
1648- otherwise, the script returns only the <img src=...></img>" code.
1649To align correctly the formula image with the text, the "valign" parameter of the image is required.
1650That's why a parameter (1000+valign) is recorded in the name of the image file (the "detectimg" function returns this parameter if the image exists in the cache directory)
1651To be sure that the name of the image file is unique and to allow the script to retrieve the valign parameter without re-creating the image, the syntax of the image filename is :
1652math_(1000+valign)_md5(formulatext.size).png.
1653(1000+valign is used instead of valign directly to avoid a negative number)
1654*/
1655$text=stripslashes($text);
1656$size=max($size,10);
1657$size=min($size,24);
1658preg_match_all("|<m>(.*?)</m>|", $text, $regs, PREG_SET_ORDER);
1659foreach ($regs as $math)
1660	{
1661	$t=str_replace('<m>','',$math[0]);
1662	$t=str_replace('</m>','',$t);
1663	$code=mathimage(trim($t),$size,$pathtoimg);
1664	$text = str_replace($math[0], $code, $text);
1665	}
1666return $text;
1667}
1668
1669?>
1670