Blame | Letzte Änderung | Log anzeigen | RSS feed
<?php// Height constraint "merging" function.//// Constraints have the following precedece:// 1. constant constraint// 2. diapason constraint// 3. no constraint//// If both constraints are constant, the first one is choosen;//// If both constraints are diapason constraints the first one is choosen//function merge_height_constraint($hc1, $hc2) {// First constraint is constant; return this, as second constraint// will never override itif (!is_null($hc1->constant)) { return $hc1; };// Second constraint is constant; first is not constant;// return second, as it is more importantif (!is_null($hc2->constant)) { return $hc2; };// Ok, both constraints are not constant. Check if there's any diapason// constraints// Second constraint is free constraint, return first one, as// if it is a non-free it should have precedence, otherwise// it will be free constraint tooif (is_null($hc2->min) && is_null($hc2->max)) { return $hc1; };// The same rule applied if the first constraint is free constraintif (is_null($hc1->min) && is_null($hc1->max)) { return $hc2; };// If we got here it means both constraints are diapason constraints.return $hc1;}// Height constraint class//// Height could be constrained as a percentage of the parent height OR// as a constant value. Note that in most cases percentage constraint// REQUIRE parent height to be constrained.//// Note that constraint can be given as a diapason from min to max height// It is applied only of no strict height constraint is given//class HCConstraint {var $constant;var $min;var $max;function applicable(&$box) {if (!is_null($this->constant)) {return $this->applicable_value($this->constant, $box);}$applicable_min = false;if (!is_null($this->min)) {$applicable_min = $this->applicable_value($this->min, $box);};$applicable_max = false;if (!is_null($this->max)) {$applicable_max = $this->applicable_value($this->max, $box);};return $applicable_min || $applicable_max;}/*** Since we decided to calculate percentage constraints of the top-level boxes using* the page height as the basis, all height constraint values will be applicable.** In older version, percentage height constraints on top-level boxes were silently ignored and* height was determined by box content*/function applicable_value($value, &$box) {return true;// Constant constraints always applicable// if (!$value[1]) { return true; };// if (!$box->parent) { return false; };// return $box->parent->_height_constraint->applicable($box->parent);}function _fix_value($value, &$box, $default, $no_table_recursion) {// A percentage or immediate value?if ($value[1]) {// CSS 2.1: The percentage is calculated with respect to the height of the generated box's containing block.// If the height of the containing block is not specified explicitly (i.e., it depends on content height),// and this element is not absolutely positioned, the value is interpreted like 'auto'./*** Check if parent exists. If there's no parent, calculate percentage relatively to the page* height (excluding top/bottom margins, of course)*/if (!isset($box->parent) || !$box->parent) {global $g_media;return mm2pt($g_media->real_height()) * $value[0] / 100;}if (!isset($box->parent->parent) || !$box->parent->parent) {global $g_media;return mm2pt($g_media->real_height()) * $value[0] / 100;}// if (!isset($box->parent)) { return null; }// if (!$box->parent) { return null; }// if parent does not have constrained height, return null - no height constraint can be applied// Table cells should be processed separatelyif (!$box->parent->isCell() &&is_null($box->parent->_height_constraint->constant) &&is_null($box->parent->_height_constraint->min) &&is_null($box->parent->_height_constraint->max)) {return $default;};if ($box->parent->isCell()) {if (!$no_table_recursion) {$rhc = $box->parent->parent->get_rhc($box->parent->row);if ($rhc->is_null()) { return $default; };return $rhc->apply($box->parent->get_height(), $box, true) * $value[0] / 100;} else {return $box->parent->parent->get_height() * $value[0] / 100;};};return $box->parent->get_height() * $value[0] / 100;} else {// Immediatereturn $value[0];}}function &create(&$box) {// Determine if there's constant restriction$value = $box->get_css_property(CSS_HEIGHT);if ($value->isAuto($value)) {$constant = null;} elseif ($value->isPercentage()) {$constant = array($value->getPercentage(), true);} else {$constant = array($value->getPoints(), false);};// Determine if there's min restriction$value = $box->get_css_property(CSS_MIN_HEIGHT);if ($value->isAuto($value)) {$min = null;} elseif ($value->isPercentage()) {$min = array($value->getPercentage(), true);} else {$min = array($value->getPoints(), false);};// Determine if there's max restriction$value = $box->get_css_property(CSS_MAX_HEIGHT);if ($value->isAuto($value)) {$max = null;} elseif ($value->isPercentage()) {$max = array($value->getPercentage(), true);} else {$max = array($value->getPoints(), false);};$constraint =& new HCConstraint($constant, $min, $max);return $constraint;}// Height constraint constructor//// @param $constant value of constant constraint or null of none// @param $min value of minimal box height or null if none// @param $max value of maximal box height or null if none//function HCConstraint($constant, $min, $max) {$this->constant = $constant;$this->min = $min;$this->max = $max;}function apply_min($value, &$box, $no_table_recursion) {if (is_null($this->min)) {return $value;} else {return max($this->_fix_value($this->min, $box, $value, $no_table_recursion), $value);}}function apply_max($value, &$box, $no_table_recursion) {if (is_null($this->max)) {return $value;} else {return min($this->_fix_value($this->max, $box, $value, $no_table_recursion), $value);}}function apply($value, &$box, $no_table_recursion = false) {if (!is_null($this->constant)) {$height = $this->_fix_value($this->constant, $box, $value, $no_table_recursion);} else {$height = $this->apply_min($this->apply_max($value, $box, $no_table_recursion), $box, $no_table_recursion);}// Table cells contained in tables with border-collapse: separate// have padding included in the 'height' value. So, we'll need to subtract// vertical-extra from the current value to get the actual content height// TODOreturn $height;}function is_min_null() {if (is_null($this->min)) {return true;};return $this->min[0] == 0;}function is_null() {returnis_null($this->max) &&$this->is_min_null() &&is_null($this->constant);}}?>