Merge changes I59149dfd,I73821aec,Ie9f10058,I0d41d9b9,I0bd84672, ...

* changes:
  [poincare] improve the sum layout
  [poincare] create a sum layout
  [poincare] Improve integral layout
  [poincare] Create a class integral layout
  [poincare] Improve logarithm layout
  [poincare] Create a class subscript layout
This commit is contained in:
Émilie Feral
2017-01-27 10:33:24 +01:00
committed by Gerrit
14 changed files with 354 additions and 2 deletions

View File

@@ -42,10 +42,13 @@ objs += $(addprefix poincare/src/layout/,\
expression_layout.o\
fraction_layout.o\
horizontal_layout.o\
integral_layout.o\
matrix_layout.o\
nth_root_layout.o\
parenthesis_layout.o\
string_layout.o\
sum_layout.o\
subscript_layout.o\
)
tests += $(addprefix poincare/test/,\

View File

@@ -21,7 +21,6 @@ public:
protected:
Expression ** m_args;
int m_numberOfArguments;
private:
const char * m_name;
};

View File

@@ -11,6 +11,7 @@ public:
Type type() const override;
Expression * cloneWithDifferentOperands(Expression ** newOperands,
int numberOfOperands, bool cloneOperands = true) const override;
ExpressionLayout * createLayout() const override;
private:
float functionValueAtAbscissa(float x, XContext xcontext) const;
};

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

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

View File

@@ -5,7 +5,11 @@
extern "C" {
#include <assert.h>
#include <math.h>
#include <stdlib.h>
}
#include "layout/horizontal_layout.h"
#include "layout/string_layout.h"
#include "layout/integral_layout.h"
Integral::Integral() :
Function("int")
@@ -52,6 +56,13 @@ float Integral::approximate(Context& context) const {
return result;
}
ExpressionLayout * Integral::createLayout() const {
ExpressionLayout ** childrenLayouts = (ExpressionLayout **)malloc(2*sizeof(ExpressionLayout *));
childrenLayouts[0] = m_args[0]->createLayout();
childrenLayouts[1] = new StringLayout("dx", 2);
return new IntegralLayout(m_args[1]->createLayout(), m_args[2]->createLayout(), new HorizontalLayout(childrenLayouts, 2));
}
float Integral::functionValueAtAbscissa(float x, XContext xContext) const {
Float e = Float(x);
Symbol xSymbol = Symbol('x');

View File

@@ -0,0 +1,93 @@
#include "integral_layout.h"
#include <string.h>
#include <assert.h>
const uint8_t topSymbolPixel[IntegralLayout::k_symbolHeight][IntegralLayout::k_symbolWidth] = {
{0x00, 0x00, 0xFF, 0xFF},
{0xFF, 0xFF, 0x00, 0xFF},
{0xFF, 0xFF, 0x00, 0x00},
{0xFF, 0xFF, 0x00, 0x00},
};
const uint8_t bottomSymbolPixel[IntegralLayout::k_symbolHeight][IntegralLayout::k_symbolWidth] = {
{0x00, 0x00, 0xFF, 0xFF},
{0x00, 0x00, 0xFF, 0xFF},
{0xFF, 0x00, 0xFF, 0xFF},
{0xFF, 0xFF, 0x00, 0x00},
};
IntegralLayout::IntegralLayout(ExpressionLayout * lowerBoundLayout, ExpressionLayout * upperBoundLayout, ExpressionLayout * integrandLayout) :
ExpressionLayout(),
m_lowerBoundLayout(lowerBoundLayout),
m_upperBoundLayout(upperBoundLayout),
m_integrandLayout(integrandLayout)
{
m_lowerBoundLayout->setParent(this);
m_upperBoundLayout->setParent(this);
m_integrandLayout->setParent(this);
m_baseline = m_upperBoundLayout->size().height() + k_integrandHeigthMargin + m_integrandLayout->baseline();
}
IntegralLayout::~IntegralLayout() {
delete m_lowerBoundLayout;
delete m_upperBoundLayout;
delete m_integrandLayout;
}
void IntegralLayout::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) {
KDSize integrandSize = m_integrandLayout->size();
KDSize upperBoundSize = m_upperBoundLayout->size();
KDColor workingBuffer[k_symbolWidth*k_symbolHeight];
KDRect topSymbolFrame(p.x() + k_symbolWidth + k_lineThickness, p.y() + upperBoundSize.height() - k_boundHeightMargin,
k_symbolWidth, k_symbolHeight);
ctx->blendRectWithMask(topSymbolFrame, expressionColor, (const uint8_t *)topSymbolPixel, (KDColor *)workingBuffer);
KDRect bottomSymbolFrame(p.x(),
p.y() + upperBoundSize.height() + 2*k_integrandHeigthMargin + integrandSize.height() + k_boundHeightMargin - k_symbolHeight,
k_symbolWidth, k_symbolHeight);
ctx->blendRectWithMask(bottomSymbolFrame, expressionColor, (const uint8_t *)bottomSymbolPixel, (KDColor *)workingBuffer);
ctx->fillRect(KDRect(p.x() + k_symbolWidth, p.y() + upperBoundSize.height() - k_boundHeightMargin, k_lineThickness,
2*k_boundHeightMargin+2*k_integrandHeigthMargin+integrandSize.height()), expressionColor);
}
KDSize IntegralLayout::computeSize() {
KDSize integrandSize = m_integrandLayout->size();
KDSize lowerBoundSize = m_lowerBoundLayout->size();
KDSize upperBoundSize = m_upperBoundLayout->size();
return KDSize(
k_symbolWidth+k_lineThickness+k_boundWidthMargin+max(lowerBoundSize.width(), upperBoundSize.width())+k_integrandWidthMargin+integrandSize.width(),
upperBoundSize.height()+ 2*k_integrandHeigthMargin+integrandSize.height()+lowerBoundSize.height());
}
ExpressionLayout * IntegralLayout::child(uint16_t index) {
switch (index) {
case 0:
return m_upperBoundLayout;
case 1:
return m_lowerBoundLayout;
case 2:
return m_integrandLayout;
default:
return nullptr;
}
}
KDPoint IntegralLayout::positionOfChild(ExpressionLayout * child) {
KDSize integrandSize = m_integrandLayout->size();
KDSize lowerBoundSize = m_lowerBoundLayout->size();
KDSize upperBoundSize = m_upperBoundLayout->size();
KDCoordinate x = 0;
KDCoordinate y = 0;
if (child == m_lowerBoundLayout) {
x = k_symbolWidth+k_lineThickness+k_boundWidthMargin;
y = upperBoundSize.height()+2*k_integrandHeigthMargin+integrandSize.height();
} else if (child == m_upperBoundLayout) {
x = k_symbolWidth+k_lineThickness+k_boundWidthMargin;;
y = 0;
} else if (child == m_integrandLayout) {
x = k_symbolWidth +k_lineThickness+ k_boundWidthMargin+max(lowerBoundSize.width(), upperBoundSize.width())+k_integrandWidthMargin;
y = upperBoundSize.height()+k_integrandHeigthMargin;
} else {
assert(false);
}
return KDPoint(x,y);
}

View File

@@ -0,0 +1,29 @@
#ifndef POINCARE_INTEGRAL_LAYOUT_H
#define POINCARE_INTEGRAL_LAYOUT_H
#include <poincare/expression.h>
#include <poincare/expression_layout.h>
class IntegralLayout : public ExpressionLayout {
public:
IntegralLayout(ExpressionLayout * lowerBoundLayout, ExpressionLayout * upperBoundLayout, ExpressionLayout * integrandLayout);
~IntegralLayout();
constexpr static KDCoordinate k_symbolHeight = 4;
constexpr static KDCoordinate k_symbolWidth = 4;
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_boundHeightMargin = 8;
constexpr static KDCoordinate k_boundWidthMargin = 5;
constexpr static KDCoordinate k_integrandWidthMargin = 2;
constexpr static KDCoordinate k_integrandHeigthMargin = 2;
constexpr static KDCoordinate k_lineThickness = 1;
ExpressionLayout * m_lowerBoundLayout;
ExpressionLayout * m_upperBoundLayout;
ExpressionLayout * m_integrandLayout;
};
#endif

View File

@@ -0,0 +1,49 @@
#include "subscript_layout.h"
#include <string.h>
#include <assert.h>
SubscriptLayout::SubscriptLayout(ExpressionLayout * baseLayout, ExpressionLayout * subscriptLayout) :
ExpressionLayout(),
m_baseLayout(baseLayout),
m_subscriptLayout(subscriptLayout)
{
m_baseLayout->setParent(this);
m_subscriptLayout->setParent(this);
m_baseline = m_baseLayout->baseline();
}
SubscriptLayout::~SubscriptLayout() {
delete m_baseLayout;
delete m_subscriptLayout;
}
void SubscriptLayout::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) {
// There is nothing to draw for a power, only the position of the children matters
}
KDSize SubscriptLayout::computeSize() {
KDSize baseSize = m_baseLayout->size();
KDSize subscriptSize = m_subscriptLayout->size();
return KDSize(baseSize.width() + subscriptSize.width(), m_baseLayout->baseline() + subscriptSize.height() - k_subscriptHeight);
}
ExpressionLayout * SubscriptLayout::child(uint16_t index) {
switch (index) {
case 0:
return m_baseLayout;
case 1:
return m_subscriptLayout;
default:
return nullptr;
}
}
KDPoint SubscriptLayout::positionOfChild(ExpressionLayout * child) {
KDCoordinate x = 0;
KDCoordinate y = 0;
if (child == m_subscriptLayout) {
x = m_baseLayout->size().width();
y = m_baseLayout->baseline() - k_subscriptHeight;
}
return KDPoint(x,y);
}

View File

@@ -0,0 +1,22 @@
#ifndef POINCARE_SUBSCRIPT_LAYOUT_H
#define POINCARE_SUBSCRIPT_LAYOUT_H
#include <poincare/expression.h>
#include <poincare/expression_layout.h>
class SubscriptLayout : public ExpressionLayout {
public:
SubscriptLayout(ExpressionLayout * baseLayout, ExpressionLayout * subscriptLayout);
~SubscriptLayout();
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_subscriptHeight = 5;
ExpressionLayout * m_baseLayout;
ExpressionLayout * m_subscriptLayout;
};
#endif

View File

@@ -0,0 +1,92 @@
#include "sum_layout.h"
#include <string.h>
#include <assert.h>
const uint8_t symbolPixel[SumLayout::k_symbolHeight][SumLayout::k_symbolWidth] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
};
SumLayout::SumLayout(ExpressionLayout * lowerBoundLayout, ExpressionLayout * upperBoundLayout, ExpressionLayout * argumentLayout) :
ExpressionLayout(),
m_lowerBoundLayout(lowerBoundLayout),
m_upperBoundLayout(upperBoundLayout),
m_argumentLayout(argumentLayout)
{
m_lowerBoundLayout->setParent(this);
m_upperBoundLayout->setParent(this);
m_argumentLayout->setParent(this);
m_baseline = max(m_upperBoundLayout->size().height()+k_boundHeightMargin+k_symbolHeight, m_argumentLayout->baseline());
}
SumLayout::~SumLayout() {
delete m_lowerBoundLayout;
delete m_upperBoundLayout;
delete m_argumentLayout;
}
void SumLayout::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) {
KDSize upperBoundSize = m_upperBoundLayout->size();
KDSize lowerBoundSize = m_lowerBoundLayout->size();
KDColor workingBuffer[k_symbolWidth*k_symbolHeight];
KDRect symbolFrame(p.x() + max(max(0, (upperBoundSize.width()-k_symbolWidth)/2), (lowerBoundSize.width()-k_symbolWidth)/2),
p.y() + max(upperBoundSize.height()+k_boundHeightMargin, m_argumentLayout->baseline()-k_symbolHeight),
k_symbolWidth, k_symbolHeight);
ctx->blendRectWithMask(symbolFrame, expressionColor, (const uint8_t *)symbolPixel, (KDColor *)workingBuffer);
}
KDSize SumLayout::computeSize() {
KDSize argumentSize = m_argumentLayout->size();
KDSize lowerBoundSize = m_lowerBoundLayout->size();
KDSize upperBoundSize = m_upperBoundLayout->size();
return KDSize(
max(max(k_symbolWidth, lowerBoundSize.width()), upperBoundSize.width())+k_argumentWidthMargin+argumentSize.width(),
m_baseline + max(k_boundHeightMargin+lowerBoundSize.height(), argumentSize.height() - m_argumentLayout->baseline())
);
}
ExpressionLayout * SumLayout::child(uint16_t index) {
switch (index) {
case 0:
return m_upperBoundLayout;
case 1:
return m_lowerBoundLayout;
case 2:
return m_argumentLayout;
default:
return nullptr;
}
}
KDPoint SumLayout::positionOfChild(ExpressionLayout * child) {
KDSize lowerBoundSize = m_lowerBoundLayout->size();
KDSize upperBoundSize = m_upperBoundLayout->size();
KDCoordinate x = 0;
KDCoordinate y = 0;
if (child == m_lowerBoundLayout) {
x = max(max(0, (k_symbolWidth-lowerBoundSize.width())/2), (upperBoundSize.width()-lowerBoundSize.width())/2);
y = m_baseline + k_boundHeightMargin;
} else if (child == m_upperBoundLayout) {
x = max(max(0, (k_symbolWidth-upperBoundSize.width())/2), (lowerBoundSize.width()-upperBoundSize.width())/2);
y = m_baseline - k_symbolHeight- k_boundHeightMargin-upperBoundSize.height();
} else if (child == m_argumentLayout) {
x = max(max(k_symbolWidth, lowerBoundSize.width()), upperBoundSize.width())+k_argumentWidthMargin;
y = m_baseline - m_argumentLayout->baseline();
} else {
assert(false);
}
return KDPoint(x,y);
}

View File

@@ -0,0 +1,26 @@
#ifndef POINCARE_SUM_LAYOUT_H
#define POINCARE_SUM_LAYOUT_H
#include <poincare/expression.h>
#include <poincare/expression_layout.h>
class SumLayout : public ExpressionLayout {
public:
SumLayout(ExpressionLayout * lowerBoundLayout, ExpressionLayout * upperBoundLayout, ExpressionLayout * argumentLayout);
~SumLayout();
constexpr static KDCoordinate k_symbolHeight = 15;
constexpr static KDCoordinate k_symbolWidth = 9;
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_boundHeightMargin = 2;
constexpr static KDCoordinate k_argumentWidthMargin = 2;
ExpressionLayout * m_lowerBoundLayout;
ExpressionLayout * m_upperBoundLayout;
ExpressionLayout * m_argumentLayout;
};
#endif

View File

@@ -2,7 +2,12 @@
extern "C" {
#include <assert.h>
#include <math.h>
#include <stdlib.h>
}
#include "layout/horizontal_layout.h"
#include "layout/parenthesis_layout.h"
#include "layout/string_layout.h"
#include "layout/subscript_layout.h"
Logarithm::Logarithm() :
Function("log")
@@ -28,3 +33,13 @@ float Logarithm::approximate(Context& context) const {
}
return log10f(m_args[1]->approximate(context))/log10f(m_args[0]->approximate(context));
}
ExpressionLayout * Logarithm::createLayout() const {
if (m_numberOfArguments == 1) {
return Function::createLayout();
}
ExpressionLayout ** childrenLayouts = (ExpressionLayout **)malloc(2*sizeof(ExpressionLayout *));
childrenLayouts[0] = new SubscriptLayout(new StringLayout(m_name, strlen(m_name)), m_args[0]->createLayout());
childrenLayouts[1] = new ParenthesisLayout(m_args[1]->createLayout());
return new HorizontalLayout(childrenLayouts, 2);
}

View File

@@ -1,9 +1,12 @@
#include <poincare/sum.h>
#include <poincare/symbol.h>
#include <poincare/float.h>
#include "layout/sum_layout.h"
#include "layout/string_layout.h"
#include "layout/horizontal_layout.h"
extern "C" {
#include <assert.h>
#include <stdlib.h>
}
Sum::Sum() :
@@ -37,3 +40,10 @@ float Sum::approximate(Context& context) const {
}
return result;
}
ExpressionLayout * Sum::createLayout() const {
ExpressionLayout ** childrenLayouts = (ExpressionLayout **)malloc(2*sizeof(ExpressionLayout *));
childrenLayouts[0] = new StringLayout("n=", 2);
childrenLayouts[1] = m_args[1]->createLayout();
return new SumLayout(new HorizontalLayout(childrenLayouts, 2), m_args[2]->createLayout(), m_args[0]->createLayout());
}