Proper drawing of expressions

This commit is contained in:
Romain Goyet
2015-05-19 18:06:25 +02:00
parent 86cacc5471
commit ac26f20ffb
21 changed files with 173 additions and 33 deletions

View File

@@ -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

View File

@@ -4,6 +4,7 @@
#include <kandinsky/color.h>
#include <kandinsky/line.h>
#include <kandinsky/rect.h>
#include <kandinsky/referential.h>
#include <kandinsky/text.h>
#include <kandinsky/types.h>

View File

@@ -0,0 +1,14 @@
#ifndef KANDINSKY_REFERENTIAL_H
#define KANDINSKY_REFERENTIAL_H
#include <kandinsky/types.h>
#include <kandinsky/color.h>
void KDSetOrigin(KDPoint origin);
KDPoint KDGetOrigin();
KDColor * KDPixelAddress(KDPoint p);
#define COLOR(p) *KDPixelAddress(p)
#endif

View File

@@ -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;

View File

@@ -1,8 +1,8 @@
#include <kandinsky/line.h>
#include <framebuffer.h>
#include <kandinsky/referential.h>
void KDDrawLine(KDPoint p1, KDPoint p2) {
for (KDCoordinate x = p1.x; x<p2.x; x++) {
PIXEL(x, p1.y) = 0xFF;
COLOR(KDPOINT(x, p1.y)) = 0xFF;
}
}

View File

@@ -1,9 +1,9 @@
#include <kandinsky/rect.h>
#include <framebuffer.h>
#include <kandinsky/referential.h>
#include <string.h>
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);
}
}

View File

@@ -0,0 +1,19 @@
#include <kandinsky/referential.h>
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));
}

View File

@@ -1,12 +1,12 @@
#include <kandinsky/text.h>
#include <framebuffer.h>
#include <kandinsky/referential.h>
#include <string.h>
#include "font.h"
void KDDrawChar(char character, KDPoint p) {
for (int j=0; j<BITMAP_FONT_CHARACTER_HEIGHT;j++) {
for (int i=0; i<BITMAP_FONT_CHARACTER_WIDTH;i++) {
PIXEL(p.x+i, p.y+j) = 0xFF-bitmapFont[character-BITMAP_FONT_FIRST_CHARACTER][j][i];
COLOR(KDPOINT(p.x+i, p.y+j)) = 0xFF-bitmapFont[character-BITMAP_FONT_FIRST_CHARACTER][j][i];
}
}
}

View File

@@ -91,6 +91,10 @@ SECTIONS {
PROVIDE(_ResetServiceRoutine = _start);
PROVIDE(_HardFaultServiceRoutine = abort);
/* C++ code calls __cxa_pure_virtual when a pure-virtual method is called.
* This is an error case, so we just redirect it to abort. */
PROVIDE(__cxa_pure_virtual = abort);
*(.text)
*(.text.*)
} >FLASH

View File

@@ -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

View File

@@ -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)

View File

@@ -4,5 +4,6 @@
#include <poincare/expression.h>
#include <poincare/fraction.h>
#include <poincare/number.h>
#include <poincare/power.h>
#endif

View File

@@ -5,11 +5,19 @@ extern "C" {
#include <kandinsky.h>
}
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

View File

@@ -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

View File

@@ -7,6 +7,7 @@ class Number : public Expression {
public:
Number(int v);
virtual void draw();
virtual Expression ** children();
protected:
virtual void layout();
private:

View File

@@ -0,0 +1,16 @@
#ifndef POINCARE_POWER_H
#define POINCARE_POWER_H
#include <poincare/expression.h>
class Power : public Expression {
public:
Power(Expression * base, Expression * exponent);
virtual Expression ** children();
// protected:
virtual void layout();
private:
Expression * m_children[3];
};
#endif

View File

@@ -1,2 +1,38 @@
#include <poincare/expression.h>
#include <string.h>
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
}

View File

@@ -1,44 +1,47 @@
#include <poincare/fraction.h>
#include <string.h>
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});

View File

@@ -1,5 +1,6 @@
#include <poincare/number.h>
#include <kandinsky/text.h>
#include <string.h>
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));
}

30
poincare/src/power.cpp Normal file
View File

@@ -0,0 +1,30 @@
#include <poincare/power.h>
#include <string.h>
#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
};
}

View File

@@ -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();
}