Esempio n. 1
0
 /**
  * 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());
 }
Esempio n. 2
0
 /**
  * @covers       round
  * @dataProvider getDataForRoundTest
  */
 public function testRound($value, $precision, $expected)
 {
     $this->assertEquals($expected, Math::round($value, $precision), sprintf('Rounding of "%s" with precision "%s" works', $value, $precision));
 }
Esempio n. 3
0
 /**
  * Returns the 'value' channel of @color in the HSV space
  *
  * @param ColorNode $color
  * @return string
  */
 public function hsvvalue(Node $color)
 {
     if (!$color instanceof ColorNode) {
         return $color;
     }
     $hsv = $color->toHSV();
     return new DimensionNode(Math::round($hsv['v'] * 100), '%');
 }
Esempio n. 4
0
 /**
  * Round the value using the `$context->precision` setting.
  *
  * @param Context $context
  * @param mixed $value
  *
  * @return string
  */
 public static function round(Context $context, $value)
 {
     // add "epsilon" to ensure numbers like 1.000000005 (represented as 1.000000004999....) are properly rounded...
     return $context->numPrecision === null ? $value : Math::toFixed($value + 2.0E-16, $context->numPrecision);
 }
Esempio n. 5
0
File: Color.php Progetto: jxav/iless
 /**
  * Returns the color as HEX string (when transparency present, in RGBA model)
  *
  * @param boolean $compress Compress the color?
  * @param boolean $canShorten Can the color be shortened if possible?
  * @return string
  */
 public function toString($compress = false, $canShorten = false)
 {
     if ($this->isTransparentKeyword) {
         return 'transparent';
     }
     if ($this->originalForm) {
         return $this->originalForm;
     }
     $alpha = Math::toFixed($this->alpha + 2.0E-16, 8);
     if ($alpha < 1) {
         $fixedRGB = $this->getFixedRGB();
         return sprintf('rgba(%s)', join($compress ? ',' : ', ', [$fixedRGB[0], $fixedRGB[1], $fixedRGB[2], Math::clean($this->clamp($alpha, 1))]));
     }
     // prevent named colors
     if ($this->keyword) {
         return $this->keyword;
     }
     $color = [];
     foreach ($this->getFixedRgb() as $i) {
         $color[] = str_pad(dechex(Math::round($i)), 2, '0', STR_PAD_LEFT);
     }
     $color = join('', $color);
     // convert color to short format
     if ($canShorten && $color[0] === $color[1] && $color[2] === $color[3] && $color[4] === $color[5]) {
         $color = $color[0] . $color[2] . $color[4];
     }
     $color = '#' . $color;
     return $color;
 }
Esempio n. 6
0
 /**
  * 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);
 }