home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / include / areafill.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-11  |  7.2 KB  |  243 lines

  1. //-----------------------------------------------------------------------------------//
  2. //              Windows Graphics Programming: Win32 GDI and DirectDraw               //
  3. //                             ISBN  0-13-086985-6                                   //
  4. //                                                                                   //
  5. //  Written            by  Yuan, Feng                             www.fengyuan.com   //
  6. //  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
  7. //  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
  8. //                                                                                   //
  9. //  FileName   : areafill.cpp                                                         //
  10. //  Description: Gradient fill, pattern fill                                         //
  11. //  Version    : 1.00.000, May 31, 2000                                              //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define STRICT
  15. #define WIN32_LEAN_AND_MEAN
  16.  
  17. #include <windows.h>
  18. #include <math.h>
  19.  
  20. #include "color.h"
  21. #include "areafill.h"
  22.  
  23. BOOL GradientRectangle(HDC hDC, int x0, int y0, int x1, int y1, COLORREF c0, COLORREF c1, int angle)
  24. {
  25.     TRIVERTEX vert[4] = { 
  26.         { x0, y0,  R16(c0), G16(c0), B16(c0), 0 },                //  0:c0         3:(c0+c1)/2
  27.         { x1, y1,  R16(c1), G16(c1), B16(c1), 0 },                //
  28.         { x0, y1,  R16(c0, c1), G16(c0, c1), B16(c0, c1), 0 },    //
  29.         { x1, y0,  R16(c0, c1), G16(c0, c1), B16(c0, c1), 0 }    //  2:(c0+c1)/2  1: c1
  30.     };
  31.  
  32.     ULONG Index[] = { 0, 1, 2, 0, 1, 3};
  33.  
  34.     switch ( angle % 180 )
  35.     {
  36.         case   0: 
  37.             return GradientFill(hDC, vert, 2, Index, 1, GRADIENT_FILL_RECT_H);
  38.  
  39.         case  45: 
  40.             return GradientFill(hDC, vert, 4, Index, 2, GRADIENT_FILL_TRIANGLE);
  41.  
  42.         case  90: 
  43.             return GradientFill(hDC, vert, 2, Index, 1, GRADIENT_FILL_RECT_V);
  44.  
  45.         case 135: 
  46.             vert[0].x = x1;
  47.             vert[3].x = x0;
  48.             vert[1].x = x0;
  49.             vert[2].x = x1;
  50.             return GradientFill(hDC, vert, 4, Index, 2, GRADIENT_FILL_TRIANGLE);
  51.     }
  52.  
  53.     return FALSE;
  54. }
  55.  
  56. BOOL SymGradientRectangle(HDC hDC, int x0, int y0, int x1, int y1, COLORREF c0, COLORREF c1, int angle)
  57. {
  58.     TRIVERTEX vert[] = { 
  59.         { x0,        y0,  R16(c0), G16(c0), B16(c0), 0 },
  60.         { x1, (y0+y1)/2,  R16(c1), G16(c1), B16(c1), 0 },
  61.         { x0, (y0+y1)/2,  R16(c1), G16(c1), B16(c1), 0 },
  62.         { x1,        y1,  R16(c0), G16(c0), B16(c0), 0 },
  63.         
  64.         { x1,         y0,  R16(c1), G16(c1), B16(c1), 0 },
  65.         { x0,         y1,  R16(c1), G16(c1), B16(c1), 0 },
  66.  
  67.         { (x0+x1)/2, y1,  R16(c1), G16(c1), B16(c1), 0 },
  68.         { (x0+x1)/2, y0,  R16(c1), G16(c1), B16(c1), 0 }
  69.     };
  70.  
  71.     switch ( angle % 180 )
  72.     {
  73.         case 0:
  74.         {
  75.             ULONG Index[] = { 0, 6, 7, 3 };
  76.             return GradientFill(hDC, vert, 8, Index, 2, GRADIENT_FILL_RECT_H);
  77.         }
  78.  
  79.         case 45:
  80.         {
  81.             ULONG Index[] = { 0, 4, 5, 4, 5, 3 };
  82.             return GradientFill(hDC, vert, 6, Index, 2, GRADIENT_FILL_TRIANGLE);
  83.         }
  84.  
  85.         case 90:
  86.         {
  87.             ULONG Index[] = { 0, 1, 2, 3 };
  88.             return GradientFill(hDC, vert, 4, Index, 2, GRADIENT_FILL_RECT_V);
  89.         }
  90.  
  91.         case 135:
  92.         {
  93.             TRIVERTEX vert[4] = { 
  94.                 { x0, y0,  R16(c1), G16(c1), B16(c1), 0 },
  95.                 { x1, y0,  R16(c0), G16(c0), B16(c0), 0 },
  96.                 { x0, y1,  R16(c0), G16(c0), B16(c0), 0 },
  97.                 { x1, y1,  R16(c1), G16(c1), B16(c1), 0 }
  98.             };
  99.  
  100.             ULONG Index[] = { 0, 1, 3, 0, 3, 2 };
  101.  
  102.             return GradientFill(hDC, vert, 4, Index, 2, GRADIENT_FILL_TRIANGLE);
  103.         }
  104.     }
  105.  
  106.     return FALSE;
  107. }
  108.  
  109. BOOL CornerGradientRectangle(HDC hDC, int x0, int y0, int x1, int y1, COLORREF c0, COLORREF c1, int corner)
  110. {
  111.     TRIVERTEX vert[] = { 
  112.         { x0,        y0,  R16(c1), G16(c1), B16(c1), 0 },
  113.         { x1,        y0,  R16(c1), G16(c1), B16(c1), 0 },
  114.         { x1,         y1,  R16(c1), G16(c1), B16(c1), 0 },
  115.         { x0,         y1,  R16(c1), G16(c1), B16(c1), 0 }
  116.     };
  117.  
  118.     vert[corner].Red   = R16(c0);
  119.     vert[corner].Green = G16(c0);
  120.     vert[corner].Blue  = B16(c0);
  121.  
  122.     ULONG Index[] = { corner, (corner+1)%4, (corner+2)%4, 
  123.                       corner, (corner+3)%4, (corner+2)%4 };
  124.     
  125.     return GradientFill(hDC, vert, 4, Index, 2, GRADIENT_FILL_TRIANGLE);
  126. }
  127.  
  128. BOOL CenterGradientRectangle(HDC hDC, int x0, int y0, int x1, int y1, COLORREF c0, COLORREF c1)
  129. {
  130.     TRIVERTEX vert[] = { 
  131.         { x0,        y0,        R16(c1), G16(c1), B16(c1), 0 },
  132.         { x1,        y0,        R16(c1), G16(c1), B16(c1), 0 },
  133.         { x1,         y1,        R16(c1), G16(c1), B16(c1), 0 },
  134.         { x0,         y1,        R16(c1), G16(c1), B16(c1), 0 },
  135.         { (x0+x1)/2, (y0+y1)/2, R16(c0), G16(c0), B16(c0), 0 }
  136.     };
  137.  
  138.     ULONG Index[] = { 0, 1, 4, 1, 2, 4, 2, 3, 4, 3, 0, 4 };
  139.     
  140.     return GradientFill(hDC, vert, 5, Index, 4, GRADIENT_FILL_TRIANGLE);
  141. }
  142.  
  143.  
  144. void HLSGradientRectangle(HDC hDC, int x0, int y0, int x1, int y1, COLORREF cref0, COLORREF cref1, int nPart)
  145. {
  146.     KColor c0(cref0); c0.ToHLS();
  147.     KColor c1(cref1); c1.ToHLS();
  148.  
  149.     for (int i=0; i<nPart; i++)
  150.     {
  151.         KColor c;
  152.  
  153.         c.hue        = ( c0.hue       * (nPart-1-i) + c1.hue       * i ) / (nPart-1);
  154.         c.lightness  = ( c0.lightness * (nPart-1-i) + c1.lightness * i ) / (nPart-1);
  155.         c.saturation = ( c0.saturation* (nPart-1-i) + c1.saturation* i ) / (nPart-1);
  156.         c.ToRGB();
  157.  
  158.         HBRUSH hBrush = CreateSolidBrush(c.GetColorRef());
  159.  
  160.         RECT rect = { x0+i*(x1-x0)/nPart,     y0, 
  161.                       x0+(i+1)*(x1-x0)/nPart, y1 }; 
  162.         FillRect(hDC, & rect, hBrush);
  163.         DeleteObject(hBrush);
  164.     }
  165. }
  166.  
  167.  
  168. BOOL RadialGradientFill(HDC hDC, int x0, int y0, int x1, int y1, int r, COLORREF c0, COLORREF c1, int nPart)
  169. {
  170.     const double PI2 = 3.1415927 * 2;
  171.  
  172.     TRIVERTEX * pVertex = new TRIVERTEX[nPart+1];
  173.     ULONG     * pMesh   = new ULONG[(nPart+1)*3];
  174.  
  175.     pVertex[0].x     = x1;
  176.     pVertex[0].y     = y1;
  177.     pVertex[0].Red   = R16(c0);
  178.     pVertex[0].Green = G16(c0);
  179.     pVertex[0].Blue  = G16(c0);
  180.     pVertex[0].Alpha = 0;
  181.  
  182.     for (int i=0; i<nPart; i++)
  183.     {
  184.         pVertex[i+1].x     = x0 + (int) (r * cos(PI2 * i / nPart));
  185.         pVertex[i+1].y     = y0 + (int) (r * sin(PI2 * i / nPart));
  186.         pVertex[i+1].Red   = R16(c1);
  187.         pVertex[i+1].Green = G16(c1);
  188.         pVertex[i+1].Blue  = B16(c1);
  189.         pVertex[i+1].Alpha = 0;
  190.  
  191.         pMesh[i*3+0] = 0;
  192.         pMesh[i*3+1] = i+1;
  193.         pMesh[i*3+2] = (i+1) % nPart+1;
  194.     }
  195.  
  196.     BOOL rslt = GradientFill(hDC, pVertex, nPart+1, pMesh, nPart, GRADIENT_FILL_TRIANGLE);
  197.  
  198.     delete [] pVertex;
  199.     delete [] pMesh;
  200.  
  201.     return rslt;
  202. }
  203.  
  204.  
  205. void BrickPatternFill(HDC hDC, int x0, int y0, int x1, int y1, int width, int height)
  206. {
  207.     width  = abs(width);
  208.     height = abs(height);
  209.  
  210.     if ( x0>x1 ) { int t = x0; x0 = x1; x1 = t; }
  211.     if ( y0>y1 ) { int t = y0; y0 = y1; y1 = t; }
  212.  
  213. //    Rectangle(hDC, x0, y0, x1, y1);
  214.  
  215.     for (int y=y0; y<y1; y += height )
  216.     for (int x=x0; x<x1; x += width  )
  217.     {
  218.         MoveToEx(hDC, x,       y, NULL); LineTo(hDC, x+width,   y+height);
  219.         MoveToEx(hDC, x+width, y, NULL); LineTo(hDC, x+width/2, y+height/2);
  220.     }
  221. }
  222.  
  223. void RoundRectButton(HDC hDC, int x0, int y0, int x1, int y1, int w, int d, COLORREF c1, COLORREF c0)
  224. {
  225.     for (int i=0; i<2; i++)
  226.     {
  227.         POINT P[3] = { x0+d*i, y0+d*i, x1-d*i, y1-d*i, x0+d*i+w, y0+d*i+w };
  228.  
  229.         LPtoDP(hDC, P, 3);
  230.  
  231.         HRGN hRgn = CreateRoundRectRgn(P[0].x, P[0].y, P[1].x, P[1].y, P[2].x-P[0].x, P[2].y-P[0].y);
  232.         SelectClipRgn(hDC, hRgn);
  233.         DeleteObject(hRgn);
  234.     
  235.         if ( i==0 )
  236.             GradientRectangle(hDC, x0, y0, x1, y1, c1, c0, 45);
  237.         else
  238.             GradientRectangle(hDC, x0+d, y0+d, x1-d, y1-d, c0, c1, 45);
  239.     }
  240.     
  241.     SelectClipRgn(hDC, NULL);
  242. }
  243.