Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*!
  2.   \file Draw_Round.c
  3.   \author Mario Palomo <mpalomo@ihman.com>
  4.   \author Jose M. de la Huerga Fernández
  5.   \author Pepe González Mora
  6.   \date 05-2002
  7.  
  8.   This library is free software; you can redistribute it and/or
  9.   modify it under the terms of the GNU Library General Public
  10.   License as published by the Free Software Foundation; either
  11.   version 2 of the License, or (at your option) any later version.
  12.  
  13.   This library is distributed in the hope that it will be useful,
  14.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.   Library General Public License for more details.
  17.  
  18.   You should have received a copy of the GNU Library General Public
  19.   License along with this library; if not, write to the Free Foundation,
  20.   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21. */
  22.  
  23. /*Circle arcs*/
  24. #define SDL_DRAW_PUTPIXEL_CIRCLE_BPP(A, B, C) \
  25.   *(##A##(##B##(Uint8*)super->pixels + (Ycenter-x)*super->pitch +        \
  26.                                 (Xcenter - corner)*SDL_DRAW_BPP)) = C##; \
  27.   *(##A##(##B##(Uint8*)super->pixels + (Ycenter-corner)*super->pitch +   \
  28.                                      (Xcenter - x)*SDL_DRAW_BPP)) = C##; \
  29.   *(##A##(##B##(Uint8*)super->pixels + (Ycenter-corner)*super->pitch +   \
  30.                                     (X2center + x)*SDL_DRAW_BPP)) = C##; \
  31.   *(##A##(##B##(Uint8*)super->pixels + (Ycenter-x)*super->pitch +        \
  32.                                (X2center + corner)*SDL_DRAW_BPP)) = C##; \
  33.   *(##A##(##B##(Uint8*)super->pixels + (Y2center+corner)*super->pitch +  \
  34.                                     (X2center + x)*SDL_DRAW_BPP)) = C##; \
  35.   *(##A##(##B##(Uint8*)super->pixels + (Y2center+x)*super->pitch +       \
  36.                                (X2center + corner)*SDL_DRAW_BPP)) = C##; \
  37.   *(##A##(##B##(Uint8*)super->pixels + (Y2center+corner)*super->pitch +  \
  38.                                      (Xcenter - x)*SDL_DRAW_BPP)) = C##; \
  39.   *(##A##(##B##(Uint8*)super->pixels + (Y2center+x)*super->pitch +       \
  40.                                 (Xcenter - corner)*SDL_DRAW_BPP)) = C##;
  41.  
  42.  
  43. #if SDL_DRAW_BPP == 1
  44. #define SDL_DRAW_PUTPIXEL_CIRCLE SDL_DRAW_PUTPIXEL_CIRCLE_BPP(0+,0+,color)
  45.  
  46. #elif SDL_DRAW_BPP == 2
  47. #define SDL_DRAW_PUTPIXEL_CIRCLE SDL_DRAW_PUTPIXEL_CIRCLE_BPP((Uint16*),0+,color)
  48.  
  49. #elif SDL_DRAW_BPP == 3
  50. #define SDL_DRAW_PUTPIXEL_CIRCLE \
  51.   SDL_DRAW_PUTPIXEL_CIRCLE_BPP(0+,1+,colorbyte1)   \
  52.   if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {         \
  53.     SDL_DRAW_PUTPIXEL_CIRCLE_BPP(0+,0+,colorbyte2)   \
  54.     SDL_DRAW_PUTPIXEL_CIRCLE_BPP(0+,2+,colorbyte0) \
  55.   }else{                                         \
  56.     SDL_DRAW_PUTPIXEL_CIRCLE_BPP(0+,0+,colorbyte0)   \
  57.     SDL_DRAW_PUTPIXEL_CIRCLE_BPP(0+,2+,colorbyte2) \
  58.   }
  59.  
  60. #elif SDL_DRAW_BPP == 4
  61. #define SDL_DRAW_PUTPIXEL_CIRCLE SDL_DRAW_PUTPIXEL_CIRCLE_BPP((Uint32*),0+,color)
  62.  
  63. #endif /*SDL_DRAW_BPP*/
  64.  
  65.  
  66. /*Rectangles*/
  67. #if SDL_DRAW_BPP == 1
  68. #define SDL_DRAW_PUTPIXEL \
  69.   memset(p0, color, dx);               \
  70.   memset(p1, color, dx);               \
  71.                                        \
  72.   if (h<3)  return;                    \
  73.   p0 = (Uint8*)super->pixels + Ycenter*super->pitch + x0; \
  74.   p1 = (Uint8*)super->pixels + Ycenter*super->pitch + x0+w-1; \
  75.   i=dy;                                \
  76.   switch( i % 4 ) {                    \
  77.     do{                                \
  78.       case 0:                          \
  79.         *p0 = color; p0+=super->pitch; \
  80.         *p1 = color; p1+=super->pitch; \
  81.       case 3:                          \
  82.         *p0 = color; p0+=super->pitch; \
  83.         *p1 = color; p1+=super->pitch; \
  84.       case 2:                          \
  85.         *p0 = color; p0+=super->pitch; \
  86.         *p1 = color; p1+=super->pitch; \
  87.       case 1:                          \
  88.         *p0 = color; p0+=super->pitch; \
  89.         *p1 = color; p1+=super->pitch; \
  90.     }while( (i-=4) > 0 );              \
  91.   }
  92.  
  93. #elif SDL_DRAW_BPP == 2
  94. #define SDL_DRAW_PUTPIXEL \
  95.   i=dx;                                         \
  96.   switch( i % 4 ) {                             \
  97.     do{                                         \
  98.       case 0:                                   \
  99.         *(Uint16*)p0 = color; p0+=2;            \
  100.         *(Uint16*)p1 = color; p1+=2;            \
  101.       case 3:                                   \
  102.         *(Uint16*)p0 = color; p0+=2;            \
  103.         *(Uint16*)p1 = color; p1+=2;            \
  104.       case 2:                                   \
  105.         *(Uint16*)p0 = color; p0+=2;            \
  106.         *(Uint16*)p1 = color; p1+=2;            \
  107.       case 1:                                   \
  108.         *(Uint16*)p0 = color; p0+=2;            \
  109.         *(Uint16*)p1 = color; p1+=2;            \
  110.     }while( (i-=4) > 0 );                       \
  111.   }                                             \
  112.   if (h<3)  return;                             \
  113.   p0 = (Uint8*)super->pixels + Ycenter*super->pitch + x0*2;       \
  114.   p1 = (Uint8*)super->pixels + Ycenter*super->pitch + (x0+w-1)*2; \
  115.   i=dy;                                         \
  116.   switch( i % 4 ) {                             \
  117.     do{                                         \
  118.       case 0:                                   \
  119.         *(Uint16*)p0 = color; p0+=super->pitch; \
  120.         *(Uint16*)p1 = color; p1+=super->pitch; \
  121.       case 3:                                   \
  122.         *(Uint16*)p0 = color; p0+=super->pitch; \
  123.         *(Uint16*)p1 = color; p1+=super->pitch; \
  124.       case 2:                                   \
  125.         *(Uint16*)p0 = color; p0+=super->pitch; \
  126.         *(Uint16*)p1 = color; p1+=super->pitch; \
  127.       case 1:                                   \
  128.         *(Uint16*)p0 = color; p0+=super->pitch; \
  129.         *(Uint16*)p1 = color; p1+=super->pitch; \
  130.     }while( (i-=4) > 0 );                       \
  131.   }
  132.  
  133.  
  134. #elif SDL_DRAW_BPP == 3
  135. #define SDL_DRAW_PUTPIXEL_BPP_3_AUX \
  136.     if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \
  137.       p0[0] = colorbyte2;                  \
  138.       p0[1] = colorbyte1;                  \
  139.       p0[2] = colorbyte0;                  \
  140.       p1[0] = colorbyte2;                  \
  141.       p1[1] = colorbyte1;                  \
  142.       p1[2] = colorbyte0;                  \
  143.     } else {                               \
  144.       p0[0] = colorbyte0;                  \
  145.       p0[1] = colorbyte1;                  \
  146.       p0[2] = colorbyte2;                  \
  147.       p1[0] = colorbyte0;                  \
  148.       p1[1] = colorbyte1;                  \
  149.       p1[2] = colorbyte2;                  \
  150.     }
  151.  
  152. #define SDL_DRAW_PUTPIXEL \
  153.   i=dx;                                     \
  154.   switch( i % 4 ) {                         \
  155.     do{                                     \
  156.       case 0:                               \
  157.         SDL_DRAW_PUTPIXEL_BPP_3_AUX         \
  158.         p0+=3; p1+=3;                       \
  159.       case 3:                               \
  160.         SDL_DRAW_PUTPIXEL_BPP_3_AUX         \
  161.         p0+=3; p1+=3;                       \
  162.       case 2:                               \
  163.         SDL_DRAW_PUTPIXEL_BPP_3_AUX         \
  164.         p0+=3; p1+=3;                       \
  165.       case 1:                               \
  166.         SDL_DRAW_PUTPIXEL_BPP_3_AUX         \
  167.         p0+=3; p1+=3;                       \
  168.     }while( (i-=4) > 0 );                   \
  169.   }                                         \
  170.   if (h<3)  return;                         \
  171.   p0 = (Uint8*)super->pixels + Ycenter*super->pitch + x0*3;       \
  172.   p1 = (Uint8*)super->pixels + Ycenter*super->pitch + (x0+w-1)*3; \
  173.   i=dy;                                     \
  174.   switch( i % 4 ) {                         \
  175.     do{                                     \
  176.       case 0:                               \
  177.         SDL_DRAW_PUTPIXEL_BPP_3_AUX         \
  178.         p0+=super->pitch; p1+=super->pitch; \
  179.       case 3:                               \
  180.         SDL_DRAW_PUTPIXEL_BPP_3_AUX         \
  181.         p0+=super->pitch; p1+=super->pitch; \
  182.       case 2:                               \
  183.         SDL_DRAW_PUTPIXEL_BPP_3_AUX         \
  184.         p0+=super->pitch; p1+=super->pitch; \
  185.       case 1:                               \
  186.         SDL_DRAW_PUTPIXEL_BPP_3_AUX         \
  187.         p0+=super->pitch; p1+=super->pitch; \
  188.     }while( (i-=4) > 0 );                   \
  189.   }
  190.  
  191.  
  192. #elif SDL_DRAW_BPP == 4
  193. #ifdef __linux__
  194. #define SDL_DRAW_WMEMSET_START \
  195. if (sizeof(wchar_t) == sizeof(Uint32)) {        \
  196.   wmemset((wchar_t*)p0, color, dx);             \
  197.   wmemset((wchar_t*)p1, color, dx);             \
  198. } else {
  199. #define SDL_DRAW_WMEMSET_END }
  200. #else
  201. #define SDL_DRAW_WMEMSET_START
  202. #define SDL_DRAW_WMEMSET_END
  203. #endif
  204.  
  205. #define SDL_DRAW_PUTPIXEL \
  206. SDL_DRAW_WMEMSET_START                          \
  207.   i=dx;                                         \
  208.   switch( i % 4 ) {                             \
  209.     do{                                         \
  210.       case 0:                                   \
  211.         *(Uint32*)p0 = color; p0+=4;            \
  212.         *(Uint32*)p1 = color; p1+=4;            \
  213.       case 3:                                   \
  214.         *(Uint32*)p0 = color; p0+=4;            \
  215.         *(Uint32*)p1 = color; p1+=4;            \
  216.       case 2:                                   \
  217.         *(Uint32*)p0 = color; p0+=4;            \
  218.         *(Uint32*)p1 = color; p1+=4;            \
  219.       case 1:                                   \
  220.         *(Uint32*)p0 = color; p0+=4;            \
  221.         *(Uint32*)p1 = color; p1+=4;            \
  222.     }while( (i-=4) > 0 );                       \
  223.   }                                             \
  224. SDL_DRAW_WMEMSET_END                            \
  225.   if (h<3)  return;                             \
  226.   p0 = (Uint8*)super->pixels + Ycenter*super->pitch + x0*4;       \
  227.   p1 = (Uint8*)super->pixels + Ycenter*super->pitch + (x0+w-1)*4; \
  228.   i=dy;                                         \
  229.   switch( i % 4 ) {                             \
  230.     do{                                         \
  231.       case 0:                                   \
  232.         *(Uint32*)p0 = color; p0+=super->pitch; \
  233.         *(Uint32*)p1 = color; p1+=super->pitch; \
  234.       case 3:                                   \
  235.         *(Uint32*)p0 = color; p0+=super->pitch; \
  236.         *(Uint32*)p1 = color; p1+=super->pitch; \
  237.       case 2:                                   \
  238.         *(Uint32*)p0 = color; p0+=super->pitch; \
  239.         *(Uint32*)p1 = color; p1+=super->pitch; \
  240.       case 1:                                   \
  241.         *(Uint32*)p0 = color; p0+=super->pitch; \
  242.         *(Uint32*)p1 = color; p1+=super->pitch; \
  243.     }while( (i-=4) > 0 );                       \
  244.   }
  245.  
  246. #endif /*SDL_DRAW_BPP*/
  247.  
  248.  
  249.  
  250. void SDL_DRAWFUNCTION(SDL_Surface *super,
  251.                       Sint16 x0,Sint16 y0, Uint16 w,Uint16 h,
  252.                       Uint16 corner, Uint32 color)
  253. {
  254. #if SDL_DRAW_BPP == 3
  255.   Uint8 colorbyte0 = (Uint8) (color & 0xff);
  256.   Uint8 colorbyte1 = (Uint8) ((color >> 8)  & 0xff);
  257.   Uint8 colorbyte2 = (Uint8) ((color >> 16) & 0xff);
  258. #endif
  259.  
  260.   register Uint8 *p0;
  261.   register Uint8 *p1;
  262.   register Sint16 i;
  263.   Sint16 dx, dy;
  264.  
  265.   Sint16 Xcenter, Ycenter, X2center, Y2center;
  266.  
  267.   Sint16 x = 0;
  268.   Sint16 rightInc = 6;
  269.   Sint16 d, diagonalInc;
  270.  
  271.   if (w==0 || h==0)  return;
  272.  
  273.   /*TODO: We can do better :-)*/
  274.   if (corner!=0) {
  275.     d = w<h ? w : h;
  276.     --corner;
  277.     if (corner!=0 && corner+2 >= d ) {
  278.       if (corner+2 == d)  --corner;
  279.       else corner = 0;
  280.     }
  281.   }
  282.  
  283.   d = 3 - (corner<<1);
  284.   diagonalInc = 10 - (corner<<2);
  285.  
  286.   /*Rectangles*/
  287.   dx = w - (corner<<1);
  288.   Xcenter = x0+corner;
  289.   dy = h - (corner<<1);
  290.   Ycenter = y0+corner;
  291.  
  292.   /*Centers*/
  293.   X2center=Xcenter+dx-1;
  294.   Y2center=Ycenter+dy-1;
  295.  
  296.   p0 = (Uint8*)super->pixels +    y0    * super->pitch + Xcenter*SDL_DRAW_BPP;
  297.   p1 = (Uint8*)super->pixels + (y0+h-1) * super->pitch + Xcenter*SDL_DRAW_BPP;
  298.  
  299.   SDL_DRAW_PUTPIXEL
  300.  
  301.   while (x < corner) {
  302.  
  303.     SDL_DRAW_PUTPIXEL_CIRCLE
  304.  
  305.     if (d >= 0) {
  306.       d += diagonalInc;
  307.       diagonalInc += 8;
  308.       --corner;
  309.     } else {
  310.       d += rightInc;
  311.       diagonalInc += 4;
  312.     }
  313.     rightInc += 4;
  314.     ++x;
  315.   }/*while*/
  316.  
  317. }/*Draw_Round*/
  318.  
  319.  
  320. #undef SDL_DRAW_PUTPIXEL
  321. #undef SDL_DRAW_PUTPIXEL_CIRCLE
  322. #undef SDL_DRAW_PUTPIXEL_CIRCLE_BPP
  323.  
  324. #undef SDL_DRAW_WMEMSET_START
  325. #undef SDL_DRAW_WMEMSET_END
  326.  
  327.