[poincare] add a nth root layout

Change-Id: Ib40811700c82ab7aab6cdb9caab0d4557ecb8a69
This commit is contained in:
Émilie Feral
2017-01-04 11:17:53 +01:00
parent 4ef58a4019
commit 0bc13c65b2
5 changed files with 147 additions and 0 deletions

View File

@@ -36,6 +36,7 @@ objs += $(addprefix poincare/src/layout/,\
fraction_layout.o\
horizontal_layout.o\
matrix_layout.o\
nth_root_layout.o\
string_layout.o\
)

View File

@@ -10,6 +10,7 @@ public:
Type type() const override;
Expression * cloneWithDifferentOperands(Expression ** newOperands,
int numberOfOperands, bool cloneOperands = true) const override;
ExpressionLayout * createLayout() const override;
};
#endif

View File

@@ -0,0 +1,113 @@
#include <string.h>
#include <assert.h>
#include "nth_root_layout.h"
const uint8_t radixPixel[NthRootLayout::k_leftRadixHeight][NthRootLayout::k_leftRadixWidth] = {
{0x00, 0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0x00, 0xFF, 0xFF, 0xFF},
{0xFF, 0x00, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0x00, 0xFF, 0xFF},
{0xFF, 0xFF, 0x00, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0x00, 0xFF},
{0xFF, 0xFF, 0xFF, 0x00, 0xFF},
{0xFF, 0xFF, 0xFF, 0xFF, 0x00},
};
NthRootLayout::NthRootLayout(ExpressionLayout * radicandLayout, ExpressionLayout * indexLayout) :
ExpressionLayout(),
m_radicandLayout(radicandLayout),
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_leftRadixHeight - m_radicandLayout->size().height() - k_heightMargin + m_radicandLayout->baseline());
}
NthRootLayout::~NthRootLayout() {
delete m_radicandLayout;
delete m_indexLayout;
}
void NthRootLayout::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) {
KDSize radicandSize = m_radicandLayout->size();
KDSize indexSize = m_indexLayout->size();
KDColor workingBuffer[k_leftRadixWidth*k_leftRadixHeight];
KDRect leftRadixFrame(p.x() + indexSize.width() + k_widthMargin - k_leftRadixWidth,
p.y() + max(indexSize.height(), k_radixLineThickness+2*k_heightMargin+radicandSize.height()-k_leftRadixHeight),
k_leftRadixWidth, k_leftRadixHeight);
ctx->blendRectWithMask(leftRadixFrame, expressionColor, (const uint8_t *)radixPixel, (KDColor *)workingBuffer);
if (indexSize.height() + k_leftRadixHeight > k_radixLineThickness + radicandSize.height() + 2*k_heightMargin) {
ctx->fillRect(KDRect(p.x() + indexSize.width() + k_widthMargin,
p.y() + indexSize.height() + k_leftRadixHeight - radicandSize.height() - k_radixLineThickness - 2*k_heightMargin,
k_radixLineThickness,
radicandSize.height() + 2*k_heightMargin + k_radixLineThickness), expressionColor);
ctx->fillRect(KDRect(p.x() + indexSize.width() + k_widthMargin,
p.y() + indexSize.height() + k_leftRadixHeight - radicandSize.height() - k_radixLineThickness - 2*k_heightMargin,
radicandSize.width() + 2*k_widthMargin,
k_radixLineThickness), expressionColor);
ctx->fillRect(KDRect(p.x() + indexSize.width() + k_widthMargin + radicandSize.width() + 2*k_widthMargin,
p.y() + indexSize.height() + k_leftRadixHeight - radicandSize.height() - k_radixLineThickness - 2*k_heightMargin,
k_radixLineThickness,
k_rightRadixHeight + k_radixLineThickness), expressionColor);
} else {
ctx->fillRect(KDRect(p.x() + indexSize.width() + k_widthMargin,
p.y(),
k_radixLineThickness,
radicandSize.height() + 2*k_heightMargin + k_radixLineThickness), expressionColor);
ctx->fillRect(KDRect(p.x() + indexSize.width() + k_widthMargin,
p.y(),
radicandSize.width() + 2*k_widthMargin,
k_radixLineThickness), expressionColor);
ctx->fillRect(KDRect(p.x() + indexSize.width() + k_widthMargin + radicandSize.width() + 2*k_widthMargin,
p.y(),
k_radixLineThickness,
k_rightRadixHeight + k_radixLineThickness), expressionColor);
}
}
KDSize NthRootLayout::computeSize() {
KDSize radicandSize = m_radicandLayout->size();
KDSize indexSize = m_indexLayout->size();
return KDSize(
indexSize.width() + 3*k_widthMargin + 2*k_radixLineThickness + radicandSize.width(),
max(k_radixLineThickness + 2*k_heightMargin + radicandSize.height(), indexSize.height() + k_leftRadixHeight)
);
}
ExpressionLayout * NthRootLayout::child(uint16_t index) {
switch (index) {
case 0:
return m_indexLayout;
case 1:
return m_radicandLayout;
default:
return nullptr;
}
}
KDPoint NthRootLayout::positionOfChild(ExpressionLayout * child) {
KDCoordinate x = 0;
KDCoordinate y = 0;
KDSize radicandSize = m_radicandLayout->size();
KDSize indexSize = m_indexLayout->size();
if (child == m_indexLayout) {
x = 0;
if (indexSize.height() + k_leftRadixHeight > k_radixLineThickness + radicandSize.height() + 2*k_heightMargin) {
y = 0;
} else {
y = k_radixLineThickness+2*k_heightMargin+radicandSize.height()-k_leftRadixHeight - indexSize.height();
}
} else if (child == m_radicandLayout) {
x = indexSize.width() + 2*k_widthMargin + k_radixLineThickness;
if (indexSize.height() + k_leftRadixHeight > k_radixLineThickness + radicandSize.height() + 2*k_heightMargin) {
y = indexSize.height() + k_leftRadixHeight - radicandSize.height() - k_heightMargin;
} else {
y = k_radixLineThickness + k_heightMargin;
}
} else {
assert(false);
}
return KDPoint(x,y);
}

View File

@@ -0,0 +1,27 @@
#ifndef POINCARE_NTH_ROOT_LAYOUT_H
#define POINCARE_NTH_ROOT_LAYOUT_H
#include <poincare/expression.h>
#include <poincare/expression_layout.h>
class NthRootLayout : public ExpressionLayout {
public:
NthRootLayout(ExpressionLayout * radicandLayout, ExpressionLayout * indexLayout);
~NthRootLayout();
constexpr static KDCoordinate k_leftRadixHeight = 8;
constexpr static KDCoordinate k_leftRadixWidth = 5;
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_rightRadixHeight = 2;
constexpr static KDCoordinate k_heightMargin = 2;
constexpr static KDCoordinate k_widthMargin = 1;
constexpr static KDCoordinate k_radixLineThickness = 1;
ExpressionLayout * m_radicandLayout;
ExpressionLayout * m_indexLayout;
};
#endif

View File

@@ -1,4 +1,5 @@
#include <poincare/nth_root.h>
#include "layout/nth_root_layout.h"
extern "C" {
#include <assert.h>
@@ -26,3 +27,7 @@ Expression * NthRoot::cloneWithDifferentOperands(Expression** newOperands,
float NthRoot::approximate(Context& context) const {
return powf(m_args[0]->approximate(context), 1.0f/m_args[1]->approximate(context));
}
ExpressionLayout * NthRoot::createLayout() const {
return new NthRootLayout(m_args[0]->createLayout(), m_args[1]->createLayout());
}