Browse Source

* 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.
tags/v0.99.beta14
Sam Hocevar sam 17 years ago
parent
commit
7373e6b18c
3 changed files with 92 additions and 90 deletions
  1. +2
    -2
      cucul/cucul.h
  2. +89
    -87
      cucul/transform.c
  3. +1
    -1
      test/text.c

+ 2
- 2
cucul/cucul.h View File

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


+ 89
- 87
cucul/transform.c View File

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


+ 1
- 1
test/text.c View File

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


Loading…
Cancel
Save