From ac26f20ffb310e9e2aa487dbf3f2d73fc4c800f4 Mon Sep 17 00:00:00 2001 From: Romain Goyet Date: Tue, 19 May 2015 18:06:25 +0200 Subject: [PATCH] Proper drawing of expressions --- kandinsky/Makefile | 2 +- kandinsky/include/kandinsky.h | 1 + kandinsky/include/kandinsky/referential.h | 14 +++++++++ kandinsky/include/kandinsky/types.h | 2 ++ kandinsky/src/line.c | 4 +-- kandinsky/src/rect.c | 4 +-- kandinsky/src/referential.c | 19 ++++++++++++ kandinsky/src/text.c | 4 +-- platform/stm32f429/boot/flash.ld | 4 +++ platform/stm32f429/framebuffer.h | 3 -- poincare/Makefile | 2 +- poincare/include/poincare.h | 1 + poincare/include/poincare/expression.h | 12 ++++++-- poincare/include/poincare/fraction.h | 4 +-- poincare/include/poincare/number.h | 1 + poincare/include/poincare/power.h | 16 ++++++++++ poincare/src/expression.cpp | 36 +++++++++++++++++++++++ poincare/src/fraction.cpp | 31 ++++++++++--------- poincare/src/number.cpp | 7 ++++- poincare/src/power.cpp | 30 +++++++++++++++++++ src/hello.cpp | 9 ++++-- 21 files changed, 173 insertions(+), 33 deletions(-) create mode 100644 kandinsky/include/kandinsky/referential.h create mode 100644 kandinsky/src/referential.c create mode 100644 poincare/include/poincare/power.h create mode 100644 poincare/src/power.cpp diff --git a/kandinsky/Makefile b/kandinsky/Makefile index 9d9bedf7b..3db532ac7 100644 --- a/kandinsky/Makefile +++ b/kandinsky/Makefile @@ -1,5 +1,5 @@ SFLAGS += -Ikandinsky/include -Iplatform/stm32f429 -objs += $(addprefix kandinsky/src/, line.o text.o font.o rect.o) +objs += $(addprefix kandinsky/src/, line.o text.o font.o rect.o referential.o) FREETYPE_PATH := /usr/local/Cellar/freetype/2.5.5 LIBPNG_PATH := /usr/local/Cellar/libpng/1.6.17 diff --git a/kandinsky/include/kandinsky.h b/kandinsky/include/kandinsky.h index 0e92a888e..51134600e 100644 --- a/kandinsky/include/kandinsky.h +++ b/kandinsky/include/kandinsky.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include diff --git a/kandinsky/include/kandinsky/referential.h b/kandinsky/include/kandinsky/referential.h new file mode 100644 index 000000000..5ca3d23c2 --- /dev/null +++ b/kandinsky/include/kandinsky/referential.h @@ -0,0 +1,14 @@ +#ifndef KANDINSKY_REFERENTIAL_H +#define KANDINSKY_REFERENTIAL_H + +#include +#include + +void KDSetOrigin(KDPoint origin); +KDPoint KDGetOrigin(); + +KDColor * KDPixelAddress(KDPoint p); + +#define COLOR(p) *KDPixelAddress(p) + +#endif diff --git a/kandinsky/include/kandinsky/types.h b/kandinsky/include/kandinsky/types.h index 4d5493dd0..70d975dbf 100644 --- a/kandinsky/include/kandinsky/types.h +++ b/kandinsky/include/kandinsky/types.h @@ -10,6 +10,8 @@ typedef struct { KDCoordinate y; } KDPoint; +#define KDPOINT(xc,yc) ((KDPoint){.x=(KDCoordinate)(xc),.y=(KDCoordinate)(yc)}) + typedef struct { KDCoordinate width; KDCoordinate height; diff --git a/kandinsky/src/line.c b/kandinsky/src/line.c index 6312a7a61..7767a2dda 100644 --- a/kandinsky/src/line.c +++ b/kandinsky/src/line.c @@ -1,8 +1,8 @@ #include -#include +#include void KDDrawLine(KDPoint p1, KDPoint p2) { for (KDCoordinate x = p1.x; x -#include +#include #include void KDFillRect(KDRect rect, KDColor color) { for (KDCoordinate y = rect.y ; y < (rect.y + rect.height); y++) { - memset(PIXEL_ADDRESS(rect.x, y), color, rect.width); + memset(KDPixelAddress((KDPoint){.x=rect.x, .y=y}), color, rect.width); } } diff --git a/kandinsky/src/referential.c b/kandinsky/src/referential.c new file mode 100644 index 000000000..eebb493ed --- /dev/null +++ b/kandinsky/src/referential.c @@ -0,0 +1,19 @@ +#include + +static KDPoint sOrigin = {.x = 0, .y = 0}; + +void KDSetOrigin(KDPoint origin) { + sOrigin = origin; +} + +KDPoint KDGetOrigin() { + return sOrigin; +} + +KDColor * KDPixelAddress(KDPoint p) { + KDPoint origin = KDGetOrigin(); + return (KDColor *)(FRAMEBUFFER_ADDRESS + + FRAMEBUFFER_WIDTH*(p.y + origin.y) + + (p.x + origin.x)); +} + diff --git a/kandinsky/src/text.c b/kandinsky/src/text.c index b7f573c2e..6181639c2 100644 --- a/kandinsky/src/text.c +++ b/kandinsky/src/text.c @@ -1,12 +1,12 @@ #include -#include +#include #include #include "font.h" void KDDrawChar(char character, KDPoint p) { for (int j=0; jFLASH diff --git a/platform/stm32f429/framebuffer.h b/platform/stm32f429/framebuffer.h index 7e359c5a4..f396e9972 100644 --- a/platform/stm32f429/framebuffer.h +++ b/platform/stm32f429/framebuffer.h @@ -10,7 +10,4 @@ typedef uint8_t pixel_t; #define FRAMEBUFFER_BITS_PER_PIXEL 8 #define FRAMEBUFFER_ADDRESS (pixel_t *)(0x2001D400) -#define PIXEL_ADDRESS(x,y) (pixel_t *)(FRAMEBUFFER_ADDRESS+FRAMEBUFFER_WIDTH*(y)+(x)) -#define PIXEL(x,y) *PIXEL_ADDRESS(x,y) - #endif diff --git a/poincare/Makefile b/poincare/Makefile index 0953f511d..95b283736 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -1,2 +1,2 @@ SFLAGS += -Ipoincare/include -objs += $(addprefix poincare/src/, expression.o number.o fraction.o) +objs += $(addprefix poincare/src/, expression.o number.o fraction.o power.o) diff --git a/poincare/include/poincare.h b/poincare/include/poincare.h index a5119c0f5..e0a5dfbd8 100644 --- a/poincare/include/poincare.h +++ b/poincare/include/poincare.h @@ -4,5 +4,6 @@ #include #include #include +#include #endif diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 18d169c5b..9a7628f5a 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -5,11 +5,19 @@ extern "C" { #include } +class Expression; +typedef void (Expression::*ExpressionAction)(void); + class Expression { public: - virtual void draw() = 0; - virtual void layout() = 0; + void recursiveDraw(); + void recursiveLayout(); KDRect m_frame; + virtual Expression ** children() = 0; // NULL-terminated + virtual void draw(); + virtual void layout(); + private: + void forEachChild(ExpressionAction); }; #endif diff --git a/poincare/include/poincare/fraction.h b/poincare/include/poincare/fraction.h index e176ddfdf..baf5c3a63 100644 --- a/poincare/include/poincare/fraction.h +++ b/poincare/include/poincare/fraction.h @@ -7,11 +7,11 @@ class Fraction : public Expression { public: Fraction(Expression * numerator, Expression * denominator); virtual void draw(); + virtual Expression ** children(); // protected: virtual void layout(); private: - Expression * m_numerator; - Expression * m_denominator; + Expression * m_children[3]; }; #endif diff --git a/poincare/include/poincare/number.h b/poincare/include/poincare/number.h index d80bcba59..3bbd0295f 100644 --- a/poincare/include/poincare/number.h +++ b/poincare/include/poincare/number.h @@ -7,6 +7,7 @@ class Number : public Expression { public: Number(int v); virtual void draw(); + virtual Expression ** children(); protected: virtual void layout(); private: diff --git a/poincare/include/poincare/power.h b/poincare/include/poincare/power.h new file mode 100644 index 000000000..706bca17f --- /dev/null +++ b/poincare/include/poincare/power.h @@ -0,0 +1,16 @@ +#ifndef POINCARE_POWER_H +#define POINCARE_POWER_H + +#include + +class Power : public Expression { + public: + Power(Expression * base, Expression * exponent); + virtual Expression ** children(); +// protected: + virtual void layout(); + private: + Expression * m_children[3]; +}; + +#endif diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index 7a1ef13b9..c1ba6df5f 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -1,2 +1,38 @@ #include +#include +void Expression::forEachChild(ExpressionAction action) { + Expression ** childPointer = children(); + if (childPointer == NULL) { + return; + } + while(*childPointer != NULL) { + (*childPointer->*action)(); + childPointer++; + } +} + +void Expression::recursiveLayout() { + forEachChild(&Expression::recursiveLayout); + layout(); +} + +void Expression::recursiveDraw() { + KDPoint origin = KDGetOrigin(); + KDSetOrigin(KDPOINT(origin.x + m_frame.origin.x, + origin.y + m_frame.origin.y)); + + forEachChild(&Expression::recursiveDraw); + + draw(); + + KDSetOrigin(origin); +} + +void Expression::draw() { + // No-op by default +} + +void Expression::layout() { + // No-op by default +} diff --git a/poincare/src/fraction.cpp b/poincare/src/fraction.cpp index 3eb2d462d..7cc4197d3 100644 --- a/poincare/src/fraction.cpp +++ b/poincare/src/fraction.cpp @@ -1,44 +1,47 @@ #include +#include static inline KDCoordinate max(KDCoordinate a, KDCoordinate b) { return (a > b ? a : b); } +#define NUMERATOR m_children[0] +#define DENOMINATOR m_children[1] + #define FRACTION_BORDER_LENGTH 2 #define FRACTION_LINE_MARGIN 2 #define FRACTION_LINE_HEIGHT 1 -Fraction::Fraction(Expression * numerator, Expression * denominator) : - m_numerator(numerator), - m_denominator(denominator) { +Fraction::Fraction(Expression * numerator, Expression * denominator) { + m_children[0] = numerator; + m_children[1] = denominator; + m_children[2] = NULL; +} + +Expression ** Fraction::children() { + return m_children; } void Fraction::layout() { - m_numerator->layout(); - m_denominator->layout(); - - KDRect numFrame = m_numerator->m_frame; - KDRect denFrame = m_denominator->m_frame; + KDRect numFrame = NUMERATOR->m_frame; + KDRect denFrame = DENOMINATOR->m_frame; m_frame.width = max(numFrame.width, denFrame.width) + 2*FRACTION_BORDER_LENGTH; m_frame.height = numFrame.height + FRACTION_LINE_MARGIN + FRACTION_LINE_HEIGHT + FRACTION_LINE_MARGIN + denFrame.height; - m_numerator->m_frame.origin = { + NUMERATOR->m_frame.origin = { .x = (KDCoordinate)((m_frame.width - numFrame.width)/2), .y = 0 }; - m_denominator->m_frame.origin = { + DENOMINATOR->m_frame.origin = { .x = (KDCoordinate)((m_frame.width - denFrame.width)/2), .y = (KDCoordinate)(numFrame.height + 2*FRACTION_LINE_MARGIN + FRACTION_LINE_HEIGHT) }; } void Fraction::draw() { - m_numerator->draw(); - m_denominator->draw(); - - KDCoordinate fractionLineY = m_numerator->m_frame.height + FRACTION_LINE_MARGIN; + KDCoordinate fractionLineY = NUMERATOR->m_frame.height + FRACTION_LINE_MARGIN; KDDrawLine((KDPoint){.x = 0, .y = fractionLineY}, (KDPoint){.x = m_frame.width, .y = fractionLineY}); diff --git a/poincare/src/number.cpp b/poincare/src/number.cpp index 9f8d0e03f..0eac1d338 100644 --- a/poincare/src/number.cpp +++ b/poincare/src/number.cpp @@ -1,5 +1,6 @@ #include #include +#include Number::Number(int v) : m_value(v) { for (int i=0; i<16; i++) { @@ -17,10 +18,14 @@ Number::Number(int v) : m_value(v) { } } +Expression ** Number::children() { + return NULL; +} + void Number::layout() { m_frame.size = KDStringSize(m_stringValue); } void Number::draw() { - KDDrawString(m_stringValue, m_frame.origin); + KDDrawString(m_stringValue, KDPOINT(0,0)); } diff --git a/poincare/src/power.cpp b/poincare/src/power.cpp new file mode 100644 index 000000000..e20d4d026 --- /dev/null +++ b/poincare/src/power.cpp @@ -0,0 +1,30 @@ +#include +#include + +#define BASE m_children[0] +#define EXPONENT m_children[1] + +Power::Power(Expression * base, Expression * exponent) { + m_children[0] = base; + m_children[1] = exponent; + m_children[2] = NULL; +} + +Expression ** Power::children() { + return m_children; +} + +void Power::layout() { + m_frame.width = BASE->m_frame.width + EXPONENT->m_frame.width; + m_frame.height = BASE->m_frame.height + EXPONENT->m_frame.height; + + BASE->m_frame.origin = { + .x = 0, + .y = EXPONENT->m_frame.height + }; + + EXPONENT->m_frame.origin = { + .x = BASE->m_frame.width, + .y = 0 + }; +} diff --git a/src/hello.cpp b/src/hello.cpp index de1ffc538..94d564bce 100644 --- a/src/hello.cpp +++ b/src/hello.cpp @@ -24,9 +24,12 @@ void hello() { Fraction f = Fraction(&n1, &n2); - f.layout(); - f.m_frame.origin = (KDPoint){.x = 0, .y = 0}; - f.draw();//(KDPoint){.x = 10, .y = 10}); + Number n3 = Number(3); + Power p = Power(&f, &n3); + + p.recursiveLayout(); + p.m_frame.origin = KDPOINT(0, 0); + p.recursiveDraw(); }