|
|
@@ -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; |
|
|
|