From 7373e6b18c04b333716ac5b16582be7fedb71d54 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Tue, 17 Jul 2007 20:46:18 +0000 Subject: [PATCH] * Renamed cucul_rotate_*_wide to cucul_rotate_* and cucul_rotate_* to cucul_stretch_* to avoid long function names. And the pairwise rotations look so nice now that they should be the real rotation chars. --- cucul/cucul.h | 4 +- cucul/transform.c | 176 +++++++++++++++++++++++----------------------- test/text.c | 2 +- 3 files changed, 92 insertions(+), 90 deletions(-) diff --git a/cucul/cucul.h b/cucul/cucul.h index 8fb6354..636f2f1 100644 --- a/cucul/cucul.h +++ b/cucul/cucul.h @@ -122,9 +122,9 @@ int cucul_flip(cucul_canvas_t *); int cucul_flop(cucul_canvas_t *); int cucul_rotate_180(cucul_canvas_t *); int cucul_rotate_left(cucul_canvas_t *); -int cucul_rotate_left_wide(cucul_canvas_t *); int cucul_rotate_right(cucul_canvas_t *); -int cucul_rotate_right_wide(cucul_canvas_t *); +int cucul_stretch_left(cucul_canvas_t *); +int cucul_stretch_right(cucul_canvas_t *); /* @} */ /** \defgroup attributes libcucul attribute conversions diff --git a/cucul/transform.c b/cucul/transform.c index c469112..fcd33b4 100644 --- a/cucul/transform.c +++ b/cucul/transform.c @@ -222,15 +222,19 @@ int cucul_rotate_180(cucul_canvas_t *cv) /** \brief Rotate a canvas, 90 degrees counterclockwise. * * Apply a 90-degree transformation to a canvas, choosing characters - * that look like the rotated version wherever possible. Some characters - * will stay unchanged by the process, some others will be replaced by - * close equivalents. Fullwidth characters will be lost. The operation is + * that look like the rotated version wherever possible. Characters cells + * are rotated two-by-two. Some characters will stay unchanged by the + * process, some others will be replaced by close equivalents. Fullwidth + * characters at odd horizontal coordinates will be lost. The operation is * not guaranteed to be reversible at all. * - * Note that the width and height of the canvas are swapped. + * Note that the width of the canvas is divided by two and becomes the + * new height. Height is multiplied by two and becomes the new width. It + * is illegal to pass a canvas with an odd width to this function. * * If an error occurs, -1 is returned and \b errno is set accordingly: * - \c EBUSY The canvas is in use by a display driver and cannot be rotated. + * - \c EINVAL The canvas' width is odd. * - \c ENOMEM Not enough memory to allocate the new canvas size. If this * happens, the previous canvas handle is still valid. * @@ -240,7 +244,7 @@ int cucul_rotate_180(cucul_canvas_t *cv) int cucul_rotate_left(cucul_canvas_t *cv) { uint32_t *newchars, *newattrs; - unsigned int x, y; + unsigned int x, y, subwidth, subheight; if(cv->refcount) { @@ -248,6 +252,12 @@ int cucul_rotate_left(cucul_canvas_t *cv) return -1; } + if(cv->width & 1) + { + seterrno(EINVAL); + return -1; + } + /* Save the current frame shortcuts */ _cucul_save_frame_info(cv); @@ -262,20 +272,26 @@ int cucul_rotate_left(cucul_canvas_t *cv) return -1; } - for(y = 0; y < cv->height; y++) + subwidth = cv->width / 2; + subheight = cv->height; + + for(y = 0; y < subheight; y++) { - for(x = 0; x < cv->width; x++) + for(x = 0; x < subwidth; x++) { - uint32_t ch, attr; + uint32_t pair[2], attr1, attr2; - ch = cv->chars[cv->width * y + x]; - attr = cv->attrs[cv->width * y + x]; + pair[0] = cv->chars[(subwidth * y + x) * 2]; + attr1 = cv->attrs[(subwidth * y + x) * 2]; + pair[1] = cv->chars[(subwidth * y + x) * 2 + 1]; + attr2 = cv->attrs[(subwidth * y + x) * 2 + 1]; - /* FIXME: do something about fullwidth characters */ - ch = leftchar(ch); + leftpair(pair); - newchars[cv->height * (cv->width - 1 - x) + y] = ch; - newattrs[cv->height * (cv->width - 1 - x) + y] = attr; + newchars[(subheight * (subwidth - 1 - x) + y) * 2] = pair[0]; + newattrs[(subheight * (subwidth - 1 - x) + y) * 2] = attr1; + newchars[(subheight * (subwidth - 1 - x) + y) * 2 + 1] = pair[1]; + newattrs[(subheight * (subwidth - 1 - x) + y) * 2 + 1] = attr2; } } @@ -285,16 +301,16 @@ int cucul_rotate_left(cucul_canvas_t *cv) /* Swap X and Y information */ x = cv->frames[cv->frame].x; y = cv->frames[cv->frame].y; - cv->frames[cv->frame].x = y; - cv->frames[cv->frame].y = cv->width - 1 - x; + cv->frames[cv->frame].x = y * 2; + cv->frames[cv->frame].y = (cv->width - 1 - x) / 2; x = cv->frames[cv->frame].handlex; y = cv->frames[cv->frame].handley; - cv->frames[cv->frame].handlex = y; - cv->frames[cv->frame].handley = cv->width - 1 - x; + cv->frames[cv->frame].handlex = y * 2; + cv->frames[cv->frame].handley = (cv->width - 1 - x) / 2; - cv->frames[cv->frame].width = cv->height; - cv->frames[cv->frame].height = cv->width; + cv->frames[cv->frame].width = cv->height * 2; + cv->frames[cv->frame].height = cv->width / 2; cv->frames[cv->frame].chars = newchars; cv->frames[cv->frame].attrs = newattrs; @@ -305,7 +321,7 @@ int cucul_rotate_left(cucul_canvas_t *cv) return 0; } -/** \brief Rotate a canvas, 90 degrees counterclockwise (widechar version). +/** \brief Rotate a canvas, 90 degrees counterclockwise. * * Apply a 90-degree transformation to a canvas, choosing characters * that look like the rotated version wherever possible. Characters cells @@ -324,10 +340,10 @@ int cucul_rotate_left(cucul_canvas_t *cv) * - \c ENOMEM Not enough memory to allocate the new canvas size. If this * happens, the previous canvas handle is still valid. * - * \param cv The canvas to rotate left. + * \param cv The canvas to rotate right. * \return 0 in case of success, -1 if an error occurred. */ -int cucul_rotate_left_wide(cucul_canvas_t *cv) +int cucul_rotate_right(cucul_canvas_t *cv) { uint32_t *newchars, *newattrs; unsigned int x, y, subwidth, subheight; @@ -372,12 +388,12 @@ int cucul_rotate_left_wide(cucul_canvas_t *cv) pair[1] = cv->chars[(subwidth * y + x) * 2 + 1]; attr2 = cv->attrs[(subwidth * y + x) * 2 + 1]; - leftpair(pair); + rightpair(pair); - newchars[(subheight * (subwidth - 1 - x) + y) * 2] = pair[0]; - newattrs[(subheight * (subwidth - 1 - x) + y) * 2] = attr1; - newchars[(subheight * (subwidth - 1 - x) + y) * 2 + 1] = pair[1]; - newattrs[(subheight * (subwidth - 1 - x) + y) * 2 + 1] = attr2; + newchars[(subheight * x + subheight - 1 - y) * 2] = pair[0]; + newattrs[(subheight * x + subheight - 1 - y) * 2] = attr1; + newchars[(subheight * x + subheight - 1 - y) * 2 + 1] = pair[1]; + newattrs[(subheight * x + subheight - 1 - y) * 2 + 1] = attr2; } } @@ -387,13 +403,13 @@ int cucul_rotate_left_wide(cucul_canvas_t *cv) /* Swap X and Y information */ x = cv->frames[cv->frame].x; y = cv->frames[cv->frame].y; - cv->frames[cv->frame].x = y * 2; - cv->frames[cv->frame].y = (cv->width - 1 - x) / 2; + cv->frames[cv->frame].x = (cv->height - 1 - y) * 2; + cv->frames[cv->frame].y = x / 2; x = cv->frames[cv->frame].handlex; y = cv->frames[cv->frame].handley; - cv->frames[cv->frame].handlex = y * 2; - cv->frames[cv->frame].handley = (cv->width - 1 - x) / 2; + cv->frames[cv->frame].handlex = (cv->height - 1 - y) * 2; + cv->frames[cv->frame].handley = x / 2; cv->frames[cv->frame].width = cv->height * 2; cv->frames[cv->frame].height = cv->width / 2; @@ -407,25 +423,26 @@ int cucul_rotate_left_wide(cucul_canvas_t *cv) return 0; } -/** \brief Rotate a canvas, 90 degrees clockwise. +/** \brief Rotate and stretch a canvas, 90 degrees counterclockwise. * - * Apply a 270-degree transformation to a canvas, choosing characters + * Apply a 90-degree transformation to a canvas, choosing characters * that look like the rotated version wherever possible. Some characters * will stay unchanged by the process, some others will be replaced by * close equivalents. Fullwidth characters will be lost. The operation is * not guaranteed to be reversible at all. * - * Note that the width and height of the canvas are swapped. + * Note that the width and height of the canvas are swapped, causing its + * aspect ratio to look stretched. * * If an error occurs, -1 is returned and \b errno is set accordingly: * - \c EBUSY The canvas is in use by a display driver and cannot be rotated. * - \c ENOMEM Not enough memory to allocate the new canvas size. If this * happens, the previous canvas handle is still valid. * - * \param cv The canvas to rotate right. + * \param cv The canvas to rotate left. * \return 0 in case of success, -1 if an error occurred. */ -int cucul_rotate_right(cucul_canvas_t *cv) +int cucul_stretch_left(cucul_canvas_t *cv) { uint32_t *newchars, *newattrs; unsigned int x, y; @@ -441,16 +458,12 @@ int cucul_rotate_right(cucul_canvas_t *cv) newchars = malloc(cv->width * cv->height * sizeof(uint32_t)); if(!newchars) - { - seterrno(ENOMEM); return -1; - } newattrs = malloc(cv->width * cv->height * sizeof(uint32_t)); if(!newattrs) { free(newchars); - seterrno(ENOMEM); return -1; } @@ -464,10 +477,10 @@ int cucul_rotate_right(cucul_canvas_t *cv) attr = cv->attrs[cv->width * y + x]; /* FIXME: do something about fullwidth characters */ - ch = rightchar(ch); + ch = leftchar(ch); - newchars[cv->height * x + cv->height - 1 - y] = ch; - newattrs[cv->height * x + cv->height - 1 - y] = attr; + newchars[cv->height * (cv->width - 1 - x) + y] = ch; + newattrs[cv->height * (cv->width - 1 - x) + y] = attr; } } @@ -477,13 +490,13 @@ int cucul_rotate_right(cucul_canvas_t *cv) /* Swap X and Y information */ x = cv->frames[cv->frame].x; y = cv->frames[cv->frame].y; - cv->frames[cv->frame].x = cv->height - 1 - y; - cv->frames[cv->frame].y = x; + cv->frames[cv->frame].x = y; + cv->frames[cv->frame].y = cv->width - 1 - x; x = cv->frames[cv->frame].handlex; y = cv->frames[cv->frame].handley; - cv->frames[cv->frame].handlex = cv->height - 1 - y; - cv->frames[cv->frame].handley = x; + cv->frames[cv->frame].handlex = y; + cv->frames[cv->frame].handley = cv->width - 1 - x; cv->frames[cv->frame].width = cv->height; cv->frames[cv->frame].height = cv->width; @@ -497,32 +510,29 @@ int cucul_rotate_right(cucul_canvas_t *cv) return 0; } -/** \brief Rotate a canvas, 90 degrees counterclockwise (widechar version). +/** \brief Rotate and stretch a canvas, 90 degrees clockwise. * - * Apply a 90-degree transformation to a canvas, choosing characters - * that look like the rotated version wherever possible. Characters cells - * are rotated two-by-two. Some characters will stay unchanged by the - * process, some others will be replaced by close equivalents. Fullwidth - * characters at odd horizontal coordinates will be lost. The operation is + * Apply a 270-degree transformation to a canvas, choosing characters + * that look like the rotated version wherever possible. Some characters + * will stay unchanged by the process, some others will be replaced by + * close equivalents. Fullwidth characters will be lost. The operation is * not guaranteed to be reversible at all. * - * Note that the width of the canvas is divided by two and becomes the - * new height. Height is multiplied by two and becomes the new width. It - * is illegal to pass a canvas with an odd width to this function. + * Note that the width and height of the canvas are swapped, causing its + * aspect ratio to look stretched. * * If an error occurs, -1 is returned and \b errno is set accordingly: * - \c EBUSY The canvas is in use by a display driver and cannot be rotated. - * - \c EINVAL The canvas' width is odd. * - \c ENOMEM Not enough memory to allocate the new canvas size. If this * happens, the previous canvas handle is still valid. * * \param cv The canvas to rotate right. * \return 0 in case of success, -1 if an error occurred. */ -int cucul_rotate_right_wide(cucul_canvas_t *cv) +int cucul_stretch_right(cucul_canvas_t *cv) { uint32_t *newchars, *newattrs; - unsigned int x, y, subwidth, subheight; + unsigned int x, y; if(cv->refcount) { @@ -530,46 +540,38 @@ int cucul_rotate_right_wide(cucul_canvas_t *cv) return -1; } - if(cv->width & 1) - { - seterrno(EINVAL); - return -1; - } - /* Save the current frame shortcuts */ _cucul_save_frame_info(cv); newchars = malloc(cv->width * cv->height * sizeof(uint32_t)); if(!newchars) + { + seterrno(ENOMEM); return -1; + } newattrs = malloc(cv->width * cv->height * sizeof(uint32_t)); if(!newattrs) { free(newchars); + seterrno(ENOMEM); return -1; } - subwidth = cv->width / 2; - subheight = cv->height; - - for(y = 0; y < subheight; y++) + for(y = 0; y < cv->height; y++) { - for(x = 0; x < subwidth; x++) + for(x = 0; x < cv->width; x++) { - uint32_t pair[2], attr1, attr2; + uint32_t ch, attr; - pair[0] = cv->chars[(subwidth * y + x) * 2]; - attr1 = cv->attrs[(subwidth * y + x) * 2]; - pair[1] = cv->chars[(subwidth * y + x) * 2 + 1]; - attr2 = cv->attrs[(subwidth * y + x) * 2 + 1]; + ch = cv->chars[cv->width * y + x]; + attr = cv->attrs[cv->width * y + x]; - rightpair(pair); + /* FIXME: do something about fullwidth characters */ + ch = rightchar(ch); - newchars[(subheight * x + subheight - 1 - y) * 2] = pair[0]; - newattrs[(subheight * x + subheight - 1 - y) * 2] = attr1; - newchars[(subheight * x + subheight - 1 - y) * 2 + 1] = pair[1]; - newattrs[(subheight * x + subheight - 1 - y) * 2 + 1] = attr2; + newchars[cv->height * x + cv->height - 1 - y] = ch; + newattrs[cv->height * x + cv->height - 1 - y] = attr; } } @@ -579,16 +581,16 @@ int cucul_rotate_right_wide(cucul_canvas_t *cv) /* Swap X and Y information */ x = cv->frames[cv->frame].x; y = cv->frames[cv->frame].y; - cv->frames[cv->frame].x = (cv->height - 1 - y) * 2; - cv->frames[cv->frame].y = x / 2; + cv->frames[cv->frame].x = cv->height - 1 - y; + cv->frames[cv->frame].y = x; x = cv->frames[cv->frame].handlex; y = cv->frames[cv->frame].handley; - cv->frames[cv->frame].handlex = (cv->height - 1 - y) * 2; - cv->frames[cv->frame].handley = x / 2; + cv->frames[cv->frame].handlex = cv->height - 1 - y; + cv->frames[cv->frame].handley = x; - cv->frames[cv->frame].width = cv->height * 2; - cv->frames[cv->frame].height = cv->width / 2; + cv->frames[cv->frame].width = cv->height; + cv->frames[cv->frame].height = cv->width; cv->frames[cv->frame].chars = newchars; cv->frames[cv->frame].attrs = newattrs; diff --git a/test/text.c b/test/text.c index f84d036..5df2ea3 100644 --- a/test/text.c +++ b/test/text.c @@ -82,7 +82,7 @@ int main(int argc, char *argv[]) fwrite(buffer, len, 1, stdout); free(buffer); - cucul_rotate_left_wide(cv); + cucul_rotate_left(cv); buffer = cucul_export_memory(cv, "utf8", &len); fwrite(buffer, len, 1, stdout); free(buffer);