diff --git a/cucul/canvas.c b/cucul/canvas.c index 9f9ff71..7905331 100644 --- a/cucul/canvas.c +++ b/cucul/canvas.c @@ -274,9 +274,6 @@ int cucul_clear_canvas(cucul_canvas_t *cv) * - \c EINVAL A mask was specified but the mask size and source canvas * size do not match. * - * FIXME: this function may corrupt the canvas if fullwidth characters - * appear at odd places. - * * \param dst The destination canvas. * \param x X coordinate. * \param y Y coordinate. @@ -308,28 +305,42 @@ int cucul_blit(cucul_canvas_t *dst, int x, int y, for(j = startj; j < endj; j++) { + unsigned int dstix = (j + y) * dst->width + starti + x; + unsigned int srcix = j * src->width + starti; + int stride = endi - starti; + + /* FIXME: we are ignoring the mask here */ + if((starti + x) && dst->chars[dstix] == CUCUL_MAGIC_FULLWIDTH) + dst->chars[dstix - 1] = ' '; + + if((unsigned int)(endi + x) < dst->width + && dst->chars[dstix + stride] == CUCUL_MAGIC_FULLWIDTH) + dst->chars[dstix + stride] = ' '; + if(mask) { - for(i = starti; i < endi; i++) + for(i = 0; i < stride; i++) { - if(mask->chars[j * src->width + i] == (uint32_t)' ') + if(mask->chars[srcix + i] == (uint32_t)' ') continue; - dst->chars[(j + y) * dst->width + (i + x)] - = src->chars[j * src->width + i]; - dst->attr[(j + y) * dst->width + (i + x)] - = src->attr[j * src->width + i]; + dst->chars[dstix + i] = src->chars[srcix + i]; + dst->attr[dstix + i] = src->attr[srcix + i]; } } else { - memcpy(dst->chars + (j + y) * dst->width + starti + x, - src->chars + j * src->width + starti, - (endi - starti) * 4); - memcpy(dst->attr + (j + y) * dst->width + starti + x, - src->attr + j * src->width + starti, - (endi - starti) * 4); + memcpy(dst->chars + dstix, src->chars + srcix, (stride) * 4); + memcpy(dst->attr + dstix, src->attr + srcix, (stride) * 4); } + + /* Fix split fullwidth chars */ + if(src->chars[srcix] == CUCUL_MAGIC_FULLWIDTH) + dst->chars[dstix] = ' '; + + if((unsigned int)endi < src->width + && src->chars[endi] == CUCUL_MAGIC_FULLWIDTH) + dst->chars[dstix + stride - 1] = ' '; } return 0; diff --git a/cucul/transform.c b/cucul/transform.c index 30223cc..c275c1f 100644 --- a/cucul/transform.c +++ b/cucul/transform.c @@ -92,6 +92,7 @@ int cucul_flip(cucul_canvas_t *cv) if(cleft == cright) *cleft = flipchar(*cleft); + /* Fix fullwidth characters. Could it be done in one loop? */ cleft = cv->chars + y * cv->width; cright = cleft + cv->width - 1; for( ; cleft < cright; cleft++) @@ -187,6 +188,7 @@ int cucul_rotate(cucul_canvas_t *cv) if(cbegin == cend) *cbegin = rotatechar(*cbegin); + /* Fix fullwidth characters. Could it be done in one loop? */ for(y = 0; y < cv->height; y++) { cbegin = cv->chars + y * cv->width; diff --git a/test/fullwidth.c b/test/fullwidth.c index 98829c0..5692025 100644 --- a/test/fullwidth.c +++ b/test/fullwidth.c @@ -28,7 +28,7 @@ int main(int argc, char *argv[]) { - cucul_canvas_t *cv, *caca; + cucul_canvas_t *cv, *caca, *line; caca_display_t *dp; unsigned int i; @@ -37,7 +37,9 @@ int main(int argc, char *argv[]) dp = caca_create_display(cv); caca = cucul_create_canvas(6, 10); + line = cucul_create_canvas(2, 1); + /* Line of x's */ for(i = 0; i < 10; i++) { cucul_set_color(caca, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE); @@ -48,6 +50,7 @@ int main(int argc, char *argv[]) cucul_blit(cv, 1, 1, caca, NULL); + /* Line of ホ's */ for(i = 0; i < 10; i++) { cucul_set_color(caca, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE); @@ -58,11 +61,26 @@ int main(int argc, char *argv[]) cucul_blit(cv, 15, 1, caca, NULL); + /* Line of canvas */ + cucul_set_color(line, CUCUL_COLOR_WHITE, CUCUL_COLOR_MAGENTA); + cucul_putstr(line, 0, 0, "ほ"); + for(i = 0; i < 10; i++) + { + cucul_set_color(caca, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE); + cucul_putstr(caca, 0, i, CACA); + cucul_blit(caca, i - 2, i, line, NULL); + } + + cucul_blit(cv, 29, 1, caca, NULL); + caca_refresh_display(dp); caca_get_event(dp, CACA_EVENT_KEY_PRESS, NULL, -1); caca_free_display(dp); + + cucul_free_canvas(line); + cucul_free_canvas(caca); cucul_free_canvas(cv); return 0;