From 77641d59a7ece60554da6cc1337d885786e5fc3f Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Sat, 17 Mar 2018 22:54:07 -0400 Subject: puzzles: add formatting to help viewer The help text is now processed to generate a style array to pass to the display_text library in addition to the text itself. The help text is still compressed using LZ4, and still fits on the c200v2. Change-Id: I7a3a664f90f67a1a018956c72d2b62d92b8ffd17 --- apps/plugins/puzzles/compress.c | 116 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 106 insertions(+), 10 deletions(-) (limited to 'apps/plugins/puzzles/compress.c') diff --git a/apps/plugins/puzzles/compress.c b/apps/plugins/puzzles/compress.c index 96f0be5232..04df077e53 100644 --- a/apps/plugins/puzzles/compress.c +++ b/apps/plugins/puzzles/compress.c @@ -2,11 +2,14 @@ * output. Do not directly compile or use this program, instead it * will be automatically used by genhelp.sh */ +#include #include #include -#include +#include #include #include +#include + #include "help.h" char *compress(const char *in, int inlen, int *rc, int *minsz, int *minlev) @@ -18,7 +21,7 @@ char *compress(const char *in, int inlen, int *rc, int *minsz, int *minlev) for(int i = LZ4HC_CLEVEL_MIN; i < LZ4HC_CLEVEL_MAX; ++i) { - *rc = LZ4_compress_HC(help_text, outbuf, inlen, maxsz, i); + *rc = LZ4_compress_HC(in, outbuf, inlen, maxsz, i); if(!*rc) { fprintf(stderr, "compress failed\n"); @@ -30,7 +33,7 @@ char *compress(const char *in, int inlen, int *rc, int *minsz, int *minlev) *minlev = i; } } - *rc = LZ4_compress_HC(help_text, outbuf, inlen, maxsz, *minlev); + *rc = LZ4_compress_HC(in, outbuf, inlen, maxsz, *minlev); return outbuf; } @@ -42,28 +45,121 @@ void dump_bytes(unsigned char *buf, int len) int stop = i + 10; for(;i < stop && i < len; ++i) { - printf("0x%02x, ", buf[i]); + unsigned char c = buf[i]; + printf("0x%02x,", c); + if(i != stop - 1 && i != len - 1) + printf(" "); } printf("\n"); } } +/* Input: help text in help_text array (to be compiled against) as a + * standard C string + * Output: C source code on stdout defining the following: + * + * const char help_text_words[]; + * const unsigned short help_text_len; + * const struct style_text help_text_style[]; + * + * help_text_words consists of help_text_len bytes containing the + * words of the help text, delimited with NULs, not a standard C + * string. The rockbox frontend is responsible for generating an array + * of pointers into this array to pass to display_text. */ + int main() { - int inlen = strlen(help_text) + 1, len; + int inlen = strlen(help_text) + 1, outlen; int minsz, minlev; - unsigned char *outbuf = compress(help_text, inlen, &len, &minsz, &minlev); printf("/* auto-generated on " __DATE__ " by genhelp.sh */\n"); - printf("/* orig %d comp %d ratio %g level %d saved %d */\n", inlen, minsz, (double)minsz / inlen, minlev, inlen - minsz); + printf("/* help text is compressed using LZ4; see compress.c for details */\n"); printf("/* DO NOT EDIT! */\n\n"); + + printf("#include \"lib/display_text.h\"\n\n"); + + printf("const struct style_text help_text_style[] = {\n"); + + /* break up words on spaces and newline while printing indices of + * underlined words */ + char *buf = strdup(help_text); + bool underline = false, center = false; + int word_idx = 0, help_text_len = inlen; + + for(int i = 0; i < help_text_len; ++i) + { + switch(buf[i]) + { + case '#': + case '_': + /* title or underlined portion */ + if(buf[i] == '#') + { + center = !center; + if(center) + printf(" { %d, TEXT_CENTER | C_RED },\n", word_idx); + } + else + { + /* underline */ + underline = !underline; + + if(underline) + printf(" { %d, TEXT_UNDERLINE },\n", word_idx); + } + + /* delete the formatting character */ + memmove(buf + i, buf + i + 1, help_text_len - i - 1); + --help_text_len; + --i; + break; + case '$': + /* genhelp.sh replaces the dollar signs in URLs with + * dollar signs to help us out. */ + buf[i] = '_'; + break; + case '\n': + center = false; + /* fall through */ + case ' ': + case '\0': + /* Groups of words that are centered or underlined are + * counted as a single "word". */ + if(!underline && !center) + { + buf[i] = '\0'; + ++word_idx; + } + break; + } + } + /* sanity check */ + int words_check = 0; + for(int i = 0; i < help_text_len; ++i) + if(!buf[i]) + { + ++words_check; + } + + assert(words_check == word_idx); + + printf(" LAST_STYLE_ITEM\n};\n\n"); + + /* remove trailing NULs */ + for(int i = help_text_len - 2; i >= 0 && !buf[i]; --i, --help_text_len, --word_idx); + + unsigned char *outbuf = compress(buf, help_text_len, &outlen, &minsz, &minlev); + + printf("/* orig %d comp %d ratio %g level %d saved %d */\n", help_text_len, minsz, (double)minsz / help_text_len, minlev, help_text_len - minsz); printf("const char help_text[] = {\n"); - dump_bytes(outbuf, len); + dump_bytes(outbuf, outlen); free(outbuf); + free(buf); - printf("};\n"); - printf("const unsigned short help_text_len = %d;\n", inlen); + printf("};\n\n"); + printf("const unsigned short help_text_len = %d;\n", help_text_len); + printf("const unsigned short help_text_words = %d;\n", word_idx); return 0; } -- cgit v1.2.3