[poincare] Factorize computeBaseline/OperandHeight in ParLeftRightLayout

Change-Id: I5a7e4f73df75d26a1b7e21460f888f5f1901307b
This commit is contained in:
Léa Saviot
2018-04-19 10:43:54 +02:00
parent 887f3c222a
commit 2b57c00a47
6 changed files with 105 additions and 162 deletions

View File

@@ -1,5 +1,4 @@
#include "parenthesis_left_layout.h"
#include <escher/metric.h>
extern "C" {
#include <assert.h>
#include <stdlib.h>
@@ -62,92 +61,4 @@ void ParenthesisLeftLayout::render(KDContext * ctx, KDPoint p, KDColor expressio
expressionColor);
}
void ParenthesisLeftLayout::computeOperandHeight() {
assert(m_parent != nullptr);
m_operandHeight = Metric::MinimalBracketAndParenthesisHeight;
KDCoordinate max_under_baseline = 0;
KDCoordinate max_above_baseline = 0;
int indexInParent = m_parent->indexOfChild(this);
int currentNumberOfOpenParentheses = 1;
int numberOfBrothers = m_parent->numberOfChildren();
if (indexInParent < numberOfBrothers - 1
&& m_parent->child(indexInParent + 1)->isVerticalOffset())
{
// If the parenthesis is the base of a superscript layout, it should have a
// default height, else it creates an infinite loop because the parenthesis
// needs the superscript height, which needs the parenthesis height.
return;
}
for (int i = indexInParent + 1; i < numberOfBrothers; i++) {
ExpressionLayout * brother = m_parent->editableChild(i);
if (brother->isRightParenthesis()) {
currentNumberOfOpenParentheses--;
if (currentNumberOfOpenParentheses == 0) {
if (max_under_baseline + max_above_baseline > m_operandHeight) {
m_operandHeight = max_under_baseline + max_above_baseline;
}
return;
}
} else if (brother->isLeftParenthesis()) {
currentNumberOfOpenParentheses++;
}
KDCoordinate brotherHeight = brother->size().height();
KDCoordinate brotherBaseline = brother->baseline();
if (brotherHeight - brotherBaseline > max_under_baseline) {
max_under_baseline = brotherHeight - brotherBaseline ;
}
if (brotherBaseline > max_above_baseline) {
max_above_baseline = brotherBaseline;
}
}
if (max_under_baseline + max_above_baseline > m_operandHeight) {
m_operandHeight = max_under_baseline + max_above_baseline;
}
}
void ParenthesisLeftLayout::computeBaseline() {
assert(m_parent != nullptr);
int currentNumberOfOpenParentheses = 1;
int indexInParent = m_parent->indexOfChild(this);
int numberOfBrothers = m_parent->numberOfChildren();
if (indexInParent == numberOfBrothers - 1) {
// The parenthesis is the rightmost child of its parent.
m_baseline = operandHeight()/2;
m_baselined = true;
return;
}
if (m_parent->child(indexInParent + 1)->isVerticalOffset()) {
// If the parenthesis is the base of a superscript layout, it should have a
// default baseline, else it creates an infinite loop because the
// parenthesis needs the superscript height, which needs the parenthesis
// baseline.
m_baseline = operandHeight()/2;
m_baselined = true;
return;
}
m_baseline = 0;
for (int i = indexInParent + 1; i < numberOfBrothers; i++) {
ExpressionLayout * brother = m_parent->editableChild(i);
if (brother->isRightParenthesis()) {
if (i == indexInParent + 1) {
// If the parenthesis is immediately closed, we set the baseline to half
// the parenthesis height.
m_baseline = operandHeight()/2;
break;
}
currentNumberOfOpenParentheses--;
if (currentNumberOfOpenParentheses == 0) {
break;
}
} else if (brother->isLeftParenthesis()) {
currentNumberOfOpenParentheses++;
}
if (brother->baseline() > m_baseline) {
m_baseline = brother->baseline();
}
}
m_baselined = true;
}
}

View File

@@ -19,8 +19,6 @@ public:
bool isLeftParenthesis() const override { return true; }
protected:
void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) override;
void computeOperandHeight() override;
void computeBaseline() override;
};
}

View File

@@ -1,4 +1,5 @@
#include "parenthesis_left_right_layout.h"
#include <escher/metric.h>
#include <poincare/expression_layout_cursor.h>
extern "C" {
#include <assert.h>
@@ -56,6 +57,55 @@ KDSize ParenthesisLeftRightLayout::computeSize() {
return KDSize(parenthesisWidth(), operandHeight());
}
void ParenthesisLeftRightLayout::computeBaseline() {
assert(m_parent != nullptr);
bool isParenthesisLeft = isLeftParenthesis();
int indexInParent = m_parent->indexOfChild(this);
int numberOfBrothers = m_parent->numberOfChildren();
if ((isParenthesisLeft && indexInParent == numberOfBrothers - 1)
|| (!isParenthesisLeft && indexInParent == 0)
|| (isParenthesisLeft && indexInParent < numberOfBrothers - 1 && m_parent->child(indexInParent + 1)->isVerticalOffset()))
{
/* The parenthesis does not have brothers on its open direction, or it is a
* left parenthesis that is base of a superscript layout. In the latter
* case, it should have a default baseline, else it creates an infinite loop
* because the parenthesis needs the superscript height, which needs the
* parenthesis baseline. */
m_baseline = operandHeight()/2;
m_baselined = true;
return;
}
int currentNumberOfOpenParentheses = 1;
m_baseline = 0;
int increment = isParenthesisLeft ? 1 : -1;
for (int i = indexInParent + increment; i >= 0 && i <= numberOfBrothers - 1; i+= increment) {
ExpressionLayout * brother = m_parent->editableChild(i);
if ((isParenthesisLeft && brother->isRightParenthesis())
|| (!isParenthesisLeft && brother->isLeftParenthesis()))
{
if (i == indexInParent + increment) {
/* If the parenthesis is immediately closed, we set the baseline to half
* the parenthesis height. */
m_baseline = size().height()/2;
break;
}
currentNumberOfOpenParentheses--;
if (currentNumberOfOpenParentheses == 0) {
break;
}
} else if ((isParenthesisLeft && brother->isLeftParenthesis())
|| (!isParenthesisLeft && brother->isRightParenthesis()))
{
currentNumberOfOpenParentheses++;
}
if (brother->baseline() > m_baseline) {
m_baseline = brother->baseline();
}
}
m_baselined = true;
}
KDCoordinate ParenthesisLeftRightLayout::operandHeight() {
if (!m_operandHeightComputed) {
computeOperandHeight();
@@ -64,6 +114,59 @@ KDCoordinate ParenthesisLeftRightLayout::operandHeight() {
return m_operandHeight;
}
void ParenthesisLeftRightLayout::computeOperandHeight() {
assert(m_parent != nullptr);
m_operandHeight = Metric::MinimalBracketAndParenthesisHeight;
bool isParenthesisLeft = isLeftParenthesis();
int indexInParent = m_parent->indexOfChild(this);
int numberOfBrothers = m_parent->numberOfChildren();
if (isParenthesisLeft
&& indexInParent < numberOfBrothers - 1
&& m_parent->child(indexInParent + 1)->isVerticalOffset())
{
/* If a left parenthesis is the base of a superscript layout, it should have
* a default height, else it creates an infinite loop because the
* parenthesis needs the superscript height, which needs the parenthesis
* height. */
return;
}
KDCoordinate max_under_baseline = 0;
KDCoordinate max_above_baseline = 0;
int currentNumberOfOpenParentheses = 1;
int increment = isParenthesisLeft ? 1 : -1;
for (int i = indexInParent + increment; i >= 0 && i < numberOfBrothers; i+= increment) {
ExpressionLayout * brother = m_parent->editableChild(i);
if ((!isParenthesisLeft && brother->isLeftParenthesis())
|| (isParenthesisLeft && brother->isRightParenthesis()))
{
currentNumberOfOpenParentheses--;
if (currentNumberOfOpenParentheses == 0) {
if (max_under_baseline + max_above_baseline > m_operandHeight) {
m_operandHeight = max_under_baseline + max_above_baseline;
}
return;
}
} else if ((isParenthesisLeft && brother->isLeftParenthesis())
|| (!isParenthesisLeft && brother->isRightParenthesis()))
{
currentNumberOfOpenParentheses++;
}
KDCoordinate brotherHeight = brother->size().height();
KDCoordinate brotherBaseline = brother->baseline();
if (brotherHeight - brotherBaseline > max_under_baseline) {
max_under_baseline = brotherHeight - brotherBaseline ;
}
if (brotherBaseline > max_above_baseline) {
max_above_baseline = brotherBaseline;
}
}
if (max_under_baseline + max_above_baseline > m_operandHeight) {
m_operandHeight = max_under_baseline + max_above_baseline;
}
}
KDPoint ParenthesisLeftRightLayout::positionOfChild(ExpressionLayout * child) {
assert(false);
return KDPointZero;

View File

@@ -21,8 +21,9 @@ public:
protected:
KDColor s_parenthesisWorkingBuffer[k_parenthesisCurveHeight*k_parenthesisCurveWidth];
KDSize computeSize() override;
void computeBaseline() override;
KDCoordinate operandHeight();
virtual void computeOperandHeight() = 0;
void computeOperandHeight();
KDPoint positionOfChild(ExpressionLayout * child) override;
bool m_operandHeightComputed;
uint16_t m_operandHeight;

View File

@@ -1,5 +1,4 @@
#include "parenthesis_right_layout.h"
#include <escher/metric.h>
extern "C" {
#include <assert.h>
#include <stdlib.h>
@@ -62,73 +61,6 @@ void ParenthesisRightLayout::render(KDContext * ctx, KDPoint p, KDColor expressi
expressionColor);
}
void ParenthesisRightLayout::computeOperandHeight() {
assert(m_parent != nullptr);
m_operandHeight = Metric::MinimalBracketAndParenthesisHeight;
KDCoordinate max_under_baseline = 0;
KDCoordinate max_above_baseline = 0;
int currentNumberOfOpenParentheses = 1;
for (int i = m_parent->indexOfChild(this) - 1; i >= 0; i--) {
ExpressionLayout * brother = m_parent->editableChild(i);
if (brother->isLeftParenthesis()) {
currentNumberOfOpenParentheses--;
if (currentNumberOfOpenParentheses == 0) {
if (max_under_baseline + max_above_baseline > m_operandHeight) {
m_operandHeight = max_under_baseline + max_above_baseline;
}
return;
}
} else if (brother->isRightParenthesis()) {
currentNumberOfOpenParentheses++;
}
KDCoordinate brotherHeight = brother->size().height();
KDCoordinate brotherBaseline = brother->baseline();
if (brotherHeight - brotherBaseline > max_under_baseline) {
max_under_baseline = brotherHeight - brotherBaseline ;
}
if (brotherBaseline > max_above_baseline) {
max_above_baseline = brotherBaseline;
}
}
if (max_under_baseline + max_above_baseline > m_operandHeight) {
m_operandHeight = max_under_baseline + max_above_baseline;
}
}
void ParenthesisRightLayout::computeBaseline() {
assert(m_parent != nullptr);
int currentNumberOfOpenParentheses = 1;
int indexInParent = m_parent->indexOfChild(this);
if (indexInParent == 0) {
// The parenthesis is the leftmost child of its parent.
m_baseline = operandHeight()/2;
m_baselined = true;
return;
}
m_baseline = 0;
for (int i = indexInParent - 1; i >= 0; i--) {
ExpressionLayout * brother = m_parent->editableChild(i);
if (brother->isLeftParenthesis()) {
if (i == indexInParent - 1) {
// If the parenthesis is immediately closed, we set the baseline to half
// the parenthesis height.
m_baseline = operandHeight()/2;
break;
}
currentNumberOfOpenParentheses--;
if (currentNumberOfOpenParentheses == 0) {
break;
}
} else if (brother->isRightParenthesis()) {
currentNumberOfOpenParentheses++;
}
if (brother->baseline() > m_baseline) {
m_baseline = brother->baseline();
}
}
m_baselined = true;
}
}

View File

@@ -19,8 +19,6 @@ public:
bool isRightParenthesis() const override { return true; }
protected:
void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) override;
void computeOperandHeight() override;
void computeBaseline() override;
};
}