* Completed support for -s, -S, -k, -W, -o.
This commit is contained in:
parent
4b1d3a28f5
commit
3a513d8be4
3 changed files with 90 additions and 45 deletions
116
src/figlet.c
116
src/figlet.c
|
@ -37,16 +37,42 @@ static int flush_figlet(context_t *);
|
||||||
static int end_figlet(context_t *);
|
static int end_figlet(context_t *);
|
||||||
|
|
||||||
static int open_font(context_t *cx);
|
static int open_font(context_t *cx);
|
||||||
static uint32_t smush(uint32_t, uint32_t, unsigned int);
|
static uint32_t hsmush(uint32_t, uint32_t, unsigned int);
|
||||||
|
|
||||||
int init_figlet(context_t *cx)
|
int init_figlet(context_t *cx)
|
||||||
{
|
{
|
||||||
if(open_font(cx))
|
if(open_font(cx))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* FIXME: read the font's contents */
|
if(cx->full_layout & 0x3f)
|
||||||
if(cx->hlayout == H_DEFAULT)
|
cx->hsmushrule = cx->full_layout & 0x3f;
|
||||||
cx->hlayout = H_SMUSH;
|
else if(cx->old_layout > 0)
|
||||||
|
cx->hsmushrule = cx->old_layout;
|
||||||
|
|
||||||
|
switch(cx->hmode)
|
||||||
|
{
|
||||||
|
case H_DEFAULT:
|
||||||
|
if(cx->old_layout == -1)
|
||||||
|
cx->hmode = H_NONE;
|
||||||
|
else if(cx->old_layout == 0 && (cx->full_layout & 0xc0) == 0x40)
|
||||||
|
cx->hmode = H_KERN;
|
||||||
|
else if((cx->old_layout & 0x3f) && (cx->full_layout & 0x3f)
|
||||||
|
&& (cx->full_layout & 0x80))
|
||||||
|
{
|
||||||
|
cx->hmode = H_SMUSH;
|
||||||
|
cx->hsmushrule = cx->full_layout & 0x3f;
|
||||||
|
}
|
||||||
|
else if(cx->old_layout == 0 && (cx->full_layout & 0xbf) == 0x80)
|
||||||
|
{
|
||||||
|
cx->hmode = H_SMUSH;
|
||||||
|
cx->hsmushrule = 0x3f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cx->hmode = H_OVERLAP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
cx->charcv = cucul_create_canvas(cx->max_length - 2, cx->height);
|
cx->charcv = cucul_create_canvas(cx->max_length - 2, cx->height);
|
||||||
|
|
||||||
|
@ -97,12 +123,12 @@ static int feed_figlet(context_t *cx, uint32_t ch, uint32_t attr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute how much the next character will overlap */
|
/* Compute how much the next character will overlap */
|
||||||
switch(cx->hlayout)
|
switch(cx->hmode)
|
||||||
{
|
{
|
||||||
case H_SMUSH:
|
case H_SMUSH:
|
||||||
case H_KERN:
|
case H_KERN:
|
||||||
case H_OVERLAP:
|
case H_OVERLAP:
|
||||||
extra = (cx->hlayout == H_OVERLAP);
|
extra = (cx->hmode == H_OVERLAP);
|
||||||
overlap = w;
|
overlap = w;
|
||||||
for(y = 0; y < h; y++)
|
for(y = 0; y < h; y++)
|
||||||
{
|
{
|
||||||
|
@ -117,16 +143,16 @@ static int feed_figlet(context_t *cx, uint32_t ch, uint32_t attr)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Handle overlapping */
|
/* Handle overlapping */
|
||||||
if(cx->hlayout == H_OVERLAP && xleft < cx->x)
|
if(cx->hmode == H_OVERLAP && xleft < cx->x)
|
||||||
xleft++;
|
xleft++;
|
||||||
|
|
||||||
/* Handle smushing */
|
/* Handle smushing */
|
||||||
if(cx->hlayout == H_SMUSH)
|
if(cx->hmode == H_SMUSH)
|
||||||
{
|
{
|
||||||
if(xleft < cx->x &&
|
if(xleft < cx->x &&
|
||||||
smush(cucul_get_char(cx->cv, cx->x - 1 - xleft, cx->y + y),
|
hsmush(cucul_get_char(cx->cv, cx->x - 1 - xleft, cx->y + y),
|
||||||
cucul_get_char(cx->charcv, xright, y),
|
cucul_get_char(cx->charcv, xright, y),
|
||||||
0))
|
cx->hsmushrule))
|
||||||
xleft++;
|
xleft++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,11 +192,11 @@ static int feed_figlet(context_t *cx, uint32_t ch, uint32_t attr)
|
||||||
/* FIXME: this could be changed to cucul_put_attr() when the
|
/* FIXME: this could be changed to cucul_put_attr() when the
|
||||||
* function is fixed in libcucul */
|
* function is fixed in libcucul */
|
||||||
//cucul_set_attr(cx->cv, tmpat);
|
//cucul_set_attr(cx->cv, tmpat);
|
||||||
if(ch1 == ' ' || cx->hlayout != H_SMUSH)
|
if(ch1 == ' ' || cx->hmode != H_SMUSH)
|
||||||
cucul_put_char(cx->cv, cx->x + x - overlap, cx->y + y, ch2);
|
cucul_put_char(cx->cv, cx->x + x - overlap, cx->y + y, ch2);
|
||||||
else
|
else
|
||||||
cucul_put_char(cx->cv, cx->x + x - overlap, cx->y + y,
|
cucul_put_char(cx->cv, cx->x + x - overlap, cx->y + y,
|
||||||
smush(ch1, ch2, 0));
|
hsmush(ch1, ch2, cx->hsmushrule));
|
||||||
//cucul_put_attr(cx->cv, cx->x + x, cx->y + y, tmpat);
|
//cucul_put_attr(cx->cv, cx->x + x, cx->y + y, tmpat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,6 +281,16 @@ static int open_font(context_t *cx)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(cx->old_layout < -1 || cx->old_layout > 63 || cx->full_layout > 32767
|
||||||
|
|| ((cx->full_layout & 0x80) && (cx->full_layout & 0x3f) == 0
|
||||||
|
&& cx->old_layout))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "font `%s' has invalid layout %i/%u\n",
|
||||||
|
path, cx->old_layout, cx->full_layout);
|
||||||
|
toiclose(f);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
cx->hardblank = cucul_utf8_to_utf32(hardblank, NULL);
|
cx->hardblank = cucul_utf8_to_utf32(hardblank, NULL);
|
||||||
|
|
||||||
/* Skip comment lines */
|
/* Skip comment lines */
|
||||||
|
@ -373,31 +409,33 @@ static int open_font(context_t *cx)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t smush(uint32_t ch1, uint32_t ch2, unsigned int mode)
|
static uint32_t hsmush(uint32_t ch1, uint32_t ch2, unsigned int rule)
|
||||||
{
|
{
|
||||||
/* Rule 1 */
|
/* Rule 1 */
|
||||||
if(ch1 == ch2 && ch1 != 0xa0)
|
if((rule & 0x01) && ch1 == ch2 && ch1 != 0xa0)
|
||||||
return ch2;
|
return ch2;
|
||||||
|
|
||||||
if(ch1 < 0x80 && ch2 < 0x80)
|
if(ch1 < 0x80 && ch2 < 0x80)
|
||||||
{
|
{
|
||||||
char const rule2[] = "|/\\[]{}()<>";
|
char const charlist[] = "|/\\[]{}()<>";
|
||||||
char const rule3[] = "||/\\[]{}()<>";
|
|
||||||
char *tmp1, *tmp2;
|
char *tmp1, *tmp2;
|
||||||
uint16_t s, p;
|
|
||||||
|
|
||||||
/* Rule 2 */
|
/* Rule 2 */
|
||||||
if(ch1 == '_' && strchr(rule2, ch2))
|
if(rule & 0x02)
|
||||||
return ch2;
|
{
|
||||||
|
if(ch1 == '_' && strchr(charlist, ch2))
|
||||||
|
return ch2;
|
||||||
|
|
||||||
if(ch2 == '_' && strchr(rule2, ch1))
|
if(ch2 == '_' && strchr(charlist, ch1))
|
||||||
return ch1;
|
return ch1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Rule 3 */
|
/* Rule 3 */
|
||||||
if((tmp1 = strchr(rule3, ch1)) && (tmp2 = strchr(rule3, ch2)))
|
if((rule & 0x04) &&
|
||||||
|
(tmp1 = strchr(charlist, ch1)) && (tmp2 = strchr(charlist, ch2)))
|
||||||
{
|
{
|
||||||
int cl1 = (tmp1 - rule3) / 2;
|
int cl1 = (tmp1 + 1 - charlist) / 2;
|
||||||
int cl2 = (tmp2 - rule3) / 2;
|
int cl2 = (tmp2 + 1 - charlist) / 2;
|
||||||
|
|
||||||
if(cl1 < cl2)
|
if(cl1 < cl2)
|
||||||
return ch2;
|
return ch2;
|
||||||
|
@ -406,24 +444,30 @@ static uint32_t smush(uint32_t ch1, uint32_t ch2, unsigned int mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rule 4 */
|
/* Rule 4 */
|
||||||
s = ch1 + ch2;
|
if(rule & 0x08)
|
||||||
p = ch1 * ch2;
|
{
|
||||||
|
uint16_t s = ch1 + ch2;
|
||||||
|
uint16_t p = ch1 * ch2;
|
||||||
|
|
||||||
if(p == 15375 /* '{' * '}' */
|
if(p == 15375 /* '{' * '}' */
|
||||||
|| p == 8463 /* '[' * ']' */
|
|| p == 8463 /* '[' * ']' */
|
||||||
|| (p == 1640 && s == 81)) /* '(' *|+ ')' */
|
|| (p == 1640 && s == 81)) /* '(' *|+ ')' */
|
||||||
return '|';
|
return '|';
|
||||||
|
}
|
||||||
|
|
||||||
/* Rule 5 */
|
/* Rule 5 */
|
||||||
switch((ch1 << 8) | ch2)
|
if(rule & 0x10)
|
||||||
{
|
{
|
||||||
case 0x2f5c: return '|'; /* /\ */
|
switch((ch1 << 8) | ch2)
|
||||||
case 0x5c2f: return 'Y'; /* \/ */
|
{
|
||||||
case 0x3e3c: return 'X'; /* >< */
|
case 0x2f5c: return '|'; /* /\ */
|
||||||
|
case 0x5c2f: return 'Y'; /* \/ */
|
||||||
|
case 0x3e3c: return 'X'; /* >< */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rule 6 */
|
/* Rule 6 */
|
||||||
if(ch1 == ch2 && ch1 == 0xa0)
|
if((rule & 0x20) && ch1 == ch2 && ch1 == 0xa0)
|
||||||
return 0xa0;
|
return 0xa0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
src/main.c
16
src/main.c
|
@ -54,7 +54,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
cx->term_width = 80;
|
cx->term_width = 80;
|
||||||
|
|
||||||
cx->hlayout = H_DEFAULT;
|
cx->hmode = H_DEFAULT;
|
||||||
|
|
||||||
cx->filters = NULL;
|
cx->filters = NULL;
|
||||||
cx->nfilters = 0;
|
cx->nfilters = 0;
|
||||||
|
@ -138,19 +138,19 @@ int main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 's':
|
case 's':
|
||||||
cx->hlayout = H_DEFAULT;
|
cx->hmode = H_DEFAULT;
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
cx->hlayout = H_SMUSH;
|
cx->hmode = H_SMUSH;
|
||||||
break;
|
break;
|
||||||
case 'k':
|
case 'k':
|
||||||
cx->hlayout = H_KERN;
|
cx->hmode = H_KERN;
|
||||||
break;
|
break;
|
||||||
case 'W':
|
case 'W':
|
||||||
cx->hlayout = H_NONE;
|
cx->hmode = H_NONE;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
cx->hlayout = H_OVERLAP;
|
cx->hmode = H_OVERLAP;
|
||||||
break;
|
break;
|
||||||
case 'E': /* --export */
|
case 'E': /* --export */
|
||||||
if(!strcmp(optarg, "list"))
|
if(!strcmp(optarg, "list"))
|
||||||
|
@ -249,7 +249,7 @@ static void usage(void)
|
||||||
# ifdef HAVE_GETOPT_LONG
|
# ifdef HAVE_GETOPT_LONG
|
||||||
printf(" -f, --font <name> select the font\n");
|
printf(" -f, --font <name> select the font\n");
|
||||||
printf(" -d, --directory <dir> specify font directory\n");
|
printf(" -d, --directory <dir> specify font directory\n");
|
||||||
printf(" -s, -S, -k, -W, -o render mode (default smushing, force smushing,\n");
|
printf(" -s, -S, -k, -W, -o render mode (default, force smushing,\n");
|
||||||
printf(" kerning, full width, overlap)\n");
|
printf(" kerning, full width, overlap)\n");
|
||||||
printf(" -w, --width <width> set output width\n");
|
printf(" -w, --width <width> set output width\n");
|
||||||
printf(" -t, --termwidth adapt to terminal's width\n");
|
printf(" -t, --termwidth adapt to terminal's width\n");
|
||||||
|
@ -267,7 +267,7 @@ static void usage(void)
|
||||||
# else
|
# else
|
||||||
printf(" -f <name> select the font\n");
|
printf(" -f <name> select the font\n");
|
||||||
printf(" -d <dir> specify font directory\n");
|
printf(" -d <dir> specify font directory\n");
|
||||||
printf(" -s, -S, -k, -W, -o render mode (default smushing, force smushing,\n");
|
printf(" -s, -S, -k, -W, -o render mode (default, force smushing,\n");
|
||||||
printf(" kerning, full width, overlap)\n");
|
printf(" kerning, full width, overlap)\n");
|
||||||
printf(" -w <width> set output width\n");
|
printf(" -w <width> set output width\n");
|
||||||
printf(" -t adapt to terminal's width\n");
|
printf(" -t adapt to terminal's width\n");
|
||||||
|
|
|
@ -33,7 +33,8 @@ struct toilet_context
|
||||||
int (*end)(struct toilet_context *);
|
int (*end)(struct toilet_context *);
|
||||||
|
|
||||||
/* Used by the FIGlet driver */
|
/* Used by the FIGlet driver */
|
||||||
enum { H_DEFAULT, H_KERN, H_SMUSH, H_NONE, H_OVERLAP } hlayout;
|
enum { H_DEFAULT, H_KERN, H_SMUSH, H_NONE, H_OVERLAP } hmode;
|
||||||
|
unsigned int hsmushrule;
|
||||||
unsigned long int hardblank;
|
unsigned long int hardblank;
|
||||||
unsigned int height, baseline, max_length;
|
unsigned int height, baseline, max_length;
|
||||||
int old_layout;
|
int old_layout;
|
||||||
|
|
Loading…
Reference in a new issue