function quantumLayoutParams(&$sizes, &$box, &$growWide) { global $debug; global $offset_y; if ($debug) { echo '<ul>'; echo '<li>'; $offset_y += 100; } $boxes = array(); $pivotIndex = $this->computePivotIndex($sizes); $pivotSize = $sizes[$pivotIndex]; $boxAR = $box->aspectRatio(); //echo "pivotIndex=$pivotIndex"; //echo '<br/>'; if (count($sizes) == 1) { $boxes[] = $box; if ($debug) { echo "Stop 1: box = \n"; $box->Dump(); echo '<br/>'; } } if (count($sizes) == 2) { $ratio = $sizes[0] / ($sizes[0] + $sizes[1]); if ($growWide) { $dim1 = $this->computeTableLayout($sizes[0], $boxAR * $ratio); $dim2 = $this->computeTableLayout($sizes[1], $boxAR * $ratio); $h = max($dim1[1], $dim2[1]); //echo "h=$h<br/>"; $dim2 = $this->computeTableLayoutGivenHeight($sizes[1], $h); $boxes[0] = new Rectangle($box->x, $box->y, $dim1[0], $h); $boxes[1] = new Rectangle($box->x + $dim1[0], $box->y, $dim2[0], $dim2[1]); } else { $dim1 = $this->computeTableLayout($sizes[0], $boxAR / $ratio); $dim2 = $this->computeTableLayout($sizes[1], $boxAR / (1 - $ratio)); $w = max($dim1[0], $dim2[0]); //echo "w=$w<br/>"; $dim2 = $this->computeTableLayoutGivenWidth($sizes[1], $w); $boxes[0] = new Rectangle($box->x, $box->y, $w, $dim1[1]); $boxes[1] = new Rectangle($box->x, $box->y + $dim1[1], $dim2[0], $dim2[1]); } if ($debug) { echo "Stop 2: box[0] = "; $boxes[0]->Dump(); echo '<br />'; echo " Stop 2: box[1] = "; $boxes[1]->Dump(); echo '<br/>'; echo 'Return ' . __LINE__ . ''; echo '<br/>'; } return $boxes; } // More than 2 $box2 = NULL; $r1 = NULL; $l1 = array(); $l2 = array(); $l3 = array(); // First compute R1 if ($pivotIndex > 0) { $l1 = array_slice($sizes, 0, $pivotIndex); $l1Size = $this->computeSize($l1); $b2Size = $this->computeSizeBetween($sizes, $pivotIndex, count($sizes) - 1); if ($growWide) { $dim1 = $this->computeTableLayoutGivenHeight($l1Size, $box->h); $dim2 = $this->computeTableLayoutGivenHeight($b2Size, $box->h); $r1 = new Rectangle($box->x, $box->y, $dim1[0], $dim1[1]); $box2 = new Rectangle($box->x + $dim1[0], $box->y, $dim2[0], $dim2[1]); } else { $dim1 = $this->computeTableLayoutGivenWidth($l1Size, $box->w); $dim2 = $this->computeTableLayoutGivenWidth($b2Size, $box->w); $r1 = new Rectangle($box->x, $box->y, $dim1[0], $dim1[1]); $box2 = new Rectangle($box->x, $box->y + $dim1[1], $dim2[0], $dim2[1]); } } else { $box2 = new Rectangle($box->x, $box->y, $box->w, $box->h); } // Recurse on R1 to compute better box2 if ($debug) { echo "<b>Recurse on R1 to get better box2</b><br />"; } if (count($l1) != 0) { if (count($l1) > 1) { $r1AR = $r1->aspectRatio(); if ($r1AR == 1) { $newGrowWidth = $growWide; } else { $newGrowWidth = $r1AR >= 1 ? true : false; } $l1boxes = $this->quantumLayoutParams($l1, $r1, $newGrowWide); } else { $l1boxes[0] = $r1; } $l1FinalBox = $this->computeUnion($l1boxes); if ($growWide) { $box2->h = $r1->h; } else { $box2->w = $r1->w; } /* echo "Final R1 box="; $l1FinalBox->Dump(); echo '<br />'; echo "box2="; $box2->Dump(); echo '<br />'; */ } // Display if ($debug) { $box->html(); $l1FinalBox->html('green', 'l1'); $box2->html(); } // Then compute R2 and R3 $box2AR = $box2->aspectRatio(); $first = true; $bestAR = 0.0; $bestdim1 = array(); $bestIndex = 0; for ($i = $pivotIndex + 1; $i < count($sizes); $i++) { $l2Size = $this->computeSizeBetween($sizes, $pivotIndex + 1, $i); $ratio = $pivotSize / ($pivotSize + $l2Size); if ($growWide) { $h1 = (int) ceil($ratio * $box2->h); $dim1 = $this->computeTableLayoutGivenHeight($pivotSize, $h1); } else { $w1 = (int) ceil($ratio * $box2->w); $dim1 = $this->computeTableLayoutGivenWidth($pivotSize, $w1); } $pivotAR = max($dim1[0] / $dim1[1], $dim1[1] / $dim1[0]); if ($first || $pivotAR < $bestAR) { $first = false; $bestAR = $pivotAR; $bestdim1 = $dim1; $bestl2Size = $l2Size; $bestIndex = $i; } } //echo "Best split: pivot=$pivotIndex, bestIndex=$bestIndex, bestAR=$bestAR, bestdim1=[" . $bestdim1[0] . ',' . $bestdim1[1] . "]<br />"; $l2 = array(); if ($bestIndex > 0) { $l2 = array_slice($sizes, $pivotIndex + 1, $bestIndex - $pivotIndex); $nl3 = count($sizes) - 1 - $bestIndex; if ($nl3 > 0) { $l3 = array_slice($sizes, $bestIndex + 1, $nl3); } } /* echo "\nSplit:\n"; echo "l1\n"; print_r($l1); echo "l2\n"; print_r($l2); echo "l3\n"; print_r($l3);*/ if (count($l2) > 0) { if ($growWide) { $dim2 = $this->computeTableLayoutGivenHeight($bestl2Size, $box2->h - $bestdim1[1]); $rp = new Rectangle($box2->x, $box2->y, $bestdim1[0], $bestdim1[1]); $r2 = new Rectangle($box2->x, $box2->y + $dim1[1], $dim2[0], $dim2[1]); if (count($l3) > 0) { $l3size = $this->computeSizeBetween($sizes, $bestIndex + 1, count($sizes) - 1); $dim3 = $this->computeTableLayoutGivenHeight($l3size, $box2->h); $r3 = new Rectangle($box2->x + $dim2[0], $box2->y, $dim3[0], $dim3[1]); } } else { $dim2 = $this->computeTableLayoutGivenWidth($bestl2Size, $box2->w - $bestdim1[0]); $rp = new Rectangle($box2->x, $box2->y, $bestdim1[0], $bestdim1[1]); $r2 = new Rectangle($box2->x + $dim1[0], $box2->y, $dim2[0], $dim2[1]); if (count($l3) > 0) { $l3size = $this->computeSizeBetween($sizes, $bestIndex + 1, count($sizes) - 1); $dim3 = $this->computeTableLayoutGivenWidth($l3size, $box2->w); $r3 = new Rectangle($box2->x, $box2->y + $dim2[1], $dim3[0], $dim3[1]); } } } else { if ($growWide) { $dim1 = $this->computeTableLayoutGivenHeight($pivotSize, $r1->h); } else { $dim1 = $this->computeTableLayoutGivenWidth($pivotSize, $r1->w); } $rp = new Rectangle($box2->x, $box2->y, $dim1[0], $dim1[1]); } /*echo "dim1\n";print_r($dim1); echo "dim2\n";print_r($dim2); echo "dim3\n";print_r($dim3);*/ //echo "rp = ";$rp->Dump(); echo "<br/>"; //echo "r2 = ";$r2->Dump(); echo "<br/>"; /* if ($r3) { echo "r3";$r3->Dump(); echo "<br/>"; } */ if ($debug) { echo "Draw<br/>"; $offset_y += 100; $rp->html("red", 'rp'); $r2->html("orange", 'r2'); if ($r3) { $r3->html("blue", 'r3'); } echo "r2="; $r2->Dump(); echo "<br/>"; } //------------------------------------------------------------------------------------------ // Finally, recurse on sublists in R2 and R3 if ($debug) { echo '<b>Recurse on sublists in R2 and R3</b><br />'; } if (count($l2) != 0) { if (count($l2) > 1) { if ($debug) { echo "recurse on R2<br/>"; } $r2AR = $r2->aspectRatio(); if ($debug) { echo "r2AR={$r2AR}<br/>"; } if ($r2AR == 1) { $newGrowWide = $growWide; } else { $newGrowWide = $r2AR >= 1 ? true : false; } $l2boxes = $this->quantumLayoutParams($l2, $r2, $newGrowWide); } else { $l2boxes[0] = $r2; } $l2FinalBox = $this->computeUnion($l2boxes); if ($debug) { echo "Final R2 box="; $l2FinalBox->Dump(); echo "<br/>"; } } if (count($l3) != 0) { if (count($l3) > 1) { if ($debug) { echo "<b>Recurse on R3</b><br />"; } $r3AR = $r3->aspectRatio(); if ($r3AR == 1) { $newGrowWide = $growWide; } else { $newGrowWide = $r3AR >= 1 ? true : false; } $l3boxes = $this->quantumLayoutParams($l3, $r3, $newGrowWide); } else { $l3boxes[0] = $r3; } $l3FinalBox = $this->computeUnion($l3boxes); if ($debug) { echo "Final R3 box="; $l3FinalBox->Dump(); echo "<br/>"; } } $rp_array = array(); $r3_array = array(); // empty $rp_array[] = $rp; /*echo "rp = "; $rp_array[0]->Dump(); echo "<br />"; echo "l1 = "; $l1FinalBox->Dump(); echo "<br />"; */ if ($debug) { echo '<b>Shift, expand/contract</b><br />'; } if (1) { // Shift and expand/contract the new layouts // depending on the the other sub-layouts if ($growWide) { if ($debug) { echo '<b>gw</b><br/>'; } if (count($l1) > 0) { $rp_array[0]->x = $l1FinalBox->x + $l1FinalBox->w; $rp_array[0]->y = $l1FinalBox->y; if ($debug) { echo "rp = "; $rp_array[0]->Dump(); echo "<br />"; } } if (count($l2) > 0) { if ($debug) { echo __LINE__ . '<br/>'; } $this->translateBoxesTo($l2boxes, $rp_array[0]->x, $rp_array[0]->y + $rp_array[0]->h); if ($debug) { foreach ($l2boxes as $l) { echo "l = "; $l->Dump(); echo "<br />"; } } $this->evenBoxWidth($rp_array, $l2boxes, $r3_array); if ($debug) { foreach ($l2boxes as $l) { echo "l = "; $l->Dump(); echo "<br />"; } } //exit(); if (count($l3) > 0) { $l2FinalBox = $this->computeUnion($l2boxes); if ($debug) { echo l2FinalBox; $l2FinalBox->Dump(); echo "<br />"; } if ($debug) { echo __LINE__ . '<br/>'; } $this->translateBoxesTo($l3boxes, $l2FinalBox->x + $l2FinalBox->w, $rp_array[0]->y); } $this->evenBoxHeight($l1boxes, $l2boxes, $l3boxes); } else { $this->evenBoxHeight($rp_array, $l1boxes, $r3_array); } } else { if ($debug) { echo '<b>no gw</b><br/>'; } if (count($l1) > 0) { $rp_array[0]->x = $l1FinalBox->x; $rp_array[0]->y = $l1FinalBox->y + $l1FinalBox->h; if ($debug) { echo "rp = "; $rp_array[0]->Dump(); echo "<br />"; } } if (count($l2) > 0) { //echo __LINE__. '<br/>'; //print_r($l2boxes); $this->translateBoxesTo($l2boxes, $rp_array[0]->x + $rp_array[0]->w, $rp_array[0]->y); if ($debug) { foreach ($l2boxes as $l) { echo "l = "; $l->Dump(); echo "<br />"; } } $this->evenBoxHeight($rp_array, $l2boxes, $r3_array); //print_r($rp_array); //print_r($l2boxes); if (count($l3) > 0) { $l2FinalBox = $this->computeUnion($l2boxes); if ($debug) { echo l2FinalBox; $l2FinalBox->Dump(); echo "<br />"; } if ($debug) { echo __LINE__ . '<br/>'; } $this->translateBoxesTo($l3boxes, $rp_array[0]->x, $l2FinalBox->y + $l2FinalBox->h); } $this->evenBoxWidth($l1boxes, $l2boxes, $l3boxes); } else { $this->evenBoxWidth($rp_array, $l1boxes, $r3_array); } } } if (count($l1) > 0) { $boxes = array_merge($boxes, $l1boxes); } $boxes[] = $rp_array[0]; if (count($l2) > 0) { $boxes = array_merge($boxes, $l2boxes); } if (count($l3) > 0) { $boxes = array_merge($boxes, $l3boxes); } $boxAR = $box->aspectRatio(); if ($boxAR == 1) { $newGrowWide = $growWide; } else { $newGrowWide = $boxAR >= 1 ? true : false; } if ($debug) { echo '<b>Boxes</b><br />'; foreach ($boxes as $b) { $b->Dump(); echo "<br/>"; } echo 'Return ' . __LINE__ . ''; } if ($debug) { echo '</li>'; echo '</ul>'; } return $boxes; }