diff --git a/poincare/Makefile b/poincare/Makefile index 3ada6fb0c..dc1bc7fa5 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -37,6 +37,7 @@ objs += $(addprefix poincare/src/layout/,\ horizontal_layout.o\ matrix_layout.o\ nth_root_layout.o\ + parenthesis_layout.o\ string_layout.o\ ) diff --git a/poincare/src/layout/parenthesis_layout.cpp b/poincare/src/layout/parenthesis_layout.cpp new file mode 100644 index 000000000..7c92bc34c --- /dev/null +++ b/poincare/src/layout/parenthesis_layout.cpp @@ -0,0 +1,92 @@ +#include "parenthesis_layout.h" +extern "C" { +#include +#include +} + +const uint8_t topLeftCurve[ParenthesisLayout::k_parenthesisCurveHeight][ParenthesisLayout::k_parenthesisCurveWidth] = { + {0xFF, 0xFF, 0xFF, 0xFF, 0x00}, + {0xFF, 0xFF, 0xFF, 0x00, 0xFF}, + {0xFF, 0xFF, 0x00, 0xFF, 0xFF}, + {0xFF, 0x00, 0xFF, 0xFF, 0xFF}, + {0xFF, 0x00, 0xFF, 0xFF, 0xFF}, + {0x00, 0xFF, 0xFF, 0xFF, 0xFF}, + +}; + +const uint8_t bottomLeftCurve[ParenthesisLayout::k_parenthesisCurveHeight][ParenthesisLayout::k_parenthesisCurveWidth] = { + {0x00, 0xFF, 0xFF, 0xFF, 0xFF}, + {0xFF, 0x00, 0xFF, 0xFF, 0xFF}, + {0xFF, 0x00, 0xFF, 0xFF, 0xFF}, + {0xFF, 0xFF, 0x00, 0xFF, 0xFF}, + {0xFF, 0xFF, 0xFF, 0x00, 0xFF}, + {0xFF, 0xFF, 0xFF, 0xFF, 0x00}, + +}; + +const uint8_t topRightCurve[ParenthesisLayout::k_parenthesisCurveHeight][ParenthesisLayout::k_parenthesisCurveWidth] = { + {0x00, 0xFF, 0xFF, 0xFF, 0xFF}, + {0xFF, 0x00, 0xFF, 0xFF, 0xFF}, + {0xFF, 0xFF, 0x00, 0xFF, 0xFF}, + {0xFF, 0xFF, 0xFF, 0x00, 0xFF}, + {0xFF, 0xFF, 0xFF, 0x00, 0xFF}, + {0xFF, 0xFF, 0xFF, 0xFF, 0x00}, + +}; + +const uint8_t bottomRightCurve[ParenthesisLayout::k_parenthesisCurveHeight][ParenthesisLayout::k_parenthesisCurveWidth] = { + {0xFF, 0xFF, 0xFF, 0xFF, 0x00}, + {0xFF, 0xFF, 0xFF, 0x00, 0xFF}, + {0xFF, 0xFF, 0xFF, 0x00, 0xFF}, + {0xFF, 0xFF, 0x00, 0xFF, 0xFF}, + {0xFF, 0x00, 0xFF, 0xFF, 0xFF}, + {0x00, 0xFF, 0xFF, 0xFF, 0xFF}, + +}; + +ParenthesisLayout::ParenthesisLayout(ExpressionLayout * operandLayout) : + ExpressionLayout(), + m_operandLayout(operandLayout) +{ + m_operandLayout->setParent(this); + m_baseline = m_operandLayout->baseline() + k_heightMargin; +} + +ParenthesisLayout::~ParenthesisLayout() { + delete m_operandLayout; +} + +void ParenthesisLayout::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) { + KDSize operandSize = m_operandLayout->size(); + KDColor workingBuffer[k_parenthesisCurveHeight*k_parenthesisCurveWidth]; + KDRect frame(p.x(), p.y(), k_parenthesisCurveWidth, k_parenthesisCurveHeight); + ctx->blendRectWithMask(frame, expressionColor, (const uint8_t *)topLeftCurve, (KDColor *)workingBuffer); + frame = KDRect(p.x(), p.y() + operandSize.height() + 2*k_heightMargin - k_parenthesisCurveHeight, + k_parenthesisCurveWidth, k_parenthesisCurveHeight); + ctx->blendRectWithMask(frame, expressionColor, (const uint8_t *)bottomLeftCurve, (KDColor *)workingBuffer); + frame = KDRect(p.x() + operandSize.width() + 2*k_widthMargin + 2*k_lineThickness - k_parenthesisCurveWidth, p.y(), + k_parenthesisCurveWidth, k_parenthesisCurveHeight); + ctx->blendRectWithMask(frame, expressionColor, (const uint8_t *)topRightCurve, (KDColor *)workingBuffer); + frame = KDRect(p.x() + operandSize.width() + 2*k_widthMargin + 2*k_lineThickness - k_parenthesisCurveWidth, p.y() + operandSize.height() + 2*k_heightMargin - k_parenthesisCurveHeight, + k_parenthesisCurveWidth, k_parenthesisCurveHeight); + ctx->blendRectWithMask(frame, expressionColor, (const uint8_t *)bottomRightCurve, (KDColor *)workingBuffer); + + ctx->fillRect(KDRect(p.x(), p.y()+k_parenthesisCurveHeight, k_lineThickness, m_operandLayout->size().height()+2*k_heightMargin - 2*k_parenthesisCurveHeight), expressionColor); + ctx->fillRect(KDRect(p.x()+operandSize.width()+2*k_widthMargin+k_lineThickness, p.y()+k_parenthesisCurveHeight, k_lineThickness, m_operandLayout->size().height()+2*k_heightMargin - 2*k_parenthesisCurveHeight), expressionColor); +} + +KDSize ParenthesisLayout::computeSize() { + KDSize operandSize = m_operandLayout->size(); + return KDSize(operandSize.width() + 2*k_widthMargin + 2*k_lineThickness, operandSize.height()+2*k_heightMargin); +} + +ExpressionLayout * ParenthesisLayout::child(uint16_t index) { + if (index == 0) { + return m_operandLayout; + } + return nullptr; +} + +KDPoint ParenthesisLayout::positionOfChild(ExpressionLayout * child) { + return KDPoint(k_widthMargin+k_lineThickness, k_heightMargin); +} diff --git a/poincare/src/layout/parenthesis_layout.h b/poincare/src/layout/parenthesis_layout.h new file mode 100644 index 000000000..dc3c87772 --- /dev/null +++ b/poincare/src/layout/parenthesis_layout.h @@ -0,0 +1,25 @@ +#ifndef POINCARE_PARENTHESIS_LAYOUT_H +#define POINCARE_PARENTHESIS_LAYOUT_H + +#include +#include + +class ParenthesisLayout : public ExpressionLayout { +public: + ParenthesisLayout(ExpressionLayout * operandLayout); + ~ParenthesisLayout(); + constexpr static KDCoordinate k_parenthesisCurveWidth = 5; + constexpr static KDCoordinate k_parenthesisCurveHeight = 6; +protected: + void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) override; + KDSize computeSize() override; + ExpressionLayout * child(uint16_t index) override; + KDPoint positionOfChild(ExpressionLayout * child) override; +private: + constexpr static KDCoordinate k_widthMargin = 2; + constexpr static KDCoordinate k_heightMargin = 3; + constexpr static KDCoordinate k_lineThickness = 1; + ExpressionLayout * m_operandLayout; +}; + +#endif diff --git a/poincare/src/parenthesis.cpp b/poincare/src/parenthesis.cpp index a59a7ad7d..250f82a35 100644 --- a/poincare/src/parenthesis.cpp +++ b/poincare/src/parenthesis.cpp @@ -3,8 +3,7 @@ extern "C" { #include } #include -#include "layout/horizontal_layout.h" -#include "layout/string_layout.h" +#include "layout/parenthesis_layout.h" Parenthesis::Parenthesis(Expression * operand, bool cloneOperands) { assert(operand != nullptr); @@ -33,12 +32,7 @@ Expression * Parenthesis::clone() const { } ExpressionLayout * Parenthesis::createLayout() const { - // TODO: create a parenthesis layout to adjust parenthesis sizes to the operand - ExpressionLayout ** childrenLayouts = (ExpressionLayout **)malloc(3*sizeof(ExpressionLayout *)); - childrenLayouts[0] = new StringLayout("(", 1); - childrenLayouts[1] = m_operand->createLayout(); - childrenLayouts[2] = new StringLayout(")", 1); - return new HorizontalLayout(childrenLayouts, 3); + return new ParenthesisLayout(m_operand->createLayout()); } float Parenthesis::approximate(Context& context) const {