home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bc45 / owlsrc.pak / BRUSH.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-24  |  5.8 KB  |  217 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // (C) Copyright 1992, 1994 by Borland International, All Rights Reserved
  4. //
  5. //   Implementation for GDI Brush object
  6. //----------------------------------------------------------------------------
  7. #include <owl/owlpch.h>
  8. #include <owl/gdiobjec.h>
  9.  
  10. DIAG_DECLARE_GROUP(OwlGDI);        // General GDI diagnostic group
  11.  
  12. //
  13. // internal brush cache to keep most common brushes around cached by color
  14. //
  15.  
  16. class TBrushCache {
  17.   public:
  18.     struct TEntry {
  19.       HBRUSH  Handle;
  20.       TColor  Color;
  21.       
  22.       TEntry(HANDLE handle) {Handle = (HBRUSH)handle;}
  23.     };
  24.     
  25.     TBrushCache(TEntry* entries, int numEntries);
  26.     HBRUSH Lookup(TColor color);
  27.  
  28.   private:
  29.     TEntry*  Entries;
  30.     int      NumEntries;
  31. };
  32.  
  33. TBrushCache::TBrushCache(TEntry* entries, int numEntries)
  34. {
  35.   Entries = entries;
  36.   NumEntries = numEntries;
  37.  
  38.   for (int i = 0; i < NumEntries; i++) {
  39.     LOGBRUSH logBrush;
  40.     if (GetObject(Entries[i].Handle, sizeof(LOGBRUSH), &logBrush))
  41.       Entries[i].Color = logBrush.lbColor;
  42.   }
  43. }
  44.  
  45. HBRUSH
  46. TBrushCache::Lookup(TColor color)
  47. {
  48.   for (int i = 0; i < NumEntries; i++)
  49.     if (color == Entries[i].Color)
  50.       return Entries[i].Handle;
  51.   return 0;
  52. }
  53.  
  54. //
  55. // Static instance of a brush cache table & the cache itself
  56. //
  57. static TBrushCache::TEntry BrushCacheEntries[] = {
  58.   {::GetStockObject(BLACK_BRUSH)},
  59.   {::GetStockObject(DKGRAY_BRUSH)},
  60.   {::GetStockObject(GRAY_BRUSH)},
  61.   {::GetStockObject(LTGRAY_BRUSH)},
  62.   {::GetStockObject(WHITE_BRUSH)}
  63. };
  64. static TBrushCache BrushCache(BrushCacheEntries, COUNTOF(BrushCacheEntries));
  65.  
  66. //
  67. // Constructors
  68. //
  69. TBrush::TBrush(HBRUSH handle, TAutoDelete autoDelete)
  70.   : TGdiObject(handle, autoDelete)
  71. {
  72. #if !defined(NO_GDI_ORPHAN_CONTROL)
  73.   if (ShouldDelete)
  74.     OBJ_REF_ADD(Handle, Brush);
  75. #endif
  76. }
  77.  
  78. TBrush::TBrush(TColor color)
  79. {
  80.   if ((Handle = BrushCache.Lookup(color)) != 0) {
  81.     ShouldDelete = false;
  82.     return;
  83.   }
  84.   Handle = ::CreateSolidBrush(color);
  85.   WARNX(OwlGDI, !Handle, 0, "Cannot create solid TBrush " << hex << color);
  86.   CheckValid();
  87.   OBJ_REF_ADD(Handle, Brush);
  88. }
  89.  
  90. TBrush::TBrush(TColor color, int style)
  91. {
  92.   Handle = ::CreateHatchBrush(style, color);
  93.   WARNX(OwlGDI, !Handle, 0, "Cannot create hatch TBrush " << hex << color <<
  94.         " " << style);
  95.   CheckValid();
  96.   OBJ_REF_ADD(Handle, Brush);
  97. }
  98.  
  99. TBrush::TBrush(const TBitmap& pattern)
  100. {
  101.   Handle = ::CreatePatternBrush(pattern);
  102.   WARNX(OwlGDI, !Handle, 0, "Cannot create pattern TBrush from bitmap " <<
  103.         hex << (uint)(HBITMAP)pattern);
  104.   CheckValid();
  105.   OBJ_REF_ADD(Handle, Brush);
  106. }
  107.  
  108. TBrush::TBrush(const TDib& pattern)
  109. {
  110.   // This calls is 16/32 independent (& avoids Win32s not-implemented problem)
  111.   //
  112. #if (0)  // Extra step using hbitmap required for some Win32 versions
  113.   TBitmap bm(pattern);
  114.   LOGBRUSH lb = { BS_PATTERN, 0, (int)HANDLE(bm) };
  115.   Handle = ::CreateBrushIndirect(&lb);
  116. #else
  117.   Handle = ::CreateDIBPatternBrush(pattern, pattern.Usage());
  118. #endif
  119.  
  120.   WARNX(OwlGDI, !Handle, 0, "Cannot create pattern TBrush from DIB " <<
  121.         hex << (uint)(HANDLE)pattern);
  122.   CheckValid();
  123.   OBJ_REF_ADD(Handle, Brush);
  124. }
  125.  
  126. TBrush::TBrush(const LOGBRUSH far* logBrush)
  127. {
  128.   PRECONDITION(logBrush);
  129.   Handle = ::CreateBrushIndirect((LPLOGBRUSH)logBrush);  // API cast
  130.   WARNX(OwlGDI, !Handle, 0, "Cannot create TBrush from logBrush @" <<
  131.         hex << uint32(LPVOID(logBrush)));
  132.   CheckValid();
  133.   OBJ_REF_ADD(Handle, Brush);
  134. }
  135.  
  136. TBrush::TBrush(const TBrush& src)
  137. {
  138.   LOGBRUSH logBrush;
  139.   src.GetObject(logBrush);
  140.   Handle = ::CreateBrushIndirect(&logBrush);
  141.   WARNX(OwlGDI, !Handle, 0, "Cannot create TBrush from TBrush @" <<
  142.         hex << uint32(LPVOID(&src)));
  143.   CheckValid();
  144.   OBJ_REF_ADD(Handle, Brush);
  145. }
  146.  
  147. //----------------------------------------------------------------------------
  148.  
  149. THatch8x8Brush::THatch8x8Brush(const uint8 hatch[], TColor fgColor, TColor bgColor)
  150.   : TBrush(Create(hatch, fgColor, bgColor), AutoDelete)
  151. {
  152. }
  153.  
  154. //
  155. // reconstructs the brush with a new pattern or colors
  156. //
  157. void
  158. THatch8x8Brush::Reconstruct(const uint8 hatch[], TColor fgColor, TColor bgColor)
  159. {
  160.   if (Handle) {
  161. #if !defined(NO_GDI_ORPHAN_CONTROL)
  162.     OBJ_REF_DEC(Handle, true);
  163. #else
  164.     if (!::DeleteObject(Handle))
  165.       THROW( TXGdi(IDS_GDIDELETEFAIL, Handle) );
  166. #endif
  167.   }
  168.   Handle = Create(hatch, fgColor, bgColor);
  169.   OBJ_REF_ADD(Handle, Brush);
  170. }
  171.  
  172. //
  173. // private static create member to create or re-create the handle
  174. //
  175. HBRUSH
  176. THatch8x8Brush::Create(const uint8 hatch[], TColor fgColor, TColor bgColor)
  177. {
  178.   TDib dib(8, 8, 2, DIB_RGB_COLORS);
  179.   unsigned char HUGE* bits = (unsigned char HUGE*)dib.GetBits();
  180.   memset(bits, 0, 8*sizeof(uint32));
  181.   for (int i = 0; i < 8; i++)
  182.     bits[(7-i) * sizeof(uint32)] = hatch[i];  // Dib is upside down
  183.   dib.SetColor(0, bgColor);
  184.   dib.SetColor(1, fgColor);
  185.  
  186. #if (0)  // Extra step using hbitmap required for some Win32 versions
  187.   TBitmap bm(dib);
  188.   LOGBRUSH lb = { BS_PATTERN, DIB_RGB_COLORS, (int)HANDLE(bm) };
  189.   HBRUSH handle = ::CreateBrushIndirect(&lb);
  190. #else
  191.   HBRUSH handle = ::CreateDIBPatternBrush(dib, DIB_RGB_COLORS);
  192. #endif
  193.  
  194.   CheckValid(handle);
  195.   return handle;
  196. }
  197.  
  198. //
  199. // Predefined 8x8 hatch patterns
  200. //
  201. const uint8 THatch8x8Brush::Hatch22F1[8] = {
  202.   0x99, 0x33, 0x66, 0xCC, 0x99, 0x33, 0x66, 0xCC
  203. };
  204. const uint8 THatch8x8Brush::Hatch13F1[8] = {
  205.   0x88, 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44
  206. };
  207. const uint8 THatch8x8Brush::Hatch11F1[8] = {
  208.   0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55
  209. };
  210. const uint8 THatch8x8Brush::Hatch22B1[8] = {
  211.   0xCC, 0x66, 0x33, 0x99, 0xCC, 0x66, 0x33, 0x99
  212. };
  213. const uint8 THatch8x8Brush::Hatch13B1[8] = {
  214.   0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11, 0x88
  215. };
  216.  
  217.