Value* Color::multiply(Value* v) { Color* c; NumberValue* n; int result; if (v->type == COLOR) { c = static_cast<Color*>(v); result = color[RGB_RED] * c->getRed(); color[RGB_RED] = max(min(result, 255), 0); result = color[RGB_GREEN] * c->getGreen(); color[RGB_GREEN] = max(min(result, 255), 0); result = color[RGB_BLUE] * c->getBlue(); color[RGB_BLUE] = max(min(result, 255), 0); } else if (v->type == Value::NUMBER || v->type == Value::PERCENTAGE || v->type == Value::DIMENSION) { n = static_cast<NumberValue*>(v); color[RGB_RED] *= n->getValue(); color[RGB_GREEN] *= n->getValue(); color[RGB_BLUE] *= n->getValue(); } else { throw new ValueException("You can only multiply a color by a \ color or a number."); } valueChanged = true; return this; }
Value* Color::substract(Value* v) { Color* c; NumberValue* n; if (v->type == COLOR) { c = static_cast<Color*>(v); color[RGB_RED] = color[RGB_RED] > c->getRed() ? color[RGB_RED] - c->getRed() : 0; color[RGB_GREEN] = color[RGB_GREEN] > c->getGreen() ? color[RGB_GREEN] - c->getGreen() : 0; color[RGB_BLUE] = color[RGB_BLUE] > c->getBlue() ? color[RGB_BLUE] - c->getBlue() : 0; } else if (v->type == Value::NUMBER || v->type == Value::PERCENTAGE || v->type == Value::DIMENSION) { n = static_cast<NumberValue*>(v); color[RGB_RED] -= n->getValue(); color[RGB_GREEN] -= n->getValue(); color[RGB_BLUE] -= n->getValue(); } else { throw new ValueException("You can only substract a color or \ a number from a color."); } valueChanged = true; return this; }
Value* Color::add(Value* v) { Color* c; NumberValue* n; StringValue* s; string* str; if (v->type == COLOR) { c = static_cast<Color*>(v); color[RGB_RED] += c->getRed(); color[RGB_GREEN] += c->getGreen(); color[RGB_BLUE] += c->getBlue(); } else if (v->type == NUMBER || v->type == PERCENTAGE || v->type == DIMENSION) { n = static_cast<NumberValue*>(v); color[RGB_RED] += n->getValue(); color[RGB_GREEN] += n->getValue(); color[RGB_BLUE] += n->getValue(); } else if(v->type == STRING) { str = this->getTokens()->toString(); s = new StringValue(new Token(*str, Token::STRING), ((StringValue*)v)->getQuotes()); s->add(v); delete str; return s; } valueChanged = true; return this; }
Value* NumberValue::tan(const vector<const Value*> &args) { if (args[0]->type != Value::NUMBER && args[0]->type != Value::DIMENSION) { throw new ValueException("tan() only works on numbers " "or dimensions", *args[0]->getTokens()); } NumberValue* n = new NumberValue(*(const NumberValue*)args[0]); double val = n->getValue(); std::string unit; if (n->type == Value::DIMENSION) { unit = n->getUnit(); if(unit.compare("rad") != 0 && unit.compare("deg") != 0 && unit.compare("grad") != 0 && unit.compare("turn") != 0) { throw new ValueException("ta() requires rad, deg, " "grad or turn units.", *args[0]->getTokens()); } val = UnitValue::angleToRad(val, unit); } n->setValue(std::tan(val)); n->type = Value::NUMBER; n->setUnit(""); return n; }
Value* NumberValue::multiply(const Value &v) const { const NumberValue* n; NumberValue* ret; if (isNumber(v)) { n = static_cast<const NumberValue*>(&v); ret = new NumberValue(getValue()); if (type == NUMBER) ret->setType(*n); else { ret->setType(*this); ret->verifyUnits(*n); } ret->setValue(ret->getValue() * n->getValue()); return ret; } else if (v.type == COLOR) { return static_cast<const Color*>(&v)->multiply(*this); } else if(v.type == STRING) { return static_cast<const StringValue*>(&v)->multiply(*this); } else { throw new ValueException("Unsupported type.", *this->getTokens()); } }
Value* NumberValue::add(const Value &v) const { const NumberValue* n; const StringValue* s; NumberValue* nret; StringValue* sret; if (isNumber(v)) { n = static_cast<const NumberValue*>(&v); nret = new NumberValue(getValue()); if (type == NUMBER) nret->setType(*n); else { nret->setType(*this); nret->verifyUnits(*n); } nret->setValue(nret->getValue() + n->getValue()); return nret; } else if (v.type == COLOR) { return static_cast<const Color*>(&v)->add(*this); } else if (v.type == STRING) { s = static_cast<const StringValue*>(&v); sret = new StringValue(*this, s->getQuotes()); sret->append(v); return sret; } else { throw new ValueException("Unsupported type.", *this->getTokens()); } }
Value* NumberValue::atan(const vector<const Value*> &args) { NumberValue* n = new NumberValue(*(const NumberValue*)args[0]); n->setValue(std::atan(n->getValue())); n->setUnit("rad"); n->type = Value::DIMENSION; return n; }
Value* NumberValue::abs(const vector<const Value*> &args) { if (!NumberValue::isNumber(*args[0])) throw new ValueException("abs() only works on numeric " "values", *args[0]->getTokens()); NumberValue* n = new NumberValue(*(const NumberValue*)args[0]); n->setValue(fabs(n->getValue())); return n; }
Value* NumberValue::pow(const vector<const Value*> &args) { if (!NumberValue::isNumber(*args[0])) throw new ValueException("pow() only works on numeric values", *args[0]->getTokens()); NumberValue* n = new NumberValue(*(const NumberValue*)args[0]); double exp = ((const NumberValue*)args[1])->getValue(); n->setValue(std::pow(n->getValue(), exp)); return n; }
Value* NumberValue::mod(const vector<const Value*> &args) { if (!NumberValue::isNumber(*args[0]) || !NumberValue::isNumber(*args[1])) throw new ValueException("mod() only works on numeric values", *args[0]->getTokens()); NumberValue* n = new NumberValue(*(const NumberValue*)args[0]); double val2 = ((NumberValue*)args[1])->getValue(); n->setValue(std::fmod(n->getValue(), val2)); return n; }
Value* NumberValue::floor(const vector<const Value*> &args) { NumberValue *n; if (!NumberValue::isNumber(*args[0])) throw new ValueException("floor() only works on numeric " "values", *args[0]->getTokens()); n = new NumberValue(*static_cast<const NumberValue*>(args[0])); double val = n->getValue(); n->setValue(std::floor(val)); return n; }
Value* Color::divide(Value* v) { Color* c; NumberValue* n; if (v->type == COLOR) { c = static_cast<Color*>(v); color[RGB_RED] /= c->getRed(); color[RGB_GREEN] /= c->getGreen(); color[RGB_BLUE] /= c->getBlue(); } else if (v->type == Value::NUMBER || v->type == Value::PERCENTAGE || v->type == Value::DIMENSION){ n = static_cast<NumberValue*>(v); color[RGB_RED] /= n->getValue(); color[RGB_GREEN] /= n->getValue(); color[RGB_BLUE] /= n->getValue(); } else { throw new ValueException("You can only divide a color by a \ color or a number."); } valueChanged = true; return this; }
Value* NumberValue::round(const vector<const Value*> &args) { if (!NumberValue::isNumber(*args[0])) throw new ValueException("round() only works on numeric " "values", *args[0]->getTokens()); NumberValue* n = new NumberValue(*(const NumberValue*)args[0]); double val = n->getValue(); double decimalplaces = 0; if (args.size() > 1) decimalplaces = ((const NumberValue*)args[1])->getValue(); val = val * std::pow(10, decimalplaces); val = std::floor(val + 0.5); val = val / std::pow(10, decimalplaces); n->setValue(val); return n; }
Value* NumberValue::divide(const Value &v) const { const NumberValue* n; NumberValue* ret; if (isNumber(v)) { n = static_cast<const NumberValue*>(&v); ret = new NumberValue(getValue()); if (type == NUMBER) ret->setType(*n); else { ret->setType(*this); ret->verifyUnits(*n); } ret->setValue(ret->getValue() / n->getValue()); return ret; } else throw new ValueException("You can only divide a number " "by a *number*.", *this->getTokens()); }
Value* NumberValue::substract(const Value &v) const { const NumberValue* n; NumberValue* ret; if (isNumber(v)) { n = static_cast<const NumberValue*>(&v); ret = new NumberValue(getValue()); if (type == NUMBER) ret->setType(*n); else { ret->setType(*this); ret->verifyUnits(*n); } ret->setValue(ret->getValue() - n->getValue()); return ret; } else throw new ValueException("You can only substract a " "*number* from a number.", *this->getTokens()); }