/** * Operations have to be done per-channel, if not, * channels will spill onto each other. Once we have * our result, in the form of an integer triplet, * we create a new color node to hold the result. * * @param Context $context * @param string $op * @param Node $other * @return ColorNode * @throws InvalidArgumentException */ public function operate(Context $context, $op, Node $other) { $result = []; if (!$other instanceof ColorNode) { if (!$other instanceof ToColorConvertibleInterface) { throw new InvalidArgumentException('The other node must implement toColor() method to operate, see ILess\\Node\\Node_ToColorConvertibleInterface'); } $other = $other->toColor(); if (!$other instanceof ColorNode) { throw new InvalidArgumentException('The toColor() method must return an instance of ILess\\Node\\Node_Color'); } } $t = $this->getRGB(); $o = $other->getRGB(); for ($c = 0; $c < 3; $c++) { $result[$c] = Math::operate($op, $t[$c], $o[$c]); if ($result[$c] > 255) { $result[$c] = 255; } elseif ($result < 0) { $result[$c] = 0; } } return new ColorNode($result, $this->value->getAlpha() + $other->value->getAlpha()); }
/** * Operates with the dimension. In an operation between two dimensions, * we default to the first Dimension's unit, * so `1px + 2` will yield `3px`. * * @param Context $context * @param string $op * @param DimensionNode $other * @return DimensionNode * @throws CompilerException */ public function operate(Context $context, $op, DimensionNode $other) { $value = Math::operate($op, $this->value, $other->value); $unit = clone $this->unit; if ($op === '+' || $op === '-') { if (!count($unit->numerator) && !count($unit->denominator)) { $unit = clone $other->unit; if ($this->unit->backupUnit) { $unit->backupUnit = $this->unit->backupUnit; } } elseif (!count($other->unit->numerator) && !count($other->unit->denominator)) { // do nothing } else { $other = $other->convertTo($this->unit->usedUnits()); if ($context->strictUnits && $other->unit->toString() !== $unit->toString()) { throw new CompilerException(sprintf('Incompatible units. Change the units or use the unit function. Bad units: \'%s\' and \'%s\'.', $unit->toString(), $other->unit->toString())); } $value = Math::operate($op, $this->value, $other->value); } } elseif ($op === '*') { $unit->numerator = array_merge($unit->numerator, $other->unit->numerator); $unit->denominator = array_merge($unit->denominator, $other->unit->denominator); sort($unit->numerator); sort($unit->denominator); $unit->cancel(); } elseif ($op === '/') { $unit->numerator = array_merge($unit->numerator, $other->unit->denominator); $unit->denominator = array_merge($unit->denominator, $other->unit->numerator); sort($unit->numerator); sort($unit->denominator); $unit->cancel(); } return new DimensionNode($value, $unit); }