Added app modes, extracted into mode controllers.
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
#include "Page.h"
|
||||
|
||||
Page::Page()
|
||||
{}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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.");
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "TextReader.h"
|
||||
|
||||
class TextStorage
|
||||
{
|
||||
public:
|
||||
TextStorage();
|
||||
|
||||
TextReader* open(char* filename);
|
||||
void close(TextReader* reader);
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user