* Added filter_flip, filter_flop and filter_rotate.
* Add a -F flag to specify filters to apply. Can be specified more than once, and filters can be chained using ":", eg. "-F flip:gay".
This commit is contained in:
parent
30b6ca2596
commit
5edf3053de
5 changed files with 115 additions and 21 deletions
94
src/filter.c
94
src/filter.c
|
@ -20,11 +20,84 @@
|
|||
#if defined(HAVE_INTTYPES_H)
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <cucul.h>
|
||||
|
||||
#include "toilet.h"
|
||||
#include "filter.h"
|
||||
|
||||
void filter_autocrop(cucul_canvas_t *cv)
|
||||
static void filter_crop(cucul_canvas_t *);
|
||||
static void filter_gay(cucul_canvas_t *);
|
||||
static void filter_metal(cucul_canvas_t *);
|
||||
static void filter_flip(cucul_canvas_t *);
|
||||
static void filter_flop(cucul_canvas_t *);
|
||||
static void filter_rotate(cucul_canvas_t *);
|
||||
|
||||
struct
|
||||
{
|
||||
char const *name;
|
||||
void (*function)(cucul_canvas_t *);
|
||||
}
|
||||
const lookup[] =
|
||||
{
|
||||
{ "crop", filter_crop },
|
||||
{ "gay", filter_gay },
|
||||
{ "metal", filter_metal },
|
||||
{ "flip", filter_flip },
|
||||
{ "flop", filter_flop },
|
||||
{ "rotate", filter_rotate },
|
||||
};
|
||||
|
||||
int filter_add(context_t *cx, char const *filter)
|
||||
{
|
||||
unsigned int n;
|
||||
int i;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
while(*filter == ':')
|
||||
filter++;
|
||||
|
||||
if(*filter == '\0')
|
||||
break;
|
||||
|
||||
for(i = sizeof(lookup) / sizeof(lookup[0]); i--; )
|
||||
if(!strncmp(filter, lookup[i].name, strlen(lookup[i].name)))
|
||||
break;
|
||||
|
||||
n = strlen(lookup[i].name);
|
||||
|
||||
if(i == -1 || (filter[n] != ':' && filter[n] != '\0'))
|
||||
{
|
||||
fprintf(stderr, "unknown filter near `%s'\n", filter);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((cx->nfilters % 16) == 0)
|
||||
cx->filters = realloc(cx->filters, (cx->nfilters + 16)
|
||||
* sizeof(lookup[0].function));
|
||||
cx->filters[cx->nfilters] = lookup[i].function;
|
||||
cx->nfilters++;
|
||||
|
||||
filter += n;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int filter_do(context_t *cx)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for(i = 0; i < cx->nfilters; i++)
|
||||
cx->filters[i](cx->cv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void filter_crop(cucul_canvas_t *cv)
|
||||
{
|
||||
unsigned int x, y, w, h;
|
||||
unsigned int xmin, xmax, ymin, ymax;
|
||||
|
@ -58,7 +131,7 @@ void filter_autocrop(cucul_canvas_t *cv)
|
|||
xmax - xmin + 1, ymax - ymin + 1);
|
||||
}
|
||||
|
||||
void filter_metal(cucul_canvas_t *cv)
|
||||
static void filter_metal(cucul_canvas_t *cv)
|
||||
{
|
||||
static unsigned char const palette[] =
|
||||
{
|
||||
|
@ -88,7 +161,7 @@ void filter_metal(cucul_canvas_t *cv)
|
|||
}
|
||||
}
|
||||
|
||||
void filter_gay(cucul_canvas_t *cv)
|
||||
static void filter_gay(cucul_canvas_t *cv)
|
||||
{
|
||||
static unsigned char const rainbow[] =
|
||||
{
|
||||
|
@ -117,3 +190,18 @@ void filter_gay(cucul_canvas_t *cv)
|
|||
}
|
||||
}
|
||||
|
||||
static void filter_flip(cucul_canvas_t *cv)
|
||||
{
|
||||
cucul_flip(cv);
|
||||
}
|
||||
|
||||
static void filter_flop(cucul_canvas_t *cv)
|
||||
{
|
||||
cucul_flop(cv);
|
||||
}
|
||||
|
||||
static void filter_rotate(cucul_canvas_t *cv)
|
||||
{
|
||||
cucul_rotate(cv);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
* This header defines post-processing filter functions.
|
||||
*/
|
||||
|
||||
extern void filter_autocrop(cucul_canvas_t *);
|
||||
extern void filter_metal(cucul_canvas_t *);
|
||||
extern void filter_gay(cucul_canvas_t *);
|
||||
extern int filter_add(context_t *, char const *);
|
||||
extern int filter_do(context_t *);
|
||||
|
||||
|
|
2
src/io.c
2
src/io.c
|
@ -45,7 +45,7 @@ struct toifile
|
|||
FILE *f;
|
||||
};
|
||||
|
||||
TOIFILE *toiopen(const char *path, const char *mode)
|
||||
TOIFILE *toiopen(char const *path, const char *mode)
|
||||
{
|
||||
TOIFILE *toif = malloc(sizeof(*toif));
|
||||
|
||||
|
|
29
src/main.c
29
src/main.c
|
@ -50,8 +50,6 @@ int main(int argc, char *argv[])
|
|||
|
||||
int i, j, ret;
|
||||
|
||||
unsigned int flag_gay = 0;
|
||||
unsigned int flag_metal = 0;
|
||||
int infocode = -1;
|
||||
|
||||
cx->export = "utf8";
|
||||
|
@ -60,6 +58,9 @@ int main(int argc, char *argv[])
|
|||
|
||||
cx->term_width = 80;
|
||||
|
||||
cx->filters = NULL;
|
||||
cx->nfilters = 0;
|
||||
|
||||
#if defined(HAVE_GETOPT_H)
|
||||
for(;;)
|
||||
{
|
||||
|
@ -73,6 +74,7 @@ int main(int argc, char *argv[])
|
|||
{ "directory", 1, NULL, 'd' },
|
||||
{ "width", 1, NULL, 'w' },
|
||||
{ "termwidth", 0, NULL, 't' },
|
||||
{ "filter", 1, NULL, 'F' },
|
||||
{ "gay", 0, NULL, 'g' },
|
||||
{ "metal", 0, NULL, 'm' },
|
||||
{ "irc", 0, NULL, 'i' },
|
||||
|
@ -82,11 +84,11 @@ int main(int argc, char *argv[])
|
|||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
int c = getopt_long(argc, argv, "d:f:I:w:ghimtv",
|
||||
int c = getopt_long(argc, argv, "f:d:w:tF:gmihI:v",
|
||||
long_options, &option_index);
|
||||
# else
|
||||
# define MOREINFO "Try `%s -h' for more information.\n"
|
||||
int c = getopt(argc, argv, "d:f:I:w:ghimtv");
|
||||
int c = getopt(argc, argv, "f:d:w:tF:gmihI:v");
|
||||
# endif
|
||||
if(c == -1)
|
||||
break;
|
||||
|
@ -108,11 +110,15 @@ int main(int argc, char *argv[])
|
|||
case 'd': /* --directory */
|
||||
cx->dir = optarg;
|
||||
break;
|
||||
case 'F': /* --filter */
|
||||
if(filter_add(cx, optarg))
|
||||
return -1;
|
||||
break;
|
||||
case 'g': /* --gay */
|
||||
flag_gay = 1;
|
||||
filter_add(cx, "gay");
|
||||
break;
|
||||
case 'm': /* --metal */
|
||||
flag_metal = 1;
|
||||
filter_add(cx, "metal");
|
||||
break;
|
||||
case 'w': /* --width */
|
||||
cx->term_width = atoi(optarg);
|
||||
|
@ -220,12 +226,7 @@ int main(int argc, char *argv[])
|
|||
cx->end(cx);
|
||||
|
||||
/* Apply optional effects to our string */
|
||||
if(!strcasecmp(cx->font, "mono9"))
|
||||
filter_autocrop(cx->cv);
|
||||
if(flag_metal)
|
||||
filter_metal(cx->cv);
|
||||
if(flag_gay)
|
||||
filter_gay(cx->cv);
|
||||
filter_do(cx);
|
||||
|
||||
/* Output char */
|
||||
buffer = cucul_export_canvas(cx->cv, cx->export);
|
||||
|
@ -240,7 +241,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
#if defined(HAVE_GETOPT_H)
|
||||
# define USAGE \
|
||||
"Usage: toilet [ -ghimtv ] [ -d fontdirectory ]\n" \
|
||||
"Usage: toilet [ -ghimtvF ] [ -d fontdirectory ]\n" \
|
||||
" [ -f fontfile ] [ -w outputwidth ]\n" \
|
||||
" [ -I infocode ] [ message ]\n"
|
||||
#else
|
||||
|
@ -274,6 +275,7 @@ static void usage(void)
|
|||
printf(" -d, --directory <dir> specify font directory\n");
|
||||
printf(" -w, --width <width> set output width\n");
|
||||
printf(" -t, --termwidth adapt to terminal's width\n");
|
||||
printf(" -F, --filter apply one or several filters to the text\n");
|
||||
printf(" -g, --gay add a rainbow effect to the text\n");
|
||||
printf(" -m, --metal add a metal effect to the text\n");
|
||||
printf(" -i, --irc output IRC colour codes\n");
|
||||
|
@ -285,6 +287,7 @@ static void usage(void)
|
|||
printf(" -d <dir> specify font directory\n");
|
||||
printf(" -w <width> set output width\n");
|
||||
printf(" -t adapt to terminal's width\n");
|
||||
printf(" -F apply one or several filters to the text\n");
|
||||
printf(" -g add a rainbow effect to the text\n");
|
||||
printf(" -m add a metal effect to the text\n");
|
||||
printf(" -i output IRC colour codes\n");
|
||||
|
|
|
@ -26,7 +26,7 @@ struct toilet_context
|
|||
cucul_canvas_t *cv;
|
||||
unsigned int w, h, ew, eh, x, y;
|
||||
|
||||
/* Methods */
|
||||
/* Render methods */
|
||||
int (*feed)(struct toilet_context *, uint32_t);
|
||||
int (*end)(struct toilet_context *);
|
||||
|
||||
|
@ -43,6 +43,10 @@ struct toilet_context
|
|||
unsigned int glyphs;
|
||||
cucul_canvas_t *image;
|
||||
unsigned int *lookup;
|
||||
|
||||
/* Render filters */
|
||||
void (**filters)(cucul_canvas_t *);
|
||||
unsigned int nfilters;
|
||||
};
|
||||
|
||||
typedef struct toilet_context context_t;
|
||||
|
|
Loading…
Reference in a new issue