mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
Proper drawing of expressions
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
14
kandinsky/include/kandinsky/referential.h
Normal file
14
kandinsky/include/kandinsky/referential.h
Normal 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
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
19
kandinsky/src/referential.c
Normal file
19
kandinsky/src/referential.c
Normal 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));
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -4,5 +4,6 @@
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/fraction.h>
|
||||
#include <poincare/number.h>
|
||||
#include <poincare/power.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -7,6 +7,7 @@ class Number : public Expression {
|
||||
public:
|
||||
Number(int v);
|
||||
virtual void draw();
|
||||
virtual Expression ** children();
|
||||
protected:
|
||||
virtual void layout();
|
||||
private:
|
||||
|
||||
16
poincare/include/poincare/power.h
Normal file
16
poincare/include/poincare/power.h
Normal 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
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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});
|
||||
|
||||
@@ -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
30
poincare/src/power.cpp
Normal 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
|
||||
};
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user