home *** CD-ROM | disk | FTP | other *** search
- //----------------------------------------------------------------------------
- // ObjectWindows
- // (C) Copyright 1992, 1994 by Borland International, All Rights Reserved
- //
- // Implementation for GDI Brush object
- //----------------------------------------------------------------------------
- #include <owl/owlpch.h>
- #include <owl/gdiobjec.h>
-
- DIAG_DECLARE_GROUP(OwlGDI); // General GDI diagnostic group
-
- //
- // internal brush cache to keep most common brushes around cached by color
- //
-
- class TBrushCache {
- public:
- struct TEntry {
- HBRUSH Handle;
- TColor Color;
-
- TEntry(HANDLE handle) {Handle = (HBRUSH)handle;}
- };
-
- TBrushCache(TEntry* entries, int numEntries);
- HBRUSH Lookup(TColor color);
-
- private:
- TEntry* Entries;
- int NumEntries;
- };
-
- TBrushCache::TBrushCache(TEntry* entries, int numEntries)
- {
- Entries = entries;
- NumEntries = numEntries;
-
- for (int i = 0; i < NumEntries; i++) {
- LOGBRUSH logBrush;
- if (GetObject(Entries[i].Handle, sizeof(LOGBRUSH), &logBrush))
- Entries[i].Color = logBrush.lbColor;
- }
- }
-
- HBRUSH
- TBrushCache::Lookup(TColor color)
- {
- for (int i = 0; i < NumEntries; i++)
- if (color == Entries[i].Color)
- return Entries[i].Handle;
- return 0;
- }
-
- //
- // Static instance of a brush cache table & the cache itself
- //
- static TBrushCache::TEntry BrushCacheEntries[] = {
- {::GetStockObject(BLACK_BRUSH)},
- {::GetStockObject(DKGRAY_BRUSH)},
- {::GetStockObject(GRAY_BRUSH)},
- {::GetStockObject(LTGRAY_BRUSH)},
- {::GetStockObject(WHITE_BRUSH)}
- };
- static TBrushCache BrushCache(BrushCacheEntries, COUNTOF(BrushCacheEntries));
-
- //
- // Constructors
- //
- TBrush::TBrush(HBRUSH handle, TAutoDelete autoDelete)
- : TGdiObject(handle, autoDelete)
- {
- #if !defined(NO_GDI_ORPHAN_CONTROL)
- if (ShouldDelete)
- OBJ_REF_ADD(Handle, Brush);
- #endif
- }
-
- TBrush::TBrush(TColor color)
- {
- if ((Handle = BrushCache.Lookup(color)) != 0) {
- ShouldDelete = false;
- return;
- }
- Handle = ::CreateSolidBrush(color);
- WARNX(OwlGDI, !Handle, 0, "Cannot create solid TBrush " << hex << color);
- CheckValid();
- OBJ_REF_ADD(Handle, Brush);
- }
-
- TBrush::TBrush(TColor color, int style)
- {
- Handle = ::CreateHatchBrush(style, color);
- WARNX(OwlGDI, !Handle, 0, "Cannot create hatch TBrush " << hex << color <<
- " " << style);
- CheckValid();
- OBJ_REF_ADD(Handle, Brush);
- }
-
- TBrush::TBrush(const TBitmap& pattern)
- {
- Handle = ::CreatePatternBrush(pattern);
- WARNX(OwlGDI, !Handle, 0, "Cannot create pattern TBrush from bitmap " <<
- hex << (uint)(HBITMAP)pattern);
- CheckValid();
- OBJ_REF_ADD(Handle, Brush);
- }
-
- TBrush::TBrush(const TDib& pattern)
- {
- // This calls is 16/32 independent (& avoids Win32s not-implemented problem)
- //
- #if (0) // Extra step using hbitmap required for some Win32 versions
- TBitmap bm(pattern);
- LOGBRUSH lb = { BS_PATTERN, 0, (int)HANDLE(bm) };
- Handle = ::CreateBrushIndirect(&lb);
- #else
- Handle = ::CreateDIBPatternBrush(pattern, pattern.Usage());
- #endif
-
- WARNX(OwlGDI, !Handle, 0, "Cannot create pattern TBrush from DIB " <<
- hex << (uint)(HANDLE)pattern);
- CheckValid();
- OBJ_REF_ADD(Handle, Brush);
- }
-
- TBrush::TBrush(const LOGBRUSH far* logBrush)
- {
- PRECONDITION(logBrush);
- Handle = ::CreateBrushIndirect((LPLOGBRUSH)logBrush); // API cast
- WARNX(OwlGDI, !Handle, 0, "Cannot create TBrush from logBrush @" <<
- hex << uint32(LPVOID(logBrush)));
- CheckValid();
- OBJ_REF_ADD(Handle, Brush);
- }
-
- TBrush::TBrush(const TBrush& src)
- {
- LOGBRUSH logBrush;
- src.GetObject(logBrush);
- Handle = ::CreateBrushIndirect(&logBrush);
- WARNX(OwlGDI, !Handle, 0, "Cannot create TBrush from TBrush @" <<
- hex << uint32(LPVOID(&src)));
- CheckValid();
- OBJ_REF_ADD(Handle, Brush);
- }
-
- //----------------------------------------------------------------------------
-
- THatch8x8Brush::THatch8x8Brush(const uint8 hatch[], TColor fgColor, TColor bgColor)
- : TBrush(Create(hatch, fgColor, bgColor), AutoDelete)
- {
- }
-
- //
- // reconstructs the brush with a new pattern or colors
- //
- void
- THatch8x8Brush::Reconstruct(const uint8 hatch[], TColor fgColor, TColor bgColor)
- {
- if (Handle) {
- #if !defined(NO_GDI_ORPHAN_CONTROL)
- OBJ_REF_DEC(Handle, true);
- #else
- if (!::DeleteObject(Handle))
- THROW( TXGdi(IDS_GDIDELETEFAIL, Handle) );
- #endif
- }
- Handle = Create(hatch, fgColor, bgColor);
- OBJ_REF_ADD(Handle, Brush);
- }
-
- //
- // private static create member to create or re-create the handle
- //
- HBRUSH
- THatch8x8Brush::Create(const uint8 hatch[], TColor fgColor, TColor bgColor)
- {
- TDib dib(8, 8, 2, DIB_RGB_COLORS);
- unsigned char HUGE* bits = (unsigned char HUGE*)dib.GetBits();
- memset(bits, 0, 8*sizeof(uint32));
- for (int i = 0; i < 8; i++)
- bits[(7-i) * sizeof(uint32)] = hatch[i]; // Dib is upside down
- dib.SetColor(0, bgColor);
- dib.SetColor(1, fgColor);
-
- #if (0) // Extra step using hbitmap required for some Win32 versions
- TBitmap bm(dib);
- LOGBRUSH lb = { BS_PATTERN, DIB_RGB_COLORS, (int)HANDLE(bm) };
- HBRUSH handle = ::CreateBrushIndirect(&lb);
- #else
- HBRUSH handle = ::CreateDIBPatternBrush(dib, DIB_RGB_COLORS);
- #endif
-
- CheckValid(handle);
- return handle;
- }
-
- //
- // Predefined 8x8 hatch patterns
- //
- const uint8 THatch8x8Brush::Hatch22F1[8] = {
- 0x99, 0x33, 0x66, 0xCC, 0x99, 0x33, 0x66, 0xCC
- };
- const uint8 THatch8x8Brush::Hatch13F1[8] = {
- 0x88, 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44
- };
- const uint8 THatch8x8Brush::Hatch11F1[8] = {
- 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55
- };
- const uint8 THatch8x8Brush::Hatch22B1[8] = {
- 0xCC, 0x66, 0x33, 0x99, 0xCC, 0x66, 0x33, 0x99
- };
- const uint8 THatch8x8Brush::Hatch13B1[8] = {
- 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11, 0x88
- };
-
-