diff --git a/ion/src/shared/events.cpp b/ion/src/shared/events.cpp index a0e8246bd..0ce13fbdd 100644 --- a/ion/src/shared/events.cpp +++ b/ion/src/shared/events.cpp @@ -30,7 +30,7 @@ static constexpr EventData s_dataForEvent[] = { TL(), TL(), U(), U(), U(), U(), TL(), TL(), TL(), TL(), TL(), TL(), T("exp()"), T("ln()"), T("log()"), T("i"), T(","), T("^"), - T("sin()"), T("cos()"), T("tan()"), T("Pi"), T("sqrt()"), T("^2"), + T("sin()"), T("cos()"), T("tan()"), T("Pi"), T("v()"), T("^2"), T("7"), T("8"), T("9"), T("("), T(")"), U(), T("4"), T("5"), T("6"), T("*"), T("/"), U(), T("1"), T("2"), T("3"), T("+"), T("-"), U(), diff --git a/poincare/Makefile b/poincare/Makefile index aec11f95f..25aa347aa 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -32,6 +32,7 @@ objs += $(addprefix poincare/src/,\ power.o\ product.o\ sine.o\ + square_root.o\ subtraction.o\ sum.o\ symbol.o\ diff --git a/poincare/include/poincare.h b/poincare/include/poincare.h index 387efde16..39eaa3586 100644 --- a/poincare/include/poincare.h +++ b/poincare/include/poincare.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 238fbabab..3d18919d9 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -28,6 +28,7 @@ class Expression { Power, Product, Sine, + SquareRoot, Sum, Subtraction, Symbol, diff --git a/poincare/include/poincare/square_root.h b/poincare/include/poincare/square_root.h new file mode 100644 index 000000000..766d7d753 --- /dev/null +++ b/poincare/include/poincare/square_root.h @@ -0,0 +1,16 @@ +#ifndef POINCARE_SQUARE_ROOT_H +#define POINCARE_SQUARE_ROOT_H + +#include + +class SquareRoot : public Function { +public: + SquareRoot(); + float approximate(Context & context) const override; + Type type() const override; + Expression * cloneWithDifferentOperands(Expression ** newOperands, + int numberOfOperands, bool cloneOperands = true) const override; + ExpressionLayout * createLayout() const override; +}; + +#endif diff --git a/poincare/src/expression_lexer.l b/poincare/src/expression_lexer.l index 008d34968..90b1a9838 100644 --- a/poincare/src/expression_lexer.l +++ b/poincare/src/expression_lexer.l @@ -93,6 +93,7 @@ root { poincare_expression_yylval.expression = new NthRoot(); return FUNCTION; } sum { poincare_expression_yylval.expression = new Sum(); return FUNCTION; } product { poincare_expression_yylval.expression = new Product(); return FUNCTION; } Pi { poincare_expression_yylval.character = Symbol::SpecialSymbols::Pi; return SYMBOL; } +v { poincare_expression_yylval.expression = new SquareRoot(); return FUNCTION; } \+ { return PLUS; } \- { return MINUS; } \* { return MULTIPLY; } diff --git a/poincare/src/layout/nth_root_layout.cpp b/poincare/src/layout/nth_root_layout.cpp index 4e0664763..a178ca196 100644 --- a/poincare/src/layout/nth_root_layout.cpp +++ b/poincare/src/layout/nth_root_layout.cpp @@ -19,25 +19,31 @@ NthRootLayout::NthRootLayout(ExpressionLayout * radicandLayout, ExpressionLayout m_indexLayout(indexLayout) { m_radicandLayout->setParent(this); - m_indexLayout->setParent(this); - m_baseline = max(m_radicandLayout->baseline() + k_radixLineThickness + k_heightMargin, - m_indexLayout->size().height() + k_indexHeight); + if (m_indexLayout != nullptr) { + m_indexLayout->setParent(this); + m_baseline = max(m_radicandLayout->baseline() + k_radixLineThickness + k_heightMargin, + m_indexLayout->size().height() + k_indexHeight); + } else { + m_baseline = m_radicandLayout->baseline() + k_radixLineThickness + k_heightMargin; + } } NthRootLayout::~NthRootLayout() { delete m_radicandLayout; - delete m_indexLayout; + if (m_indexLayout != nullptr) { + delete m_indexLayout; + } } void NthRootLayout::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) { KDSize radicandSize = m_radicandLayout->size(); - KDSize indexSize = m_indexLayout->size(); + KDSize indexSize = m_indexLayout != nullptr ? m_indexLayout->size() : KDSize(k_leftRadixWidth,0); KDColor workingBuffer[k_leftRadixWidth*k_leftRadixHeight]; KDRect leftRadixFrame(p.x() + indexSize.width() + k_widthMargin - k_leftRadixWidth, p.y() + m_baseline + radicandSize.height() - m_radicandLayout->baseline() + k_heightMargin - k_leftRadixHeight, k_leftRadixWidth, k_leftRadixHeight); ctx->blendRectWithMask(leftRadixFrame, expressionColor, (const uint8_t *)radixPixel, (KDColor *)workingBuffer); - if (m_indexLayout->size().height() + k_indexHeight > m_radicandLayout->baseline() + k_radixLineThickness + k_heightMargin) { + if (indexSize.height() + k_indexHeight > m_radicandLayout->baseline() + k_radixLineThickness + k_heightMargin) { ctx->fillRect(KDRect(p.x() + indexSize.width() + k_widthMargin, p.y() + indexSize.height() + k_indexHeight - m_radicandLayout->baseline() - k_radixLineThickness - k_heightMargin, k_radixLineThickness, @@ -69,7 +75,7 @@ void NthRootLayout::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDSize NthRootLayout::computeSize() { KDSize radicandSize = m_radicandLayout->size(); - KDSize indexSize = m_indexLayout->size(); + KDSize indexSize = m_indexLayout != nullptr ? m_indexLayout->size() : KDSize(k_leftRadixWidth,0); return KDSize( indexSize.width() + 3*k_widthMargin + 2*k_radixLineThickness + radicandSize.width(), m_baseline + radicandSize.height() - m_radicandLayout->baseline() + k_heightMargin @@ -79,9 +85,9 @@ KDSize NthRootLayout::computeSize() { ExpressionLayout * NthRootLayout::child(uint16_t index) { switch (index) { case 0: - return m_indexLayout; - case 1: return m_radicandLayout; + case 1: + return m_indexLayout; default: return nullptr; } @@ -90,7 +96,7 @@ ExpressionLayout * NthRootLayout::child(uint16_t index) { KDPoint NthRootLayout::positionOfChild(ExpressionLayout * child) { KDCoordinate x = 0; KDCoordinate y = 0; - KDSize indexSize = m_indexLayout->size(); + KDSize indexSize = m_indexLayout != nullptr ? m_indexLayout->size() : KDSize(k_leftRadixWidth,0); if (child == m_indexLayout) { x = 0; y = m_baseline - indexSize.height() - k_indexHeight; diff --git a/poincare/src/square_root.cpp b/poincare/src/square_root.cpp new file mode 100644 index 000000000..2456de922 --- /dev/null +++ b/poincare/src/square_root.cpp @@ -0,0 +1,33 @@ +#include +#include "layout/nth_root_layout.h" + +extern "C" { +#include +#include +} + +SquareRoot::SquareRoot() : + Function("v") +{ +} + +Expression::Type SquareRoot::type() const { + return Type::SquareRoot; +} + +Expression * SquareRoot::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) const { + assert(numberOfOperands == 1); + assert(newOperands != nullptr); + SquareRoot * sr = new SquareRoot(); + sr->setArgument(newOperands, numberOfOperands, cloneOperands); + return sr; +} + +float SquareRoot::approximate(Context& context) const { + return powf(m_args[0]->approximate(context), 1.0f/2.0f); +} + +ExpressionLayout * SquareRoot::createLayout() const { + return new NthRootLayout(m_args[0]->createLayout(),nullptr); +} \ No newline at end of file