mirror of
https://github.com/Dejvino/lilybook.git
synced 2024-12-04 19:58:50 +00:00
Implemented typesetter to allow exact paging. Improved spacing between chars.
This commit is contained in:
parent
05f1856a10
commit
f343983184
@ -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_buffered_char;
|
||||
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
|
||||
color_t _fg; // current foreground color for fonts
|
||||
color_t _bg; // current background for non transparent fonts
|
||||
@ -1732,10 +1733,10 @@ int EPD_getStringWidth(char* str)
|
||||
char* tempStrptr = str;
|
||||
while (*tempStrptr != 0) {
|
||||
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;
|
||||
}
|
||||
@ -1980,7 +1981,7 @@ void EPD_print(char *st, int x, int y) {
|
||||
// Let's print the character
|
||||
if (cfont.x_size == 0) {
|
||||
// == 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 {
|
||||
// rotated proportional font
|
||||
offset += rotatePropChar(x, y, offset);
|
||||
|
@ -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_buffered_char;
|
||||
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 color_t _fg; // current foreground color for fonts
|
||||
extern color_t _bg; // current background for non transparent fonts
|
||||
|
@ -7,6 +7,7 @@ class Page
|
||||
public:
|
||||
Page();
|
||||
|
||||
size_t start;
|
||||
char* text;
|
||||
size_t len;
|
||||
|
||||
|
@ -5,7 +5,8 @@
|
||||
#include "esp_log.h"
|
||||
static const char *TAG = "PagePrinter";
|
||||
|
||||
int font = DEJAVU18_FONT;//DEFAULT_FONT;
|
||||
//int pageFont = DEFAULT_FONT;
|
||||
int pageFont = DEJAVU18_FONT;
|
||||
|
||||
PagePrinter::PagePrinter()
|
||||
{}
|
||||
@ -19,7 +20,7 @@ void PagePrinter::print(Page* page)
|
||||
if (page->len == 0) {
|
||||
return;
|
||||
}
|
||||
EPD_setFont(font, NULL);
|
||||
EPD_setFont(pageFont, NULL);
|
||||
text_wrap = 1;
|
||||
EPD_print(page->text, 0, 0);
|
||||
//EPD_UpdateScreen();
|
||||
|
@ -6,6 +6,4 @@ public:
|
||||
PagePrinter();
|
||||
|
||||
void print(Page* page);
|
||||
|
||||
private:
|
||||
};
|
||||
|
48
main/PageSettingsProvider.cpp
Normal file
48
main/PageSettingsProvider.cpp
Normal 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;
|
||||
}
|
12
main/PageSettingsProvider.h
Normal file
12
main/PageSettingsProvider.h
Normal 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();
|
||||
};
|
@ -32,7 +32,7 @@ size_t TextReader::read(long pos, char* text, size_t len)
|
||||
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);
|
||||
//ESP_LOGI(TAG, "Read content: %s", text);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "End of file. Closing.");
|
||||
fclose(this->f);
|
||||
|
@ -1,27 +1,38 @@
|
||||
#include <string.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->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)
|
||||
{
|
||||
Page* page = new Page;
|
||||
page->text = new char[len+1];
|
||||
memcpy(page->text, text, len);
|
||||
page->text[len] = 0;
|
||||
page->len = len;
|
||||
return page;
|
||||
return this->preparePageInternal(text, len, 1);
|
||||
}
|
||||
|
||||
void Typesetter::destroyPage(Page* page)
|
||||
@ -32,3 +43,40 @@ void Typesetter::destroyPage(Page* page)
|
||||
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);
|
||||
}
|
@ -1,12 +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
|
||||
};
|
||||
|
||||
|
@ -70,11 +70,20 @@ extern "C" void app_main()
|
||||
if (textReader != NULL) {
|
||||
if (pageCurrent == NULL) {
|
||||
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) {
|
||||
size_t read = textReader->read(bookmark - sizeof(text), text, sizeof(text));
|
||||
pageLast = typesetter.preparePreviousPage(text, sizeof(text));
|
||||
// align with the start?
|
||||
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 {
|
||||
typesetter.destroyPage(pageCurrent);
|
||||
@ -97,7 +106,8 @@ extern "C" void app_main()
|
||||
if (buttons_pressed_plus()) {
|
||||
ESP_LOGI(TAG, "Turn page PLUS.");
|
||||
if (pageCurrent != NULL) {
|
||||
bookmark += pageCurrent->len;
|
||||
bookmark = pageCurrent->start + pageCurrent->len;
|
||||
// TODO: limit bookmark to file size
|
||||
typesetter.destroyPage(pageLast);
|
||||
pageLast = pageCurrent;
|
||||
pageCurrent = NULL;
|
||||
@ -109,7 +119,7 @@ extern "C" void app_main()
|
||||
if (buttons_pressed_minus()) {
|
||||
ESP_LOGI(TAG, "Turn page MINUS.");
|
||||
if (pageLast != NULL) {
|
||||
bookmark -= pageLast->len;
|
||||
bookmark = pageLast->start;
|
||||
typesetter.destroyPage(pageCurrent);
|
||||
pageCurrent = pageLast;
|
||||
pageLast = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user