Sfoglia il codice sorgente

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

master
dejvino 4 anni fa
parent
commit
f343983184
11 ha cambiato i file con 149 aggiunte e 21 eliminazioni
  1. +4
    -3
      components/epaper/EPD.c
  2. +1
    -0
      components/epaper/EPD.h
  3. +1
    -0
      main/Page.h
  4. +3
    -2
      main/PagePrinter.cpp
  5. +0
    -2
      main/PagePrinter.h
  6. +48
    -0
      main/PageSettingsProvider.cpp
  7. +12
    -0
      main/PageSettingsProvider.h
  8. +1
    -1
      main/TextReader.cpp
  9. +56
    -8
      main/Typesetter.cpp
  10. +8
    -0
      main/Typesetter.h
  11. +15
    -5
      main/main.cpp

+ 4
- 3
components/epaper/EPD.c Vedi 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_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);


+ 1
- 0
components/epaper/EPD.h Vedi 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_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


+ 1
- 0
main/Page.h Vedi File

@@ -7,6 +7,7 @@ class Page
public:
Page();

size_t start;
char* text;
size_t len;



+ 3
- 2
main/PagePrinter.cpp Vedi File

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


+ 0
- 2
main/PagePrinter.h Vedi File

@@ -6,6 +6,4 @@ public:
PagePrinter();

void print(Page* page);

private:
};

+ 48
- 0
main/PageSettingsProvider.cpp Vedi 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
- 0
main/PageSettingsProvider.h Vedi 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();
};

+ 1
- 1
main/TextReader.cpp Vedi File

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


+ 56
- 8
main/Typesetter.cpp Vedi File

@@ -1,27 +1,38 @@
#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
}

Page* Typesetter::preparePage(char* text, size_t len)
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);
}

+ 8
- 0
main/Typesetter.h Vedi File

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


+ 15
- 5
main/main.cpp Vedi File

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


Caricamento…
Annulla
Salva