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 14namespace RL\PhpMathPublisher; 15 16/** 17 * \RL\PhpMathPublisher\MathExpression 18 * 19 * @author Pascal Brachet <pbrachet@xm1math.net> 20 * @author Peter Vasilevsky <tuxoiduser@gmail.com> a.k.a. Tux-oid 21 * @license GPLv2 22 */ 23class MathExpression extends Expression 24{ 25 /** 26 * @var Expression[]|MathExpression[]|string 27 */ 28 public $nodes; 29 30 /** 31 * Constructor 32 * 33 * @param Expression[] $exp 34 * @param Helper $helper 35 */ 36 public function __construct($exp, $helper) 37 { 38 $this->helper = $helper; 39 $this->text = "&$"; 40 $this->nodes = $exp; 41 $this->nodes = $this->parse(); 42 } 43 44 /** 45 * @return array 46 */ 47 public function parse() 48 { 49 if (count($this->nodes) <= 3) { 50 return $this->nodes; 51 } 52 $ret = array(); 53 $parenthesiss = array(); 54 for ($i = 0; $i < count($this->nodes); $i++) { 55 if ($this->nodes[$i]->text == '(' || $this->nodes[$i]->text == '{') { 56 array_push($parenthesiss, $i); 57 } elseif ($this->nodes[$i]->text == ')' || $this->nodes[$i]->text == '}') { 58 $pos = array_pop($parenthesiss); 59 if (count($parenthesiss) == 0) { 60 $sub = array_slice($this->nodes, $pos + 1, $i - $pos - 1); 61 if ($this->nodes[$i]->text == ')') { 62 $ret[] = new MathExpression(array( 63 new TextExpression("(", $this->helper), 64 new MathExpression($sub, $this->helper), 65 new TextExpression(")", $this->helper) 66 ), $this->helper); 67 } else { 68 $ret[] = new MathExpression($sub, $this->helper); 69 } 70 } 71 } elseif (count($parenthesiss) == 0) { 72 $ret[] = $this->nodes[$i]; 73 } 74 } 75 $ret = $this->handleFunction($ret, 'sqrt', 1); 76 $ret = $this->handleFunction($ret, 'vec', 1); 77 $ret = $this->handleFunction($ret, 'overline', 1); 78 $ret = $this->handleFunction($ret, 'underline', 1); 79 $ret = $this->handleFunction($ret, 'hat', 1); 80 $ret = $this->handleFunction($ret, 'int', 3); 81 $ret = $this->handleFunction($ret, 'doubleint', 3); 82 $ret = $this->handleFunction($ret, 'tripleint', 3); 83 $ret = $this->handleFunction($ret, 'oint', 3); 84 $ret = $this->handleFunction($ret, 'prod', 3); 85 $ret = $this->handleFunction($ret, 'sum', 3); 86 $ret = $this->handleFunction($ret, 'bigcup', 3); 87 $ret = $this->handleFunction($ret, 'bigcap', 3); 88 $ret = $this->handleFunction($ret, 'delim', 3); 89 $ret = $this->handleFunction($ret, 'lim', 2); 90 $ret = $this->handleFunction($ret, 'root', 2); 91 $ret = $this->handleFunction($ret, 'matrix', 3); 92 $ret = $this->handleFunction($ret, 'tabular', 3); 93 94 $ret = $this->handleOperation($ret, '^'); 95 $ret = $this->handleOperation($ret, 'over'); 96 $ret = $this->handleOperation($ret, '_'); 97 $ret = $this->handleOperation($ret, 'under'); 98 $ret = $this->handleOperation($ret, '*'); 99 $ret = $this->handleOperation($ret, '/'); 100 $ret = $this->handleOperation($ret, '+'); 101 $ret = $this->handleOperation($ret, '-'); 102 103 return $ret; 104 } 105 106 /** 107 * @param array $nodes 108 * @param $operation 109 * @return array 110 */ 111 public function handleOperation(array $nodes, $operation) 112 { 113 do { 114 $change = false; 115 if (count($nodes) <= 3) { 116 return $nodes; 117 } 118 $ret = array(); 119 for ($i = 0; $i < count($nodes); $i++) { 120 if (!$change && $i < count($nodes) - 2 && $nodes[$i + 1]->text == $operation) { 121 $ret[] = new MathExpression(array($nodes[$i], $nodes[$i + 1], $nodes[$i + 2]), $this->helper); 122 $i += 2; 123 $change = true; 124 } else { 125 $ret[] = $nodes[$i]; 126 } 127 } 128 $nodes = $ret; 129 } while ($change); 130 131 return $ret; 132 } 133 134 /** 135 * @param array $nodes 136 * @param $function 137 * @param $argumentsCount 138 * @return array 139 */ 140 public function handleFunction(array $nodes, $function, $argumentsCount) 141 { 142 if (count($nodes) <= $argumentsCount + 1) { 143 return $nodes; 144 } 145 $ret = array(); 146 for ($i = 0; $i < count($nodes); $i++) { 147 if ($i < count($nodes) - $argumentsCount && $nodes[$i]->text == $function) { 148 $a = array(); 149 for ($j = $i; $j <= $i + $argumentsCount; $j++) { 150 $a[] = $nodes[$j]; 151 } 152 $ret[] = new MathExpression($a, $this->helper); 153 $i += $argumentsCount; 154 } else { 155 $ret[] = $nodes[$i]; 156 } 157 } 158 159 return $ret; 160 } 161 162 163 /** 164 * @param $size 165 */ 166 public function draw($size) 167 { 168 switch (count($this->nodes)) { 169 case 1: 170 $this->nodes[0]->draw($size); 171 $this->image = $this->nodes[0]->image; 172 $this->verticalBased = $this->nodes[0]->verticalBased; 173 break; 174 case 2: 175 switch ($this->nodes[0]->text) { 176 case 'sqrt': 177 $this->drawSqrt($size); 178 break; 179 case 'vec': 180 $this->drawVector($size); 181 break; 182 case 'overline': 183 $this->drawOverLine($size); 184 break; 185 case 'underline': 186 $this->drawUnderline($size); 187 break; 188 case 'hat': 189 $this->drawHat($size); 190 break; 191 default: 192 $this->drawExpression($size); 193 break; 194 } 195 break; 196 case 3: 197 if ($this->nodes[0]->text == "lim") { 198 $this->drawLimit($size); 199 } elseif ($this->nodes[0]->text == "root") { 200 $this->drawRoot($size); 201 } else { 202 switch ($this->nodes[1]->text) { 203 case '/': 204 $this->drawFraction($size); 205 break; 206 case '^': 207 $this->drawExponent($size); 208 break; 209 case 'over': 210 $this->drawTop($size); 211 break; 212 case '_': 213 $this->drawIndex($size); 214 break; 215 case 'under': 216 $this->draw_bottom($size); 217 break; 218 default: 219 $this->drawExpression($size); 220 break; 221 } 222 } 223 break; 224 case 4: 225 switch ($this->nodes[0]->text) { 226 case 'int': 227 $this->drawLargestOperator($size, '_integrale'); 228 break; 229 case 'doubleint': 230 $this->drawLargestOperator($size, '_dintegrale'); 231 break; 232 case 'tripleint': 233 $this->drawLargestOperator($size, '_tintegrale'); 234 break; 235 case 'oint': 236 $this->drawLargestOperator($size, '_ointegrale'); 237 break; 238 case 'sum': 239 $this->drawLargestOperator($size, '_somme'); 240 break; 241 case 'prod': 242 $this->drawLargestOperator($size, '_produit'); 243 break; 244 case 'bigcap': 245 $this->drawLargestOperator($size, '_intersection'); 246 break; 247 case 'bigcup': 248 $this->drawLargestOperator($size, '_reunion'); 249 break; 250 case 'delim': 251 $this->drawDelimiter($size); 252 break; 253 case 'matrix': 254 $this->drawMatrix($size); 255 break; 256 case 'tabular': 257 $this->drawTable($size); 258 break; 259 default: 260 $this->drawExpression($size); 261 break; 262 } 263 break; 264 default: 265 $this->drawExpression($size); 266 break; 267 } 268 } 269 270 /** 271 * @param $size 272 */ 273 public function drawExpression($size) 274 { 275 $width = 1; 276 //$height is calculated from $top and $bottom below 277 $top = 1; 278 $bottom = 1; 279 $img = array(); 280 $base = array(); 281 for ($i = 0; $i < count($this->nodes); $i++) { 282 if ($this->nodes[$i]->text != '(' && $this->nodes[$i]->text != ')') { 283 $this->nodes[$i]->draw($size); 284 $img[$i] = $this->nodes[$i]->image; 285 $base[$i] = $this->nodes[$i]->verticalBased; 286 $top = max($base[$i], $top); 287 $bottom = max(imagesy($img[$i]) - $base[$i], $bottom); 288 } 289 } 290 $height = $top + $bottom; 291 $paro = $this->helper->parenthesis(max($top, $bottom) * 2, "("); 292 $parf = $this->helper->parenthesis(max($top, $bottom) * 2, ")"); 293 for ($i = 0; $i < count($this->nodes); $i++) { 294 if (!isset($img[$i])) { 295 if ($this->nodes[$i]->text == "(") { 296 $img[$i] = $paro; 297 } else { 298 $img[$i] = $parf; 299 } 300 $top = max(imagesy($img[$i]) / 2, $top); 301 $base[$i] = imagesy($img[$i]) / 2; 302 $bottom = max(imagesy($img[$i]) - $base[$i], $bottom); 303 $height = max(imagesy($img[$i]), $height); 304 } 305 $width += imagesx($img[$i]); 306 } 307 $this->verticalBased = $top; 308 $result = imagecreate(max($width, 1), max($height, 1)); 309 $white = $this->helper->getBackColor($result); 310 imagefilledrectangle($result, 0, 0, $width - 1, $height - 1, $white); 311 $pos = 0; 312 for ($i = 0; $i < count($img); $i++) { 313 if (isset($img[$i])) { 314 imagecopy($result, $img[$i], $pos, $top - $base[$i], 0, 0, imagesx($img[$i]), imagesy($img[$i])); 315 $pos += imagesx($img[$i]); 316 } 317 } 318 $this->image = $result; 319 } 320 321 /** 322 * @param $size 323 */ 324 public function drawFraction($size) 325 { 326 $this->nodes[0]->draw($size * 0.9); 327 $img1 = $this->nodes[0]->image; 328 $this->nodes[2]->draw($size * 0.9); 329 $img2 = $this->nodes[2]->image; 330 $height1 = imagesy($img1); 331 $height2 = imagesy($img2); 332 $width1 = imagesx($img1); 333 $width2 = imagesx($img2); 334 $width = max($width1, $width2); 335 $height = $height1 + $height2 + 4; 336 $result = imagecreate(max($width + 5, 1), max($height, 1)); 337 $black = $this->helper->getFontColor($result); 338 $white = $this->helper->getBackColor($result); 339 $this->verticalBased = $height1 + 2; 340 imagefilledrectangle($result, 0, 0, $width + 4, $height - 1, $white); 341 imagecopy($result, $img1, ($width - $width1) / 2, 0, 0, 0, $width1, $height1); 342 imageline($result, 0, $this->verticalBased, $width, $this->verticalBased, $black); 343 imagecopy($result, $img2, ($width - $width2) / 2, $height1 + 4, 0, 0, $width2, $height2); 344 $this->image = $result; 345 } 346 347 /** 348 * @param $size 349 */ 350 public function drawExponent($size) 351 { 352 $this->nodes[0]->draw($size); 353 $img1 = $this->nodes[0]->image; 354 $base1 = $this->nodes[0]->verticalBased; 355 $this->nodes[2]->draw($size * 0.8); 356 $img2 = $this->nodes[2]->image; 357 $height1 = imagesy($img1); 358 $height2 = imagesy($img2); 359 $width1 = imagesx($img1); 360 $width2 = imagesx($img2); 361 $width = $width1 + $width2; 362 if ($height1 >= $height2) { 363 $height = ceil($height2 / 2 + $height1); 364 $this->verticalBased = $height2 / 2 + $base1; 365 $result = imagecreate(max($width, 1), max($height, 1)); 366 $white = $this->helper->getBackColor($result); 367 imagefilledrectangle($result, 0, 0, $width - 1, $height - 1, $white); 368 imagecopy($result, $img1, 0, ceil($height2 / 2), 0, 0, $width1, $height1); 369 imagecopy($result, $img2, $width1, 0, 0, 0, $width2, $height2); 370 } else { 371 $height = ceil($height1 / 2 + $height2); 372 $this->verticalBased = $height2 - $base1 + $height1 / 2; 373 $result = imagecreate(max($width, 1), max($height, 1)); 374 $white = $this->helper->getBackColor($result); 375 imagefilledrectangle($result, 0, 0, $width - 1, $height - 1, $white); 376 imagecopy($result, $img1, 0, ceil($height2 - $height1 / 2), 0, 0, $width1, $height1); 377 imagecopy($result, $img2, $width1, 0, 0, 0, $width2, $height2); 378 } 379 $this->image = $result; 380 } 381 382 /** 383 * @param $size 384 */ 385 public function drawIndex($size) 386 { 387 $this->nodes[0]->draw($size); 388 $img1 = $this->nodes[0]->image; 389 $base1 = $this->nodes[0]->verticalBased; 390 $this->nodes[2]->draw($size * 0.8); 391 $img2 = $this->nodes[2]->image; 392 $height1 = imagesy($img1); 393 $height2 = imagesy($img2); 394 $width1 = imagesx($img1); 395 $width2 = imagesx($img2); 396 $width = $width1 + $width2; 397 if ($height1 >= $height2) { 398 $height = ceil($height2 / 2 + $height1); 399 $this->verticalBased = $base1; 400 $result = imagecreate(max($width, 1), max($height, 1)); 401 $white = $this->helper->getBackColor($result); 402 imagefilledrectangle($result, 0, 0, $width - 1, $height - 1, $white); 403 imagecopy($result, $img1, 0, 0, 0, 0, $width1, $height1); 404 imagecopy($result, $img2, $width1, ceil($height1 - $height2 / 2), 0, 0, $width2, $height2); 405 } else { 406 $height = ceil($height1 / 2 + $height2); 407 $this->verticalBased = $base1; 408 $result = imagecreate(max($width, 1), max($height, 1)); 409 $white = $this->helper->getBackColor($result); 410 imagefilledrectangle($result, 0, 0, $width - 1, $height - 1, $white); 411 imagecopy($result, $img1, 0, 0, 0, 0, $width1, $height1); 412 imagecopy($result, $img2, $width1, ceil($height1 / 2), 0, 0, $width2, $height2); 413 } 414 $this->image = $result; 415 } 416 417 /** 418 * @param $size 419 */ 420 public function drawSqrt($size) 421 { 422 $this->nodes[1]->draw($size); 423 $imgExp = $this->nodes[1]->image; 424 $baseExp = $this->nodes[1]->verticalBased; 425 $widthExp = imagesx($imgExp); 426 $heightExp = imagesy($imgExp); 427 428 $imgrac = $this->helper->displaySymbol("_racine", $heightExp + 2); 429 $widthrac = imagesx($imgrac); 430 $heightrac = imagesy($imgrac); 431 432 $width = $widthrac + $widthExp; 433 $height = max($heightExp, $heightrac); 434 $result = imagecreate(max($width, 1), max($height, 1)); 435 $black = $this->helper->getFontColor($result); 436 $white = $this->helper->getBackColor($result); 437 imagefilledrectangle($result, 0, 0, $width - 1, $height - 1, $white); 438 imagecopy($result, $imgrac, 0, 0, 0, 0, $widthrac, $heightrac); 439 imagecopy($result, $imgExp, $widthrac, $height - $heightExp, 0, 0, $widthExp, $heightExp); 440 imagesetthickness($result, 1); 441 imageline($result, $widthrac - 2, 2, $widthrac + $widthExp + 2, 2, $black); 442 $this->verticalBased = $height - $heightExp + $baseExp; 443 $this->image = $result; 444 } 445 446 /** 447 * @param $size 448 */ 449 public function drawRoot($size) 450 { 451 $this->nodes[1]->draw($size * 0.6); 452 $imgRoot = $this->nodes[1]->image; 453 $widthRoot = imagesx($imgRoot); 454 $heightRoot = imagesy($imgRoot); 455 456 $this->nodes[2]->draw($size); 457 $imgExp = $this->nodes[2]->image; 458 $baseExp = $this->nodes[2]->verticalBased; 459 $widthExp = imagesx($imgExp); 460 $heightExp = imagesy($imgExp); 461 462 $imgRac = $this->helper->displaySymbol("_racine", $heightExp + 2); 463 $widthRac = imagesx($imgRac); 464 $heightRac = imagesy($imgRac); 465 466 $width = $widthRac + $widthExp; 467 $height = max($heightExp, $heightRac); 468 $result = imagecreate(max($width, 1), max($height, 1)); 469 $black = $this->helper->getFontColor($result); 470 $white = $this->helper->getBackColor($result); 471 imagefilledrectangle($result, 0, 0, $width - 1, $height - 1, $white); 472 imagecopy($result, $imgRac, 0, 0, 0, 0, $widthRac, $heightRac); 473 imagecopy($result, $imgExp, $widthRac, $height - $heightExp, 0, 0, $widthExp, $heightExp); 474 imagesetthickness($result, 1); 475 imageline($result, $widthRac - 2, 2, $widthRac + $widthExp + 2, 2, $black); 476 imagecopy($result, $imgRoot, 0, 0, 0, 0, $widthRoot, $heightRoot); 477 $this->verticalBased = $height - $heightExp + $baseExp; 478 $this->image = $result; 479 } 480 481 /** 482 * @param $size 483 * @param $character 484 */ 485 public function drawLargestOperator($size, $character) 486 { 487 $this->nodes[1]->draw($size * 0.8); 488 $img1 = $this->nodes[1]->image; 489 $this->nodes[2]->draw($size * 0.8); 490 $img2 = $this->nodes[2]->image; 491 $this->nodes[3]->draw($size); 492 $imgExp = $this->nodes[3]->image; 493 $baseExp = $this->nodes[3]->verticalBased; 494 //borneinf 495 $width1 = imagesx($img1); 496 $height1 = imagesy($img1); 497 //bornesup 498 $width2 = imagesx($img2); 499 $height2 = imagesy($img2); 500 //character 501 $imgSymbol = $this->helper->displaySymbol($character, $baseExp * 1.8); //max($baseExp,$heightExp-$baseExp)*2); 502 $widthSymbol = imagesx($imgSymbol); 503 $heightSymbol = imagesy($imgSymbol); 504 $baseSymbol = $heightSymbol / 2; 505 506 $heightLeft = $heightSymbol + $height1 + $height2; 507 $widthLeft = max($widthSymbol, $width1, $width2); 508 $imgLeft = imagecreate(max($widthLeft, 1), max($heightLeft, 1)); 509 $white = $this->helper->getBackColor($imgLeft); 510 imagefilledrectangle($imgLeft, 0, 0, $widthLeft - 1, $heightLeft - 1, $white); 511 imagecopy($imgLeft, $imgSymbol, ($widthLeft - $widthSymbol) / 2, $height2, 0, 0, $widthSymbol, $heightSymbol); 512 imagecopy($imgLeft, $img2, ($widthLeft - $width2) / 2, 0, 0, 0, $width2, $height2); 513 imagecopy($imgLeft, $img1, ($widthLeft - $width1) / 2, $height2 + $heightSymbol, 0, 0, $width1, $height1); 514 $imgFin = $this->helper->alignment2($imgLeft, $baseSymbol + $height2, $imgExp, $baseExp); 515 $this->image = $imgFin; 516 $this->verticalBased = max($baseSymbol + $height2, $baseExp + $height2); 517 } 518 519 /** 520 * @param $size 521 */ 522 public function drawTop($size) 523 { 524 $this->nodes[2]->draw($size * 0.8); 525 $imgSup = $this->nodes[2]->image; 526 $this->nodes[0]->draw($size); 527 $imgExp = $this->nodes[0]->image; 528 $baseExp = $this->nodes[0]->verticalBased; 529 //expression 530 $widthExp = imagesx($imgExp); 531 $heightExp = imagesy($imgExp); 532 //bornesup 533 $widthSup = imagesx($imgSup); 534 $heightSup = imagesy($imgSup); 535 //fin 536 $height = $heightExp + $heightSup; 537 $width = max($widthSup, $widthExp) + ceil($size / 8); 538 $imgFin = imagecreate(max($width, 1), max($height, 1)); 539 $white = $this->helper->getBackColor($imgFin); 540 imagefilledrectangle($imgFin, 0, 0, $width - 1, $height - 1, $white); 541 imagecopy($imgFin, $imgSup, ($width - $widthSup) / 2, 0, 0, 0, $widthSup, $heightSup); 542 imagecopy($imgFin, $imgExp, ($width - $widthExp) / 2, $heightSup, 0, 0, $widthExp, $heightExp); 543 $this->image = $imgFin; 544 $this->verticalBased = $baseExp + $heightSup; 545 } 546 547 /** 548 * @param $size 549 */ 550 public function draw_bottom($size) 551 { 552 $this->nodes[2]->draw($size * 0.8); 553 $imgInf = $this->nodes[2]->image; 554 $this->nodes[0]->draw($size); 555 $imgExp = $this->nodes[0]->image; 556 $baseExp = $this->nodes[0]->verticalBased; 557 //expression 558 $widthExp = imagesx($imgExp); 559 $heightExp = imagesy($imgExp); 560 //borneinf 561 $widthInf = imagesx($imgInf); 562 $heightInf = imagesy($imgInf); 563 //fin 564 $height = $heightExp + $heightInf; 565 $width = max($widthInf, $widthExp) + ceil($size / 8); 566 $imgFin = imagecreate(max($width, 1), max($height, 1)); 567 $white = $this->helper->getBackColor($imgFin); 568 imagefilledrectangle($imgFin, 0, 0, $width - 1, $height - 1, $white); 569 imagecopy($imgFin, $imgExp, ($width - $widthExp) / 2, 0, 0, 0, $widthExp, $heightExp); 570 imagecopy($imgFin, $imgInf, ($width - $widthInf) / 2, $heightExp, 0, 0, $widthInf, $heightInf); 571 $this->image = $imgFin; 572 $this->verticalBased = $baseExp; 573 } 574 575 /** 576 * @param $size 577 */ 578 public function drawMatrix($size) 579 { 580 $padding = 8; 581 $nbLine = $this->nodes[1]->nodes[0]->text; 582 $nbColumn = $this->nodes[2]->nodes[0]->text; 583 584 $topLine = array(); 585 $heightLine = array(); 586 $widthColumn = array(); 587 $img = array(); 588 $height = array(); 589 $width = array(); 590 $base = array(); 591 592 for ($line = 0; $line < $nbLine; $line++) { 593 $heightLine[$line] = 0; 594 $topLine[$line] = 0; 595 } 596 for ($col = 0; $col < $nbColumn; $col++) { 597 $widthColumn[$col] = 0; 598 } 599 $i = 0; 600 for ($line = 0; $line < $nbLine; $line++) { 601 for ($col = 0; $col < $nbColumn; $col++) { 602 if ($i < count($this->nodes[3]->nodes)) { 603 $this->nodes[3]->nodes[$i]->draw($size * 0.9); 604 $img[$i] = $this->nodes[3]->nodes[$i]->image; 605 $base[$i] = $this->nodes[3]->nodes[$i]->verticalBased; 606 $topLine[$line] = max($base[$i], $topLine[$line]); 607 $width[$i] = imagesx($img[$i]); 608 $height[$i] = imagesy($img[$i]); 609 $heightLine[$line] = max($heightLine[$line], $height[$i]); 610 $widthColumn[$col] = max($widthColumn[$col], $width[$i]); 611 } 612 $i++; 613 } 614 } 615 616 $heightFin = 0; 617 $widthFin = 0; 618 for ($line = 0; $line < $nbLine; $line++) { 619 $heightFin += $heightLine[$line] + $padding; 620 } 621 for ($col = 0; $col < $nbColumn; $col++) { 622 $widthFin += $widthColumn[$col] + $padding; 623 } 624 $heightFin -= $padding; 625 $widthFin -= $padding; 626 $imgFin = imagecreate(max($widthFin, 1), max($heightFin, 1)); 627 $white = $this->helper->getBackColor($imgFin); 628 imagefilledrectangle($imgFin, 0, 0, $widthFin - 1, $heightFin - 1, $white); 629 $i = 0; 630 $h = $padding / 2 - 1; 631 for ($line = 0; $line < $nbLine; $line++) { 632 $l = $padding / 2 - 1; 633 for ($col = 0; $col < $nbColumn; $col++) { 634 if ($i < count($this->nodes[3]->nodes)) { 635 imagecopy( 636 $imgFin, 637 $img[$i], 638 $l + ceil($widthColumn[$col] - $width[$i]) / 2, 639 $h + $topLine[$line] - $base[$i], 640 0, 641 0, 642 $width[$i], 643 $height[$i] 644 ); 645 //ImageRectangle($imgFin,$l,$h,$l+$widthColumn[$col],$h+$heightLine[$line],$black); 646 } 647 $l += $widthColumn[$col] + $padding; 648 $i++; 649 } 650 $h += $heightLine[$line] + $padding; 651 } 652 //ImageRectangle($imgFin,0,0,$widthFin-1,$heightFin-1,$black); 653 $this->image = $imgFin; 654 $this->verticalBased = imagesy($imgFin) / 2; 655 } 656 657 /** 658 * @param $size 659 */ 660 public function drawTable($size) 661 { 662 $padding = 8; 663 $typeLine = $this->nodes[1]->nodes[0]->text; 664 $typeColumn = $this->nodes[2]->nodes[0]->text; 665 $nbLine = strlen($typeLine) - 1; 666 $nbColumn = strlen($typeColumn) - 1; 667 668 $topLine = array(); 669 $heightLine = array(); 670 $widthColumn = array(); 671 $img = array(); 672 $width = array(); 673 $height = array(); 674 $base = array(); 675 676 for ($line = 0; $line < $nbLine; $line++) { 677 $heightLine[$line] = 0; 678 $topLine[$line] = 0; 679 } 680 for ($col = 0; $col < $nbColumn; $col++) { 681 $widthColumn[$col] = 0; 682 } 683 $i = 0; 684 for ($line = 0; $line < $nbLine; $line++) { 685 for ($col = 0; $col < $nbColumn; $col++) { 686 if ($i < count($this->nodes[3]->nodes)) { 687 $this->nodes[3]->nodes[$i]->draw($size * 0.9); 688 $img[$i] = $this->nodes[3]->nodes[$i]->image; 689 $base[$i] = $this->nodes[3]->nodes[$i]->verticalBased; 690 $topLine[$line] = max($base[$i], $topLine[$line]); 691 $width[$i] = imagesx($img[$i]); 692 $height[$i] = imagesy($img[$i]); 693 $heightLine[$line] = max($heightLine[$line], $height[$i]); 694 $widthColumn[$col] = max($widthColumn[$col], $width[$i]); 695 } 696 $i++; 697 } 698 } 699 700 $heightFin = 0; 701 $widthFin = 0; 702 for ($line = 0; $line < $nbLine; $line++) { 703 $heightFin += $heightLine[$line] + $padding; 704 } 705 for ($col = 0; $col < $nbColumn; $col++) { 706 $widthFin += $widthColumn[$col] + $padding; 707 } 708 $imgFin = imagecreate(max($widthFin, 1), max($heightFin, 1)); 709 $black = $this->helper->getFontColor($imgFin); 710 $white = $this->helper->getBackColor($imgFin); 711 imagefilledrectangle($imgFin, 0, 0, $widthFin - 1, $heightFin - 1, $white); 712 $i = 0; 713 $h = $padding / 2 - 1; 714 if (substr($typeLine, 0, 1) == "1") { 715 imageline($imgFin, 0, 0, $widthFin - 1, 0, $black); 716 } 717 for ($line = 0; $line < $nbLine; $line++) { 718 $l = $padding / 2 - 1; 719 if (substr($typeColumn, 0, 1) == "1") { 720 imageline($imgFin, 0, $h - $padding / 2, 0, $h + $heightLine[$line] + $padding / 2, $black); 721 } 722 for ($col = 0; $col < $nbColumn; $col++) { 723 if ($i < count($this->nodes[3]->nodes)) { 724 imagecopy( 725 $imgFin, 726 $img[$i], 727 $l + ceil($widthColumn[$col] - $width[$i]) / 2, 728 $h + $topLine[$line] - $base[$i], 729 0, 730 0, 731 $width[$i], 732 $height[$i] 733 ); 734 if (substr($typeColumn, $col + 1, 1) == "1") { 735 imageline( 736 $imgFin, 737 $l + $widthColumn[$col] + $padding / 2, 738 $h - $padding / 2, 739 $l + $widthColumn[$col] + $padding / 2, 740 $h + $heightLine[$line] + $padding / 2, 741 $black 742 ); 743 } 744 } 745 $l += $widthColumn[$col] + $padding; 746 $i++; 747 } 748 if (substr($typeLine, $line + 1, 1) == "1") { 749 imageline( 750 $imgFin, 751 0, 752 $h + $heightLine[$line] + $padding / 2, 753 $widthFin - 1, 754 $h + $heightLine[$line] + $padding / 2, 755 $black 756 ); 757 } 758 $h += $heightLine[$line] + $padding; 759 } 760 $this->image = $imgFin; 761 $this->verticalBased = imagesy($imgFin) / 2; 762 } 763 764 /** 765 * @param $size 766 */ 767 public function drawVector($size) 768 { 769 //expression 770 $this->nodes[1]->draw($size); 771 $imgExp = $this->nodes[1]->image; 772 $baseExp = $this->nodes[1]->verticalBased; 773 $widthExp = imagesx($imgExp); 774 $heightExp = imagesy($imgExp); 775 //fleche 776 $imgSup = $this->helper->displaySymbol("right", 16); 777 $widthSup = imagesx($imgSup); 778 $heightSup = imagesy($imgSup); 779 //fin 780 $height = $heightExp + $heightSup; 781 $width = $widthExp; 782 $imgFin = imagecreate(max($width, 1), max($height, 1)); 783 $black = $this->helper->getFontColor($imgFin); 784 $white = $this->helper->getBackColor($imgFin); 785 imagefilledrectangle($imgFin, 0, 0, $width - 1, $height - 1, $white); 786 imagecopy($imgFin, $imgSup, $width - 6, 0, $widthSup - 6, 0, $widthSup, $heightSup); 787 imagesetthickness($imgFin, 1); 788 imageline($imgFin, 0, 6, $width - 4, 6, $black); 789 imagecopy($imgFin, $imgExp, ($width - $widthExp) / 2, $heightSup, 0, 0, $widthExp, $heightExp); 790 $this->image = $imgFin; 791 $this->verticalBased = $baseExp + $heightSup; 792 } 793 794 /** 795 * @param $size 796 */ 797 public function drawOverLine($size) 798 { 799 //expression 800 $this->nodes[1]->draw($size); 801 $imgExp = $this->nodes[1]->image; 802 $baseExp = $this->nodes[1]->verticalBased; 803 $widthExp = imagesx($imgExp); 804 $heightExp = imagesy($imgExp); 805 806 $height = $heightExp + 2; 807 $width = $widthExp; 808 $imgFin = imagecreate(max($width, 1), max($height, 1)); 809 $black = $this->helper->getFontColor($imgFin); 810 $white = $this->helper->getBackColor($imgFin); 811 imagefilledrectangle($imgFin, 0, 0, $width - 1, $height - 1, $white); 812 imagesetthickness($imgFin, 1); 813 imageline($imgFin, 0, 1, $width, 1, $black); 814 imagecopy($imgFin, $imgExp, 0, 2, 0, 0, $widthExp, $heightExp); 815 $this->image = $imgFin; 816 $this->verticalBased = $baseExp + 2; 817 } 818 819 /** 820 * @param $size 821 */ 822 public function drawUnderline($size) 823 { 824 //expression 825 $this->nodes[1]->draw($size); 826 $imgExp = $this->nodes[1]->image; 827 $baseExp = $this->nodes[1]->verticalBased; 828 $widthExp = imagesx($imgExp); 829 $heightExp = imagesy($imgExp); 830 831 $height = $heightExp + 2; 832 $width = $widthExp; 833 $imgFin = imagecreate(max($width, 1), max($height, 1)); 834 $black = $this->helper->getFontColor($imgFin); 835 $white = $this->helper->getBackColor($imgFin); 836 imagefilledrectangle($imgFin, 0, 0, $width - 1, $height - 1, $white); 837 imagesetthickness($imgFin, 1); 838 imageline($imgFin, 0, $heightExp + 1, $width, $heightExp + 1, $black); 839 imagecopy($imgFin, $imgExp, 0, 0, 0, 0, $widthExp, $heightExp); 840 $this->image = $imgFin; 841 $this->verticalBased = $baseExp; 842 } 843 844 /** 845 * @param $size 846 */ 847 public function drawHat($size) 848 { 849 $imgSup = $this->helper->displaySymbol("_hat", $size); 850 851 $this->nodes[1]->draw($size); 852 $imgExp = $this->nodes[1]->image; 853 $baseExp = $this->nodes[1]->verticalBased; 854 //expression 855 $widthExp = imagesx($imgExp); 856 $heightExp = imagesy($imgExp); 857 //bornesup 858 $widthSup = imagesx($imgSup); 859 $heightSup = imagesy($imgSup); 860 //fin 861 $height = $heightExp + $heightSup; 862 $width = max($widthSup, $widthExp) + ceil($size / 8); 863 $imgFin = imagecreate(max($width, 1), max($height, 1)); 864 $white = $this->helper->getBackColor($imgFin); 865 imagefilledrectangle($imgFin, 0, 0, $width - 1, $height - 1, $white); 866 imagecopy($imgFin, $imgSup, ($width - $widthSup) / 2, 0, 0, 0, $widthSup, $heightSup); 867 imagecopy($imgFin, $imgExp, ($width - $widthExp) / 2, $heightSup, 0, 0, $widthExp, $heightExp); 868 $this->image = $imgFin; 869 $this->verticalBased = $baseExp + $heightSup; 870 } 871 872 /** 873 * @param $size 874 */ 875 public function drawLimit($size) 876 { 877 $imgLim = $this->helper->displayMath("_lim", $size); 878 $widthLim = imagesx($imgLim); 879 $heightLim = imagesy($imgLim); 880 $baseLim = $heightLim / 2; 881 882 $this->nodes[1]->draw($size * 0.8); 883 $imgInf = $this->nodes[1]->image; 884 $widthInf = imagesx($imgInf); 885 $heightInf = imagesy($imgInf); 886 887 $this->nodes[2]->draw($size); 888 $imgExp = $this->nodes[2]->image; 889 $baseExp = $this->nodes[2]->verticalBased; 890 891 $height = $heightLim + $heightInf; 892 $width = max($widthInf, $widthLim) + ceil($size / 8); 893 $imgFin = imagecreate(max($width, 1), max($height, 1)); 894 $white = $this->helper->getBackColor($imgFin); 895 imagefilledrectangle($imgFin, 0, 0, $width - 1, $height - 1, $white); 896 imagecopy($imgFin, $imgLim, ($width - $widthLim) / 2, 0, 0, 0, $widthLim, $heightLim); 897 imagecopy($imgFin, $imgInf, ($width - $widthInf) / 2, $heightLim, 0, 0, $widthInf, $heightInf); 898 899 $this->image = $this->helper->alignment2($imgFin, $baseLim, $imgExp, $baseExp); 900 $this->verticalBased = max($baseLim, $baseExp); 901 } 902 903 /** 904 * @param $size 905 */ 906 public function drawDelimiter($size) 907 { 908 $this->nodes[2]->draw($size); 909 $imgExp = $this->nodes[2]->image; 910 $baseExp = $this->nodes[2]->verticalBased; 911 $heightExp = imagesy($imgExp); 912 if ($this->nodes[1]->text == "&$") { 913 $leftImg = $this->helper->parenthesis($heightExp, $this->nodes[1]->nodes[0]->text); 914 } else { 915 $leftImg = $this->helper->parenthesis($heightExp, $this->nodes[1]->text); 916 } 917 $leftBase = imagesy($leftImg) / 2; 918 if ($this->nodes[3]->text == "&$") { 919 if(isset($this->nodes[3]->nodes[0])) { 920 $rightImg = $this->helper->parenthesis($heightExp, $this->nodes[3]->nodes[0]->text); 921 } else { 922 $rightImg = $this->helper->parenthesis($heightExp, ''); 923 } 924 } else { 925 $rightImg = $this->helper->parenthesis($heightExp, $this->nodes[3]->text); 926 } 927 $rightBase = imagesy($rightImg) / 2; 928 $this->image = $this->helper->alignment3($leftImg, $leftBase, $imgExp, $baseExp, $rightImg, $rightBase); 929 $this->verticalBased = max($leftBase, $baseExp, $rightBase); 930 } 931} 932