Subversion Repositories Kolibri OS

Rev

Rev 7977 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #define MAX_CELL_SIZE 256
  2.  
  3. //////////////////////////////////////////////////////////////////////////////////////
  4. //                                                                                  //
  5. //                                  DRAW PIXEL                                      //
  6. //                                                                                  //
  7. //////////////////////////////////////////////////////////////////////////////////////
  8.  
  9. //The 'draw[]' is the array which holds the states should we draw a pixel or not.
  10. //Is need to decrease redraw when using some tools like line, rectangle and selection.
  11.  
  12. struct _pixel_state
  13. {
  14.         unsigned image_rows, image_columns;
  15.         bool draw[MAX_CELL_SIZE*MAX_CELL_SIZE];
  16.         void set_drawable_state();
  17.         bool is_drawable();
  18.         void reset_and_set_all_drawable();
  19.         void set_sizes();
  20. } pixel_state;
  21.  
  22. void _pixel_state::set_drawable_state(int _r, _c, _state)
  23. {
  24.         draw[image_columns*_r + _c] = _state;
  25. }
  26.  
  27. bool _pixel_state::is_drawable(int _r, _c)
  28. {
  29.         return draw[image_columns*_r + _c];
  30. }
  31.  
  32. void _pixel_state::reset_and_set_all_drawable()
  33. {
  34.         int i;
  35.         for (i = 0; i < image_columns*image_rows; i++) draw[i]=true;
  36. }
  37.  
  38. void _pixel_state::set_sizes(dword _r, _c)
  39. {
  40.         image_rows = _r;
  41.         image_columns = _c;
  42. }
  43.  
  44. //////////////////////////////////////////////////////////////////////////////////////
  45. //                                                                                  //
  46. //                                      IMAGE                                       //
  47. //                                                                                  //
  48. //////////////////////////////////////////////////////////////////////////////////////
  49.  
  50. //This stucture determines basic actions that can be done with image (icon).
  51.  
  52. struct _image
  53. {
  54.         unsigned rows, columns;
  55.         dword mas[MAX_CELL_SIZE*MAX_CELL_SIZE];
  56.         dword mas_copy[MAX_CELL_SIZE*MAX_CELL_SIZE];
  57.         dword img;
  58.         _pixel_state pixel_state;
  59.         void create();
  60.         void set_pixel();
  61.         void draw_line();
  62.         void fill();
  63.         void set_image();
  64.         dword get_pixel();
  65.         dword get_image();
  66.         dword get_image_with_replaced_color();
  67.         void move();
  68. };
  69.  
  70. void _image::create(int _rows, _columns)
  71. {
  72.         int i;
  73.         rows = _rows;
  74.         columns = _columns;
  75.         for (i = 0; i < columns*rows; i++) mas[i]=0xBFCAD2;
  76.         pixel_state.set_sizes(rows, columns);
  77. }
  78.  
  79. void _image::set_pixel(int _r, _c, _color)
  80. {
  81.         mas[columns*_r + _c] = _color;
  82. }
  83.  
  84. void _image::draw_line(int x1, int y1, int x2, int y2, dword color) {
  85.         int dx, dy, signX, signY, error, error2;
  86.  
  87.         dx = x2 - x1;
  88.  
  89.         if (dx < 0)
  90.                 dx = -dx;
  91.    
  92.         dy = y2 - y1;
  93.  
  94.         if (dy < 0)
  95.                 dy = -dy;
  96.    
  97.         if (x1 < x2)
  98.                 signX = 1;
  99.         else
  100.                 signX = -1;
  101.    
  102.         if (y1 < y2)
  103.                 signY = 1;
  104.         else
  105.                 signY = -1;
  106.    
  107.         error = dx - dy;
  108.  
  109.         set_pixel(y2, x2, color);
  110.  
  111.         while((x1 != x2) || (y1 != y2))
  112.         {
  113.                 set_pixel(y1, x1, color);
  114.                
  115.                 error2 = error * 2;
  116.  
  117.                 if(error2 > calc(-dy))
  118.                 {
  119.                         error -= dy;
  120.                         x1 += signX;
  121.                 }
  122.  
  123.                 if(error2 < dx)
  124.                 {
  125.                         error += dx;
  126.                         y1 += signY;
  127.                 }
  128.         }
  129. }
  130.  
  131. void _image::fill(int _r, _c, _color)
  132. {
  133.         #define MARKED 6
  134.         int r, c, i, restart;
  135.  
  136.         dword old_color = get_pixel(_r, _c);
  137.         set_pixel(_r, _c, MARKED);
  138.  
  139.         do {
  140.                 restart=false; 
  141.                 for (r = 0; r < rows; r++)
  142.                         for (c = 0; c < columns; c++)
  143.                         {
  144.                                 IF (get_pixel(r,c) != old_color) continue;
  145.                                 IF (get_pixel(r,c) == MARKED) continue;
  146.                                
  147.                                 IF (c>0)               && (get_pixel(r,c-1) == MARKED) set_pixel(r,c,MARKED);
  148.                                 IF (r>0)               && (get_pixel(r-1,c) == MARKED) set_pixel(r,c,MARKED);
  149.                                 IF (c<columns-1) && (get_pixel(r,c+1) == MARKED) set_pixel(r,c,MARKED);
  150.                                 IF (r<rows-1)    && (get_pixel(r+1,c) == MARKED) set_pixel(r,c,MARKED);
  151.                                
  152.                                 IF (get_pixel(r,c)==MARKED) restart=true;
  153.                         }
  154.         }while(restart);
  155.  
  156.         for (i=0; i<columns*rows; i++)
  157.                         IF (mas[i]==MARKED) mas[i] = _color;
  158. }
  159.  
  160. dword _image::get_pixel(int _r, _c)
  161. {
  162.         return mas[columns*_r + _c];
  163. }
  164.  
  165. void _image::set_image(dword _inbuf)
  166. {
  167.         dword i;
  168.         for (i = 0; i < columns*rows; i++;)
  169.         {
  170.                 // mas[i] = ESDWORD[i*4+_inbuf] & 0x00FFFFFF; //for x32 bit color
  171.                 if (i == MAX_CELL_SIZE*MAX_CELL_SIZE-1) {
  172.                         mas[i] = 0;
  173.                 } else {
  174.                         mas[i] = ESDWORD[i*3+_inbuf] & 0xFFFFFF;
  175.                 }
  176.         }
  177. }
  178.  
  179. dword _image::get_image()
  180. {
  181.         int r=0, c=0;
  182.         dword i;
  183.  
  184.         free(img);
  185.         i = img = malloc(rows*columns*3);
  186.  
  187.         for (r = 0; r < rows; r++)
  188.                 for (c = 0; c < columns; c++)
  189.                 {
  190.                         rgb.DwordToRgb(get_pixel(r,c));
  191.                         ESBYTE[i] = rgb.b;
  192.                         ESBYTE[i+1] = rgb.g;
  193.                         ESBYTE[i+2] = rgb.r;
  194.                         i += 3;
  195.                 }
  196.         return img;
  197. }
  198.  
  199. dword _image::get_image_with_replaced_color(dword _col_from, _col_to)
  200. {
  201.         int r=0, c=0;
  202.         dword i;
  203.         dword cur_pixel;
  204.  
  205.         free(img);
  206.         i = img = malloc(rows*columns*3);
  207.  
  208.         for (r = 0; r < rows; r++)
  209.                 for (c = 0; c < columns; c++)
  210.                 {
  211.                         cur_pixel = get_pixel(r,c);
  212.                         if (cur_pixel == _col_from) cur_pixel = _col_to;
  213.                         rgb.DwordToRgb(cur_pixel);
  214.                         ESBYTE[i] = rgb.b;
  215.                         ESBYTE[i+1] = rgb.g;
  216.                         ESBYTE[i+2] = rgb.r;
  217.                         i += 3;
  218.                 }
  219.         return img;
  220. }
  221.  
  222. enum {
  223.         MOVE_LEFT,
  224.         MOVE_RIGHT,
  225.         MOVE_UP,
  226.         MOVE_DOWN,
  227.         FLIP_VER,
  228.         FLIP_HOR,
  229.         ROTATE_LEFT,
  230.         ROTATE_RIGHT
  231. };
  232. void _image::move(int _direction)
  233. {
  234.         int r, c;
  235.         dword first_element_data;
  236.  
  237.         switch(_direction)
  238.         {
  239.                 case MOVE_LEFT:
  240.                                 for (r = 0; r < rows; r++)
  241.                                 {
  242.                                         first_element_data = get_pixel(r, 0);
  243.                                         for (c = 0; c < columns-1; c++) set_pixel(r, c, get_pixel(r, c+1));
  244.                                         set_pixel(r, columns-1, first_element_data);
  245.                                 }
  246.                                 break;
  247.                 case MOVE_RIGHT:
  248.                                 for (r = 0; r < rows; r++)
  249.                                 {
  250.                                         first_element_data = get_pixel(r, columns-1);
  251.                                         for (c = columns-1; c > 0; c--) set_pixel(r, c, get_pixel(r, c-1));
  252.                                         set_pixel(r, 0, first_element_data);
  253.                                 }      
  254.                                 break; 
  255.                 case MOVE_UP:
  256.                                 for (c = 0; c < columns; c++)
  257.                                 {
  258.                                         first_element_data = get_pixel(0, c);
  259.                                         for (r = 0; r < rows-1; r++) set_pixel(r, c, get_pixel(r+1, c));
  260.                                         set_pixel(rows-1, c, first_element_data);
  261.                                 }      
  262.                                 break;
  263.                 case MOVE_DOWN:
  264.                                 for (c = 0; c < columns; c++)
  265.                                 {
  266.                                         first_element_data = get_pixel(rows-1, c);
  267.                                         for (r = rows-1; r > 0; r--) set_pixel(r, c, get_pixel(r-1, c));
  268.                                         set_pixel(0, c, first_element_data);
  269.                                 }
  270.                                 break;
  271.                 case FLIP_HOR:
  272.                                 for (r = 0; r < rows; r++)
  273.                                         for (c = 0; c < columns/2; c++) {
  274.                                                 first_element_data = get_pixel(r, c);
  275.                                                 set_pixel(r, c, get_pixel(r, columns-c-1));
  276.                                                 set_pixel(r, columns-c-1, first_element_data);
  277.                                         }
  278.                                 break;
  279.                 case FLIP_VER:
  280.                                 for (c = 0; c < columns; c++)
  281.                                         for (r = 0; r < rows/2; r++) {
  282.                                                 first_element_data = get_pixel(r, c);
  283.                                                 set_pixel(r, c, get_pixel(rows-r-1, c));
  284.                                                 set_pixel(rows-r-1, c, first_element_data);
  285.                                         }
  286.                                 break;
  287.                 case ROTATE_LEFT:
  288.                                 //slow but the code is simple
  289.                                 //need to rewrite in case of big images support
  290.                                 move(ROTATE_RIGHT);
  291.                                 move(ROTATE_RIGHT);
  292.                                 move(ROTATE_RIGHT);
  293.                                 break; 
  294.                 case ROTATE_RIGHT:
  295.                                 if (columns!=rows) {
  296.                                         notify("Sorry, rotate is implemented for square canvaces only!");
  297.                                         break;
  298.                                 }
  299.  
  300.                                 for (r=0; r<MAX_CELL_SIZE*MAX_CELL_SIZE; r++)  {
  301.                                         mas_copy[r] = mas[r];
  302.                                 }
  303.  
  304.                                 for (c = 0; c < columns; c++)
  305.                                         for (r = 0; r < rows; r++) {
  306.                                                 set_pixel(c, rows-r-1, mas_copy[columns*r + c]);
  307.                                         }
  308.  
  309.                                 columns >< rows;
  310.                                 break;
  311.         }
  312. }
  313.  
  314. /*
  315. 1234
  316. 5678
  317. 90AB
  318.  
  319. 951
  320. 0
  321. A
  322. B
  323.  
  324. */
  325.  
  326.  
  327.  
  328.