[poincare/integral_layout] Changing the integral symbol

Changed the look of the integral symbol and the positions of the upper
and lower bounds. Added a drawing of the window to explain the meaning
of various margins.

Change-Id: I3ffc07848dc9ad68dce3c0e01853d548e31dd152
This commit is contained in:
Arthur Camouseigt
2020-05-06 15:30:23 +02:00
committed by Émilie Feral
parent 653b7d0ac4
commit 1e0449791d
2 changed files with 140 additions and 30 deletions

View File

@@ -9,7 +9,8 @@ namespace Poincare {
class IntegralLayoutNode final : public LayoutNode {
public:
constexpr static KDCoordinate k_symbolHeight = 4;
// Sizes of the upper and lower curls of the integral symbol
constexpr static KDCoordinate k_symbolHeight = 9;
constexpr static KDCoordinate k_symbolWidth = 4;
using LayoutNode::LayoutNode;
@@ -40,16 +41,18 @@ protected:
// LayoutNode
KDSize computeSize() override;
KDCoordinate computeBaseline() override;
KDCoordinate centralArgumentHeight();
KDPoint positionOfChild(LayoutNode * child) override;
private:
constexpr static int k_integrandLayoutIndex = 0;
constexpr static int k_differentialLayoutIndex = 1;
constexpr static const KDFont * k_font = KDFont::LargeFont;
constexpr static KDCoordinate k_boundHeightMargin = 8;
constexpr static KDCoordinate k_boundHeightMargin = 5;
constexpr static KDCoordinate k_boundWidthMargin = 5;
constexpr static KDCoordinate k_differentialWidthMargin = 3;
constexpr static KDCoordinate k_integrandWidthMargin = 2;
constexpr static KDCoordinate k_integrandHeigthMargin = 2;
constexpr static KDCoordinate k_integrandHeigthMargin = 4;
constexpr static KDCoordinate k_lineThickness = 1;
// int(f(x), x, a, b)
LayoutNode * integrandLayout() { return childAtIndex(k_integrandLayoutIndex); } // f(x)

View File

@@ -9,17 +9,27 @@
namespace Poincare {
const uint8_t topSymbolPixel[IntegralLayoutNode::k_symbolHeight][IntegralLayoutNode::k_symbolWidth] = {
{0x00, 0x00, 0xFF, 0xFF},
{0xFF, 0xFF, 0x00, 0xFF},
{0xFF, 0xFF, 0x00, 0x00},
{0xFF, 0xFF, 0x00, 0x00},
{0xFF, 0xD5, 0x46, 0x09},
{0xF1, 0x1A, 0x93, 0xF0},
{0x98, 0x54, 0xFF, 0xFF},
{0x53, 0xA7, 0xFF, 0xFF},
{0x29, 0xCF, 0xFF, 0xFF},
{0x14, 0xEA, 0xFF, 0xFF},
{0x02, 0xFC, 0xFF, 0xFF},
{0x00, 0xFF, 0xFF, 0xFF},
{0x00, 0xFF, 0xFF, 0xFF},
};
const uint8_t bottomSymbolPixel[IntegralLayoutNode::k_symbolHeight][IntegralLayoutNode::k_symbolWidth] = {
{0x00, 0x00, 0xFF, 0xFF},
{0x00, 0x00, 0xFF, 0xFF},
{0xFF, 0x00, 0xFF, 0xFF},
{0xFF, 0xFF, 0x00, 0x00},
{0xFF, 0xFF, 0xFF, 0x00},
{0xFF, 0xFF, 0xFF, 0x00},
{0xFF, 0xFF, 0xFE, 0x03},
{0xFF, 0xFF, 0xEA, 0x13},
{0xFF, 0xFF, 0xCF, 0x29},
{0xFF, 0xFF, 0xA5, 0x53},
{0xFF, 0xFF, 0x54, 0x99},
{0xF2, 0x95, 0x1A, 0xF1},
{0x09, 0x46, 0xD5, 0xFF},
};
void IntegralLayoutNode::moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout, bool forSelection) {
@@ -208,6 +218,86 @@ CodePoint IntegralLayoutNode::XNTCodePoint(int childIndex) const {
return (childIndex == k_integrandLayoutIndex || childIndex == k_differentialLayoutIndex) ? CodePoint('x') : UCodePointNull;
}
/*
Window configuration explained :
Vertical margins and offsets
+-----------------------------------------------------------------+
| | |
| k_boundHeightMargin |
| | |
| +------------------+ |
| | upperBoundHeight | |
| +------------------+ |
| | |
| k_integrandHeightMargin |
| | |
| |
| +++ |
| +++ k_symbolHeight |
| +++ |
| |
| ||| |
| ||| |
| ||| |
| ||| |
| ||| centralArgumentHeight |
| ||| |
| ||| |
| ||| |
| ||| |
| |
| +++ |
| +++ k_symbolHeight |
| +++ |
| | |
| k_integrandHeightMargin |
| | |
| +------------------+ |
| | lowerBoundHeight | |
| +------------------+ |
| | |
| k_boundHeightMargin |
| | |
+-----------------------------------------------------------------+
Horizontal margins and offsets
+-------------------------------------------------------------------------+
| | |
| |
| | +------------------+ |
| |<-upperBoundLengthOffset->| upperBoundWidth | |
| | +------------------+ |
| |
| | | |
| +++ |
| | | +++ |
| +++ |
| | | |
| ||| |
| | |||| |
| ||| |
| | |||| |
|<-k_boundWidthMargin->|<-integralSymbolOffset->|||| |
| | |||| |
| ||| |
| | |||| |
| ||| |
| | | a | |
| +++ |
| | | a++| |
| +++ |
| | | a | |
| |
| | +------------------+ |
| |<-lowerBoundLengthOffset->| lowerBoundWidth | |
| | +------------------+ |
| |
| | |
+-------------------------------------------------------------------------+
With a = k_symbolWidth + k_lineThickness
integralSymbolOffset = std::max((int)upperBoundSize.width()/2, (int)lowerBoundSize.width()/2) - k_integrandWidthMargin;
*/
KDSize IntegralLayoutNode::computeSize() {
KDSize dSize = k_font->stringSize("d");
KDSize integrandSize = integrandLayout()->layoutSize();
@@ -215,13 +305,12 @@ KDSize IntegralLayoutNode::computeSize() {
KDSize lowerBoundSize = lowerBoundLayout()->layoutSize();
KDSize upperBoundSize = upperBoundLayout()->layoutSize();
KDCoordinate width = k_symbolWidth+k_lineThickness+k_boundWidthMargin+std::max(lowerBoundSize.width(), upperBoundSize.width())+k_integrandWidthMargin+integrandSize.width()+2*k_differentialWidthMargin+dSize.width()+differentialSize.width();
KDCoordinate baseline = computeBaseline();
KDCoordinate height = baseline + k_integrandHeigthMargin+std::max(integrandSize.height()-integrandLayout()->baseline(), differentialSize.height()-differentialLayout()->baseline())+lowerBoundSize.height();
KDCoordinate height = upperBoundSize.height() + k_integrandHeigthMargin + k_symbolHeight + centralArgumentHeight() + k_symbolHeight + k_integrandHeigthMargin + lowerBoundSize.height();
return KDSize(width, height);
}
KDCoordinate IntegralLayoutNode::computeBaseline() {
return upperBoundLayout()->layoutSize().height() + k_integrandHeigthMargin + std::max(integrandLayout()->baseline(), differentialLayout()->baseline());
return upperBoundLayout()->layoutSize().height() + k_integrandHeigthMargin + k_symbolHeight + std::max(integrandLayout()->baseline(), differentialLayout()->baseline());
}
KDPoint IntegralLayoutNode::positionOfChild(LayoutNode * child) {
@@ -229,42 +318,60 @@ KDPoint IntegralLayoutNode::positionOfChild(LayoutNode * child) {
KDSize upperBoundSize = upperBoundLayout()->layoutSize();
KDCoordinate x = 0;
KDCoordinate y = 0;
// Offsets the integral bounds in order to center them
int difference = (upperBoundSize.width() - lowerBoundSize.width())/2;
if (child == lowerBoundLayout()) {
x = k_symbolWidth+k_lineThickness+k_boundWidthMargin;
y = computeSize().height()-lowerBoundSize.height();
x = std::max(0, difference);
y = computeSize().height() - lowerBoundSize.height();
} else if (child == upperBoundLayout()) {
x = k_symbolWidth+k_lineThickness+k_boundWidthMargin;;
x = std::max(0, -difference);
y = 0;
} else if (child == integrandLayout()) {
x = k_symbolWidth +k_lineThickness+ k_boundWidthMargin+std::max(lowerBoundSize.width(), upperBoundSize.width())+k_integrandWidthMargin;
x = k_symbolWidth + k_lineThickness + k_boundWidthMargin+std::max(lowerBoundSize.width(), upperBoundSize.width())+k_integrandWidthMargin;
y = computeBaseline()-integrandLayout()->baseline();
} else if (child == differentialLayout()) {
} else {
assert(child == differentialLayout());
x = computeSize().width() - k_differentialWidthMargin - differentialLayout()->layoutSize().width();
y = computeBaseline()-differentialLayout()->baseline();
} else {
assert(false);
}
return KDPoint(x,y);
}
KDCoordinate IntegralLayoutNode::centralArgumentHeight() {
KDCoordinate integrandHeight = integrandLayout()->layoutSize().height();
KDCoordinate integrandBaseline = integrandLayout()->baseline();
KDCoordinate differentialHeight = differentialLayout()->layoutSize().height();
KDCoordinate differentialBaseline = differentialLayout()->baseline();
return std::max(integrandBaseline, differentialBaseline) + std::max(integrandHeight-integrandBaseline, differentialHeight - differentialBaseline);
}
void IntegralLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor, Layout * selectionStart, Layout * selectionEnd, KDColor selectionColor) {
KDSize integrandSize = integrandLayout()->layoutSize();
KDSize differentialSize = differentialLayout()->layoutSize();
KDSize upperBoundSize = upperBoundLayout()->layoutSize();
KDCoordinate centralArgumentHeight = std::max(integrandLayout()->baseline(), differentialLayout()->baseline()) + std::max(integrandSize.height()-integrandLayout()->baseline(), differentialSize.height()-differentialLayout()->baseline());
KDSize lowerBoundSize = lowerBoundLayout()->layoutSize();
KDColor workingBuffer[k_symbolWidth*k_symbolHeight];
// Render the integral symbol
KDRect topSymbolFrame(p.x() + k_symbolWidth + k_lineThickness, p.y() + upperBoundSize.height() - k_boundHeightMargin,
k_symbolWidth, k_symbolHeight);
KDCoordinate integralSymbolOffset = std::max((int)upperBoundSize.width(), (int)lowerBoundSize.width())/2 - k_integrandWidthMargin;
KDCoordinate offsetX = p.x() + integralSymbolOffset;
KDCoordinate offsetY = p.y() + upperBoundSize.height() + k_integrandHeigthMargin;
// Upper part
KDRect topSymbolFrame(offsetX, offsetY, 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 + centralArgumentHeight + k_boundHeightMargin - k_symbolHeight,
k_symbolWidth, k_symbolHeight);
// Central bar
offsetY = offsetY + k_symbolHeight;
KDCoordinate k_centralArgumentHeight = centralArgumentHeight();
ctx->fillRect(KDRect(offsetX, offsetY, k_lineThickness, k_centralArgumentHeight), expressionColor);
// Lower part
offsetX = offsetX - k_symbolWidth + k_lineThickness;
offsetY = offsetY + k_centralArgumentHeight;
KDRect bottomSymbolFrame(offsetX, offsetY, 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+centralArgumentHeight), expressionColor);
// Render "d"
KDPoint dPosition = p.translatedBy(positionOfChild(integrandLayout())).translatedBy(KDPoint(integrandSize.width() + k_differentialWidthMargin, integrandLayout()->baseline() - k_font->glyphSize().height()/2));