Changeset 1786
- Timestamp:
- Jun 28, 2007, 5:56:59 PM (15 years ago)
- Location:
- libcaca/trunk/cucul
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
libcaca/trunk/cucul/cucul.h
r1773 r1786 122 122 int cucul_flop(cucul_canvas_t *); 123 123 int cucul_rotate(cucul_canvas_t *); 124 int cucul_left(cucul_canvas_t *); 125 int cucul_right(cucul_canvas_t *); 124 126 /* @} */ 125 127 -
libcaca/trunk/cucul/transform.c
r1782 r1786 21 21 22 22 #if !defined(__KERNEL__) 23 # include <stdlib.h> 23 24 #endif 24 25 … … 29 30 static uint32_t flopchar(uint32_t ch); 30 31 static uint32_t rotatechar(uint32_t ch); 32 static uint32_t leftchar(uint32_t ch); 33 static uint32_t rightchar(uint32_t ch); 31 34 32 35 /** \brief Invert a canvas' colours. … … 211 214 } 212 215 } 216 217 return 0; 218 } 219 220 /** \brief Rotate a canvas, 90 degrees counterclockwise. 221 * 222 * Apply a 90-degree transformation to a canvas, choosing characters 223 * that look like the rotated version wherever possible. Some characters 224 * will stay unchanged by the process, some others will be replaced by 225 * close equivalents. Fullwidth characters will be lost. The operation is 226 * not guaranteed to be reversible at all. 227 * 228 * Note that the width and height of the canvas are swapped. 229 * 230 * If an error occurs, -1 is returned and \b errno is set accordingly: 231 * - \c EBUSY The canvas is in use by a display driver and cannot be rotated. 232 * - \c ENOMEM Not enough memory to allocate the new canvas size. If this 233 * happens, the previous canvas handle is still valid. 234 * 235 * \param cv The canvas to rotate left. 236 * \return 0 in case of success, -1 if an error occurred. 237 */ 238 int cucul_left(cucul_canvas_t *cv) 239 { 240 uint32_t *newchars, *newattrs; 241 unsigned int x, y; 242 243 if(cv->refcount) 244 { 245 seterrno(EBUSY); 246 return -1; 247 } 248 249 /* Save the current frame shortcuts */ 250 _cucul_save_frame_info(cv); 251 252 newchars = malloc(cv->width * cv->height * sizeof(uint32_t)); 253 if(!newchars) 254 return -1; 255 256 newattrs = malloc(cv->width * cv->height * sizeof(uint32_t)); 257 if(!newattrs) 258 { 259 free(newchars); 260 return -1; 261 } 262 263 for(y = 0; y < cv->height; y++) 264 { 265 for(x = 0; x < cv->width; x++) 266 { 267 uint32_t ch, attr; 268 269 ch = cv->chars[cv->width * y + x]; 270 attr = cv->attrs[cv->width * y + x]; 271 272 /* FIXME: do something about fullwidth characters */ 273 ch = leftchar(ch); 274 275 newchars[cv->height * (cv->width - 1 - x) + y] = ch; 276 newattrs[cv->height * (cv->width - 1 - x) + y] = attr; 277 } 278 } 279 280 free(cv->chars); 281 free(cv->attrs); 282 283 /* Swap X and Y information */ 284 x = cv->frames[cv->frame].x; 285 y = cv->frames[cv->frame].y; 286 cv->frames[cv->frame].x = y; 287 cv->frames[cv->frame].y = cv->width - 1 - x; 288 289 x = cv->frames[cv->frame].handlex; 290 y = cv->frames[cv->frame].handley; 291 cv->frames[cv->frame].handlex = y; 292 cv->frames[cv->frame].handley = cv->width - 1 - x; 293 294 cv->frames[cv->frame].width = cv->height; 295 cv->frames[cv->frame].height = cv->width; 296 297 cv->frames[cv->frame].chars = newchars; 298 cv->frames[cv->frame].attrs = newattrs; 299 300 /* Reset the current frame shortcuts */ 301 _cucul_load_frame_info(cv); 302 303 return 0; 304 } 305 306 /** \brief Rotate a canvas, 90 degrees clockwise. 307 * 308 * Apply a 270-degree transformation to a canvas, choosing characters 309 * that look like the rotated version wherever possible. Some characters 310 * will stay unchanged by the process, some others will be replaced by 311 * close equivalents. Fullwidth characters will be lost. The operation is 312 * not guaranteed to be reversible at all. 313 * 314 * Note that the width and height of the canvas are swapped. 315 * 316 * If an error occurs, -1 is returned and \b errno is set accordingly: 317 * - \c EBUSY The canvas is in use by a display driver and cannot be rotated. 318 * - \c ENOMEM Not enough memory to allocate the new canvas size. If this 319 * happens, the previous canvas handle is still valid. 320 * 321 * \param cv The canvas to rotate right. 322 * \return 0 in case of success, -1 if an error occurred. 323 */ 324 int cucul_right(cucul_canvas_t *cv) 325 { 326 uint32_t *newchars, *newattrs; 327 unsigned int x, y; 328 329 if(cv->refcount) 330 { 331 seterrno(EBUSY); 332 return -1; 333 } 334 335 /* Save the current frame shortcuts */ 336 _cucul_save_frame_info(cv); 337 338 newchars = malloc(cv->width * cv->height * sizeof(uint32_t)); 339 if(!newchars) 340 { 341 seterrno(ENOMEM); 342 return -1; 343 } 344 345 newattrs = malloc(cv->width * cv->height * sizeof(uint32_t)); 346 if(!newattrs) 347 { 348 free(newchars); 349 seterrno(ENOMEM); 350 return -1; 351 } 352 353 for(y = 0; y < cv->height; y++) 354 { 355 for(x = 0; x < cv->width; x++) 356 { 357 uint32_t ch, attr; 358 359 ch = cv->chars[cv->width * y + x]; 360 attr = cv->attrs[cv->width * y + x]; 361 362 /* FIXME: do something about fullwidth characters */ 363 ch = rightchar(ch); 364 365 newchars[cv->height * x + cv->height - 1 - y] = ch; 366 newattrs[cv->height * x + cv->height - 1 - y] = attr; 367 } 368 } 369 370 free(cv->chars); 371 free(cv->attrs); 372 373 /* Swap X and Y information */ 374 x = cv->frames[cv->frame].x; 375 y = cv->frames[cv->frame].y; 376 cv->frames[cv->frame].x = cv->height - 1 - y; 377 cv->frames[cv->frame].y = x; 378 379 x = cv->frames[cv->frame].handlex; 380 y = cv->frames[cv->frame].handley; 381 cv->frames[cv->frame].handlex = cv->height - 1 - y; 382 cv->frames[cv->frame].handley = x; 383 384 cv->frames[cv->frame].width = cv->height; 385 cv->frames[cv->frame].height = cv->width; 386 387 cv->frames[cv->frame].chars = newchars; 388 cv->frames[cv->frame].attrs = newattrs; 389 390 /* Reset the current frame shortcuts */ 391 _cucul_load_frame_info(cv); 213 392 214 393 return 0; … … 497 676 } 498 677 678 static uint32_t const leftright2[] = 679 { 680 /* ASCII */ 681 '/', '\\', 682 '|', '-', 683 '|', '_', /* This is all right because there was already a '|' before */ 684 /* ASCII-Unicode */ 685 '|', 0x203e, /* | ‾ */ 686 /* Misc Unicode */ 687 0x2571, 0x2572, /* ╱ ╲ */ 688 /* Box drawing */ 689 0x2500, 0x2502, /* ─ │ */ 690 0x2501, 0x2503, /* ━ ┃ */ 691 0x2550, 0x2551, /* ═ ║ */ 692 0, 0 693 }; 694 695 static uint32_t const leftright4[] = 696 { 697 /* ASCII */ 698 '<', 'v', '>', '^', 699 ',', '.', '\'', '`', 700 /* Misc Unicode */ 701 0x256d, 0x2570, 0x256f, 0x256e, /* ╭ ╰ ╯ ╮ */ 702 /* CP437 */ 703 0x258c, 0x2584, 0x2590, 0x2580, /* ▌ ▄ ▐ ▀ */ 704 0x2596, 0x2597, 0x259d, 0x2598, /* ▖ ▗ ▝ ▘ */ 705 0x2599, 0x259f, 0x259c, 0x259b, /* ▙ ▟ ▜ ▛ */ 706 /* Box drawing */ 707 0x250c, 0x2514, 0x2518, 0x2510, /* ┌ └ ┘ ┐ */ 708 0x250f, 0x2517, 0x251b, 0x2513, /* ┏ ┗ ┛ ┓ */ 709 0x251c, 0x2534, 0x2524, 0x252c, /* ├ ┴ ┤ ┬ */ 710 0x2523, 0x253b, 0x252b, 0x2533, /* ┣ ┻ ┫ ┳ */ 711 0x2552, 0x2559, 0x255b, 0x2556, /* ╒ ╙ ╛ ╖ */ 712 0x2553, 0x2558, 0x255c, 0x2555, /* ╓ ╘ ╜ ╕ */ 713 0x2554, 0x255a, 0x255d, 0x2557, /* ╔ ╚ ╝ ╗ */ 714 0x255e, 0x2568, 0x2561, 0x2565, /* ╞ ╨ ╡ ╥ */ 715 0x255f, 0x2567, 0x2562, 0x2564, /* ╟ ╧ ╢ ╤ */ 716 0x2560, 0x2569, 0x2563, 0x2566, /* ╠ ╩ ╣ ╦ */ 717 0x2574, 0x2577, 0x2576, 0x2575, /* ╴ ╷ ╶ ╵ */ 718 0x2578, 0x257b, 0x257a, 0x2579, /* ╸ ╻ ╺ ╹ */ 719 0, 0, 0, 0 720 }; 721 722 static uint32_t leftchar(uint32_t ch) 723 { 724 int i; 725 726 for(i = 0; leftright2[i]; i++) 727 if(ch == leftright2[i]) 728 return leftright2[(i & ~1) | ((i + 1) & 1)]; 729 730 for(i = 0; leftright4[i]; i++) 731 if(ch == leftright4[i]) 732 return leftright4[(i & ~3) | ((i + 1) & 3)]; 733 734 return ch; 735 } 736 737 static uint32_t rightchar(uint32_t ch) 738 { 739 int i; 740 741 for(i = 0; leftright2[i]; i++) 742 if(ch == leftright2[i]) 743 return leftright2[(i & ~1) | ((i - 1) & 1)]; 744 745 for(i = 0; leftright4[i]; i++) 746 if(ch == leftright4[i]) 747 return leftright4[(i & ~3) | ((i - 1) & 3)]; 748 749 return ch; 750 } 751
Note: See TracChangeset
for help on using the changeset viewer.