Exemple #1
0
 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;
 }