diff options
Diffstat (limited to 'sent.c')
-rw-r--r-- | sent.c | 100 |
1 files changed, 80 insertions, 20 deletions
@@ -284,27 +284,66 @@ ffprepare(Image *img) img->state |= SCALED; } +static unsigned char double_to_uchar_clamp255(double dbl) +{ + dbl = round(dbl); + + return + (dbl < 0.0) ? 0 : + (dbl > 255.0) ? 255 : (unsigned char)dbl; +} + +static int int_clamp(int integer, int lower, int upper) +{ + if (integer < lower) + return lower; + else if (integer >= upper) + return upper - 1; + else + return integer; +} + void ffscale(Image *img) { - unsigned int x, y; - unsigned int width = img->ximg->width; - unsigned int height = img->ximg->height; - char* newBuf = img->ximg->data; - unsigned char* ibuf; - unsigned int jdy = img->ximg->bytes_per_line / 4 - width; - unsigned int dx = (img->bufwidth << 10) / width; - - for (y = 0; y < height; y++) { - unsigned int bufx = img->bufwidth / width; - ibuf = &img->buf[y * img->bufheight / height * img->bufwidth * 3]; - - for (x = 0; x < width; x++) { - *newBuf++ = (ibuf[(bufx >> 10)*3+2]); - *newBuf++ = (ibuf[(bufx >> 10)*3+1]); - *newBuf++ = (ibuf[(bufx >> 10)*3+0]); + const unsigned width = img->ximg->width; + const unsigned height = img->ximg->height; + unsigned char* newBuf = (unsigned char*)img->ximg->data; + const unsigned jdy = img->ximg->bytes_per_line / 4 - width; + + const double x_scale = ((double)img->bufwidth/(double)width); + const double y_scale = ((double)img->bufheight/(double)height); + + for (unsigned y = 0; y < height; ++y) { + const double old_y = (double)y * y_scale; + const double y_factor = ceil(old_y) - old_y; + const int old_y_int_0 = int_clamp((int)floor(old_y), 0, img->bufheight); + const int old_y_int_1 = int_clamp((int)ceil(old_y), 0, img->bufheight); + + for (unsigned x = 0; x < width; ++x) { + const double old_x = (double)x * x_scale; + const double x_factor = ceil(old_x) - old_x; + const int old_x_int_0 = int_clamp((int)floor(old_x), 0, img->bufwidth); + const int old_x_int_1 = int_clamp((int)ceil(old_x), 0, img->bufwidth); + + const unsigned c00_pos = 3*((old_x_int_0) + ((old_y_int_0)*img->bufwidth)); + const unsigned c01_pos = 3*((old_x_int_0) + ((old_y_int_1)*img->bufwidth)); + const unsigned c10_pos = 3*((old_x_int_1) + ((old_y_int_0)*img->bufwidth)); + const unsigned c11_pos = 3*((old_x_int_1) + ((old_y_int_1)*img->bufwidth)); + + for (int i = 2; i >= 0 ; --i) { + const unsigned char c00 = img->buf[c00_pos + i]; + const unsigned char c01 = img->buf[c01_pos + i]; + const unsigned char c10 = img->buf[c10_pos + i]; + const unsigned char c11 = img->buf[c11_pos + i]; + + const double x_result_0 = (double)c00*x_factor + (double)c10*(1.0 - x_factor); + const double x_result_1 = (double)c01*x_factor + (double)c11*(1.0 - x_factor); + const double result = x_result_0*y_factor + x_result_1*(1.0 - y_factor); + + *newBuf++ = double_to_uchar_clamp255(result); + } newBuf++; - bufx += dx; } newBuf += jdy; } @@ -528,8 +567,15 @@ xdraw(void) getfontsize(&slides[idx], &width, &height); XClearWindow(xw.dpy, xw.win); + drw_rect(d, 0, 0, xw.w, xw.h, 1, 1); + + if (idx != 0 && progressheight != 0) { + drw_rect(d, + 0, xw.h - progressheight, + (xw.w * idx)/(slidecount - 1), progressheight, + 1, 0); + } if (!im) { - drw_rect(d, 0, 0, xw.w, xw.h, 1, 1); for (i = 0; i < slides[idx].linecount; i++) drw_text(d, (xw.w - width) / 2, @@ -539,12 +585,17 @@ xdraw(void) 0, slides[idx].lines[i], 0); - drw_map(d, xw.win, 0, 0, xw.w, xw.h); + + drw_map(d, xw.win, 0, 0, xw.w, xw.h); } else { + drw_map(d, xw.win, 0, 0, xw.w, xw.h); + if (!(im->state & SCALED)) ffprepare(im); ffdraw(im); } + + } void @@ -680,7 +731,7 @@ configure(XEvent *e) void usage(void) { - die("usage: %s [file]", argv0); + die("usage: %s [-c fgcolor] [-b bgcolor] [-f font] [file]", argv0); } int @@ -692,6 +743,15 @@ main(int argc, char *argv[]) case 'v': fprintf(stderr, "sent-"VERSION"\n"); return 0; + case 'f': + fontfallbacks[0] = EARGF(usage()); + break; + case 'c': + colors[0] = EARGF(usage()); + break; + case 'b': + colors[1] = EARGF(usage()); + break; default: usage(); } ARGEND |