Added app modes, extracted into mode controllers.

This commit is contained in:
dejvino
2020-02-02 01:04:10 +01:00
parent f343983184
commit a32fcd8785
32 changed files with 323 additions and 107 deletions
+4
View File
@@ -0,0 +1,4 @@
#include "Page.h"
Page::Page()
{}
+17
View File
@@ -0,0 +1,17 @@
#ifndef _PAGE_H_
#define _PAGE_H_
#include <stdlib.h>
class Page
{
public:
Page();
size_t start;
char* text;
size_t len;
private:
};
#endif
+28
View File
@@ -0,0 +1,28 @@
#include "display.h"
#include "EPD.h"
#include "PagePrinter.h"
#include "esp_log.h"
static const char *TAG = "PagePrinter";
//int pageFont = DEFAULT_FONT;
int pageFont = DEJAVU18_FONT;
PagePrinter::PagePrinter()
{}
void PagePrinter::print(Page* page)
{
if (page->text == NULL) {
ESP_LOGE(TAG, "Page text is NULL");
return;
}
if (page->len == 0) {
return;
}
EPD_setFont(pageFont, NULL);
text_wrap = 1;
EPD_print(page->text, 0, 0);
//EPD_UpdateScreen();
}
+9
View File
@@ -0,0 +1,9 @@
#include "Page.h"
class PagePrinter
{
public:
PagePrinter();
void print(Page* page);
};
@@ -0,0 +1,48 @@
#include "PageSettingsProvider.h"
#include "EPD.h"
#include "EPDspi.h" // TODO: remove after display config is extracted
int PageSettingsProvider::getWidth()
{
return EPD_DISPLAY_WIDTH;
}
int PageSettingsProvider::getHeight()
{
return EPD_DISPLAY_HEIGHT;
}
int PageSettingsProvider::getCharWidth(char c)
{
char txt[2] = { c, 0x00 };
return this->getStringWidth(txt);
}
extern int pageFont;
void activatePageFont()
{
EPD_setFont(pageFont, NULL); // TODO: hack to get the same font as the printer
}
int PageSettingsProvider::getStringWidth(char* string)
{
activatePageFont();
int ret = EPD_getStringWidth(string);
return ret;
}
int PageSettingsProvider::getCharSpace()
{
return font_x_space;
}
int PageSettingsProvider::getLineHeight()
{
activatePageFont();
return EPD_getfontheight();
}
int PageSettingsProvider::getLineSpace()
{
return font_line_space;
}
+12
View File
@@ -0,0 +1,12 @@
class PageSettingsProvider
{
public:
int getWidth();
int getHeight();
int getCharWidth(char c);
int getStringWidth(char* string);
int getCharSpace();
int getLineHeight();
int getLineSpace();
};
+43
View File
@@ -0,0 +1,43 @@
#include <string.h>
#include "TextReader.h"
#include "esp_log.h"
static const char *TAG = "TextReader";
TextReader::TextReader(FILE* file)
{
this->f = file;
}
void TextReader::close()
{
fclose(this->f);
}
size_t TextReader::read(long pos, char* text, size_t len)
{
memset(text, 0, len);
if (pos < 0) {
len += pos;
pos = 0;
}
if (len <= 0) {
return 0;
}
if (this->f == NULL) {
ESP_LOGE(TAG, "File not opened.");
sprintf(text, "File could not be opened.");
return 0;
} else {
fseek(this->f, pos, SEEK_SET);
size_t read = fread(text, 1, len, this->f);
if (read > 0) {
//ESP_LOGI(TAG, "Read content: %s", text);
} else {
ESP_LOGI(TAG, "End of file. Closing.");
fclose(this->f);
this->f = NULL;
}
return read;
}
}
+16
View File
@@ -0,0 +1,16 @@
#include <stdlib.h>
#include <stdio.h>
class TextReader
{
public:
TextReader(FILE* file);
size_t read(long pos, char* text, size_t len);
void close();
private:
FILE* f;
};
+25
View File
@@ -0,0 +1,25 @@
#include "TextStorage.h"
#include "esp_log.h"
static const char *TAG = "TextStorage";
TextStorage::TextStorage()
{}
TextReader* TextStorage::open(char* filename)
{
FILE* f = fopen("/sdcard/book.txt", "r");
if (f == NULL) {
ESP_LOGE(TAG, "File could not be opened");
return NULL;
}
ESP_LOGI(TAG, "File opened for reading.");
return new TextReader(f);
}
void TextStorage::close(TextReader* reader)
{
reader->close();
delete reader;
ESP_LOGI(TAG, "File closed.");
}
+10
View File
@@ -0,0 +1,10 @@
#include "TextReader.h"
class TextStorage
{
public:
TextStorage();
TextReader* open(char* filename);
void close(TextReader* reader);
};
+82
View File
@@ -0,0 +1,82 @@
#include <string.h>
#include "Typesetter.h"
#include "esp_log.h"
static const char *TAG = "Typesetter";
Typesetter::Typesetter()
{
this->pageSettingsProvider = new PageSettingsProvider(); // TODO: make it a param
}
Typesetter::~Typesetter()
{
delete this->pageSettingsProvider;
}
static Page* extractPage(char* text, size_t len)
{
Page* page = new Page;
page->text = new char[len+1];
memcpy(page->text, text, len);
page->text[len] = 0;
page->len = len;
ESP_LOGI(TAG, "Extracted page (%d bytes):\n%s\n----", page->len, page->text);
return page;
}
Page* Typesetter::preparePage(char* text, size_t len)
{
return this->preparePageInternal(text, len, 0);
}
Page* Typesetter::preparePreviousPage(char* text, size_t len)
{
return this->preparePageInternal(text, len, 1);
}
void Typesetter::destroyPage(Page* page)
{
if (page == NULL) {
return;
}
delete page->text;
delete page;
}
Page* Typesetter::preparePageInternal(char* text, size_t len, int reverse)
{
int page_width = this->pageSettingsProvider->getWidth();
int page_height = this->pageSettingsProvider->getHeight();
int line_height = this->pageSettingsProvider->getLineHeight()
+ this->pageSettingsProvider->getLineSpace();
int line_count = page_height / line_height;
char buf[len+1];
memset(buf, 0, len+1);
int line_start = 0;
ESP_LOGI(TAG, " === Typesetting%s page === ", reverse ? " reversed" : "");
for (int line = 0; line < line_count && line_start < len; line++) {
int i;
for (i = line_start; i < len; i++) {
buf[i] = text[reverse ? (len - i) : (i)];
if (buf[i] == '\n') {
break;
}
int line_width = this->pageSettingsProvider->getStringWidth(&buf[line_start]);
if (line_width > page_width) {
// backtrack
buf[i] = 0;
i--;
break;
}
}
ESP_LOGI(TAG, "Line %d | %s", line, &buf[line_start]);
//ESP_LOGI(TAG, "Line %d [%04d:%04d] | %s | %03d / %03d", line, line_start, i, &buf[line_start],
// this->pageSettingsProvider->getStringWidth(&buf[line_start]), page_width);
line_start = i + 1;
}
return extractPage(text, line_start);
}
+20
View File
@@ -0,0 +1,20 @@
#include <stdlib.h>
#include "Page.h"
#include "PageSettingsProvider.h"
class Typesetter
{
public:
Typesetter();
~Typesetter();
Page* preparePage(char* text, size_t len);
Page* preparePreviousPage(char* text, size_t len);
void destroyPage(Page* page);
private:
Page* preparePageInternal(char* text, size_t len, int direction);
PageSettingsProvider* pageSettingsProvider; // TODO: expose so it may be changed
};