1
0
mirror of https://github.com/Dejvino/lilybook.git synced 2024-12-22 19:48:50 +00:00

Implemented typesetter to allow exact paging. Improved spacing between chars.

This commit is contained in:
dejvino 2020-02-01 01:04:11 +01:00
parent 05f1856a10
commit f343983184
11 changed files with 150 additions and 22 deletions

View File

@ -44,6 +44,7 @@ uint8_t font_transparent; // if not 0 draw fonts transparent
uint8_t font_forceFixed; // if not zero force drawing proportional fonts with fixed width uint8_t font_forceFixed; // if not zero force drawing proportional fonts with fixed width
uint8_t font_buffered_char; uint8_t font_buffered_char;
uint8_t font_line_space; // additional spacing between text lines; added to font height uint8_t font_line_space; // additional spacing between text lines; added to font height
uint8_t font_x_space; // additional spacing between characters in x axis
uint8_t text_wrap; // if not 0 wrap long text to the new line, else clip uint8_t text_wrap; // if not 0 wrap long text to the new line, else clip
color_t _fg; // current foreground color for fonts color_t _fg; // current foreground color for fonts
color_t _bg; // current background for non transparent fonts color_t _bg; // current background for non transparent fonts
@ -1732,10 +1733,10 @@ int EPD_getStringWidth(char* str)
char* tempStrptr = str; char* tempStrptr = str;
while (*tempStrptr != 0) { while (*tempStrptr != 0) {
if (getCharPtr(*tempStrptr++)) { if (getCharPtr(*tempStrptr++)) {
strWidth += (((fontChar.width > fontChar.xDelta) ? fontChar.width : fontChar.xDelta) + 1); strWidth += (((fontChar.width > fontChar.xDelta) ? fontChar.width : fontChar.xDelta) + font_x_space);
} }
} }
strWidth--; strWidth -= font_x_space;
} }
return strWidth; return strWidth;
} }
@ -1980,7 +1981,7 @@ void EPD_print(char *st, int x, int y) {
// Let's print the character // Let's print the character
if (cfont.x_size == 0) { if (cfont.x_size == 0) {
// == proportional font // == proportional font
if (font_rotate == 0) EPD_X += printProportionalChar( EPD_X, EPD_Y) + 1; if (font_rotate == 0) EPD_X += printProportionalChar( EPD_X, EPD_Y) + font_x_space;
else { else {
// rotated proportional font // rotated proportional font
offset += rotatePropChar(x, y, offset); offset += rotatePropChar(x, y, offset);

View File

@ -45,6 +45,7 @@ extern uint8_t font_transparent; // if not 0 draw fonts transparent
extern uint8_t font_forceFixed; // if not zero force drawing proportional fonts with fixed width extern uint8_t font_forceFixed; // if not zero force drawing proportional fonts with fixed width
extern uint8_t font_buffered_char; extern uint8_t font_buffered_char;
extern uint8_t font_line_space; // additional spacing between text lines; added to font height extern uint8_t font_line_space; // additional spacing between text lines; added to font height
extern uint8_t font_x_space; // additional spacing between characters in x axis
extern uint8_t text_wrap; // if not 0 wrap long text to the new line, else clip extern uint8_t text_wrap; // if not 0 wrap long text to the new line, else clip
extern color_t _fg; // current foreground color for fonts extern color_t _fg; // current foreground color for fonts
extern color_t _bg; // current background for non transparent fonts extern color_t _bg; // current background for non transparent fonts

View File

@ -7,6 +7,7 @@ class Page
public: public:
Page(); Page();
size_t start;
char* text; char* text;
size_t len; size_t len;

View File

@ -5,7 +5,8 @@
#include "esp_log.h" #include "esp_log.h"
static const char *TAG = "PagePrinter"; static const char *TAG = "PagePrinter";
int font = DEJAVU18_FONT;//DEFAULT_FONT; //int pageFont = DEFAULT_FONT;
int pageFont = DEJAVU18_FONT;
PagePrinter::PagePrinter() PagePrinter::PagePrinter()
{} {}
@ -19,7 +20,7 @@ void PagePrinter::print(Page* page)
if (page->len == 0) { if (page->len == 0) {
return; return;
} }
EPD_setFont(font, NULL); EPD_setFont(pageFont, NULL);
text_wrap = 1; text_wrap = 1;
EPD_print(page->text, 0, 0); EPD_print(page->text, 0, 0);
//EPD_UpdateScreen(); //EPD_UpdateScreen();

View File

@ -6,6 +6,4 @@ public:
PagePrinter(); PagePrinter();
void print(Page* page); void print(Page* page);
private:
}; };

View File

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

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

View File

@ -32,7 +32,7 @@ size_t TextReader::read(long pos, char* text, size_t len)
fseek(this->f, pos, SEEK_SET); fseek(this->f, pos, SEEK_SET);
size_t read = fread(text, 1, len, this->f); size_t read = fread(text, 1, len, this->f);
if (read > 0) { if (read > 0) {
ESP_LOGI(TAG, "Read content: %s", text); //ESP_LOGI(TAG, "Read content: %s", text);
} else { } else {
ESP_LOGI(TAG, "End of file. Closing."); ESP_LOGI(TAG, "End of file. Closing.");
fclose(this->f); fclose(this->f);

View File

@ -1,27 +1,38 @@
#include <string.h> #include <string.h>
#include "Typesetter.h" #include "Typesetter.h"
Typesetter::Typesetter() #include "esp_log.h"
{} static const char *TAG = "Typesetter";
Page* Typesetter::preparePage(char* text, size_t len) 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* page = new Page;
page->text = new char[len+1]; page->text = new char[len+1];
memcpy(page->text, text, len); memcpy(page->text, text, len);
page->text[len] = 0; page->text[len] = 0;
page->len = len; page->len = len;
ESP_LOGI(TAG, "Extracted page (%d bytes):\n%s\n----", page->len, page->text);
return page; return page;
} }
Page* Typesetter::preparePage(char* text, size_t len)
{
return this->preparePageInternal(text, len, 0);
}
Page* Typesetter::preparePreviousPage(char* text, size_t len) Page* Typesetter::preparePreviousPage(char* text, size_t len)
{ {
Page* page = new Page; return this->preparePageInternal(text, len, 1);
page->text = new char[len+1];
memcpy(page->text, text, len);
page->text[len] = 0;
page->len = len;
return page;
} }
void Typesetter::destroyPage(Page* page) void Typesetter::destroyPage(Page* page)
@ -32,3 +43,40 @@ void Typesetter::destroyPage(Page* page)
delete page->text; delete page->text;
delete page; 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);
}

View File

@ -1,12 +1,20 @@
#include <stdlib.h> #include <stdlib.h>
#include "Page.h" #include "Page.h"
#include "PageSettingsProvider.h"
class Typesetter class Typesetter
{ {
public: public:
Typesetter(); Typesetter();
~Typesetter();
Page* preparePage(char* text, size_t len); Page* preparePage(char* text, size_t len);
Page* preparePreviousPage(char* text, size_t len); Page* preparePreviousPage(char* text, size_t len);
void destroyPage(Page* page); void destroyPage(Page* page);
private:
Page* preparePageInternal(char* text, size_t len, int direction);
PageSettingsProvider* pageSettingsProvider; // TODO: expose so it may be changed
}; };

View File

@ -70,11 +70,20 @@ extern "C" void app_main()
if (textReader != NULL) { if (textReader != NULL) {
if (pageCurrent == NULL) { if (pageCurrent == NULL) {
size_t read = textReader->read(bookmark, text, sizeof(text)); size_t read = textReader->read(bookmark, text, sizeof(text));
pageCurrent = typesetter.preparePage(text, sizeof(text)); pageCurrent = typesetter.preparePage(text, read);
pageCurrent->start = bookmark;
} }
if (pageLast == NULL) { if (pageLast == NULL) {
size_t read = textReader->read(bookmark - sizeof(text), text, sizeof(text)); // align with the start?
pageLast = typesetter.preparePreviousPage(text, sizeof(text)); if (bookmark < sizeof(text)) {
size_t read = textReader->read(0, text, sizeof(text));
pageLast = typesetter.preparePage(text, read);
pageLast->start = 0;
} else {
size_t read = textReader->read((bookmark - sizeof(text)), text, sizeof(text));
pageLast = typesetter.preparePreviousPage(text, read);
pageLast->start = bookmark - pageLast->len;
}
} }
} else { } else {
typesetter.destroyPage(pageCurrent); typesetter.destroyPage(pageCurrent);
@ -97,7 +106,8 @@ extern "C" void app_main()
if (buttons_pressed_plus()) { if (buttons_pressed_plus()) {
ESP_LOGI(TAG, "Turn page PLUS."); ESP_LOGI(TAG, "Turn page PLUS.");
if (pageCurrent != NULL) { if (pageCurrent != NULL) {
bookmark += pageCurrent->len; bookmark = pageCurrent->start + pageCurrent->len;
// TODO: limit bookmark to file size
typesetter.destroyPage(pageLast); typesetter.destroyPage(pageLast);
pageLast = pageCurrent; pageLast = pageCurrent;
pageCurrent = NULL; pageCurrent = NULL;
@ -109,7 +119,7 @@ extern "C" void app_main()
if (buttons_pressed_minus()) { if (buttons_pressed_minus()) {
ESP_LOGI(TAG, "Turn page MINUS."); ESP_LOGI(TAG, "Turn page MINUS.");
if (pageLast != NULL) { if (pageLast != NULL) {
bookmark -= pageLast->len; bookmark = pageLast->start;
typesetter.destroyPage(pageCurrent); typesetter.destroyPage(pageCurrent);
pageCurrent = pageLast; pageCurrent = pageLast;
pageLast = NULL; pageLast = NULL;