From 4f72fe4f1a906688bfc4ea99a5007437503babdf Mon Sep 17 00:00:00 2001 From: David Webster Date: Fri, 3 Dec 1999 22:23:58 +0000 Subject: [PATCH] Bitmap coding git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4812 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/os2/bitmap.h | 15 +-- include/wx/os2/gdiimage.h | 206 +++++++++++++++++++++++++++++++ src/os2/bitmap.cpp | 249 +++++++++++++++++++++----------------- 3 files changed, 350 insertions(+), 120 deletions(-) create mode 100644 include/wx/os2/gdiimage.h diff --git a/include/wx/os2/bitmap.h b/include/wx/os2/bitmap.h index 5ad96f1a55..6982b9fe85 100644 --- a/include/wx/os2/bitmap.h +++ b/include/wx/os2/bitmap.h @@ -206,18 +206,7 @@ public: inline wxDC* GetSelectedInto() const { return (GetBitmapData() ? GetBitmapData()->m_selectedInto : (wxDC*) NULL); } - // Creates a bitmap that matches the device context's depth, from an - // arbitray bitmap. At present, the original bitmap must have an associated - // palette. (TODO: use a default palette if no palette exists.) This - // function is necessary for you to Blit an arbitrary bitmap (which may - // have the wrong depth). wxDC::SelectObject will compare the depth of the - // bitmap with the DC's depth, and create a new bitmap if the depths - // differ. Eventually we should perhaps make this a public API function so - // that an app can efficiently produce bitmaps of the correct depth. The - // Windows solution is to use SetDibBits to blit an arbotrary DIB directly - // to a DC, but this is too Windows-specific, hence this solution of - // quietly converting the wxBitmap. Contributed by Frederic Villeneuve - // + // An OS/2 version that probably doesn't do anything like the msw version wxBitmap GetBitmapForDC(wxDC& rDc) const; protected: @@ -229,6 +218,8 @@ protected: private: bool CopyFromIconOrCursor(const wxGDIImage& rIcon); + HDC m_hDc; + HPS m_hPs; DECLARE_DYNAMIC_CLASS(wxBitmap) }; diff --git a/include/wx/os2/gdiimage.h b/include/wx/os2/gdiimage.h new file mode 100644 index 0000000000..9ad840e345 --- /dev/null +++ b/include/wx/os2/gdiimage.h @@ -0,0 +1,206 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: include/wx/os2/gdiimage.h +// Purpose: wxGDIImage class: base class for wxBitmap, wxIcon, wxCursor +// under OS/2 +// Author: David Webster (adapted from msw version by Vadim Zeitlin) +// Modified by: +// Created: 20.11.99 +// RCS-ID: $Id$ +// Copyright: (c) 1999 David Webster +// Licence: wxWindows license +/////////////////////////////////////////////////////////////////////////////// + +// NB: this is a private header, it is not intended to be directly included by +// user code (but may be included from other, public, wxWin headers + +#ifndef _WX_OS2_GDIIMAGE_H_ +#define _WX_OS2_GDIIMAGE_H_ + +#ifdef __GNUG__ + #pragma interface "gdiimage.h" +#endif + +#include "wx/gdiobj.h" // base class +#include "wx/gdicmn.h" // wxBITMAP_TYPE_INVALID +#include "wx/list.h" + +class WXDLLEXPORT wxGDIImageRefData; +class WXDLLEXPORT wxGDIImageHandler; +class WXDLLEXPORT wxGDIImage; + +// ---------------------------------------------------------------------------- +// wxGDIImageRefData: common data fields for all derived classes +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxGDIImageRefData : public wxGDIRefData +{ +public: + wxGDIImageRefData() + { + m_nWidth = m_nHeight = m_nDepth = 0; + + m_hHandle = 0; + +#if WXWIN_COMPATIBILITY_2 + m_bOk = FALSE; +#endif // WXWIN_COMPATIBILITY_2 + } + + // accessors + bool IsOk() const { return m_hHandle != 0; } + + void SetSize( int nW + ,int nH + ) + { m_nWidth = nW; m_nHeight = nH; } + + // free the ressources we allocated + virtual void Free() = 0; + + // for compatibility, the member fields are public + + // the size of the image + int m_nWidth; + int m_nHeight; + + // the depth of the image + int m_nDepth; + + // the handle to it + union + { + WXHANDLE m_hHandle; // for untyped access + WXHBITMAP m_hBitmap; + WXHICON m_hIcon; + WXHCURSOR m_hCursor; + }; + + // this filed is redundant and using it is error prone but keep it for + // backwards compatibility +#if WXWIN_COMPATIBILITY_2 + void SetOk() { m_bOk = m_hHandle != 0; } + + bool m_bOk; +#endif // WXWIN_COMPATIBILITY_2 +}; + +// ---------------------------------------------------------------------------- +// wxGDIImageHandler: a class which knows how to load/save wxGDIImages. +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxGDIImageHandler : public wxObject +{ +public: + // ctor + wxGDIImageHandler() { m_lType = wxBITMAP_TYPE_INVALID; } + wxGDIImageHandler( const wxString& rName + ,const wxString& rExt + ,long lType + ) + : m_sName(rName) + , m_sExtension(rExt) + { + m_lType = lType; + } + + // accessors + void SetName(const wxString& rName) { m_sName = rName; } + void SetExtension(const wxString& rExt) { m_sExtension = rExt; } + void SetType(long lType) { m_lType = lType; } + + wxString GetName() const { return m_sName; } + wxString GetExtension() const { return m_sExtension; } + long GetType() const { return m_lType; } + + // real handler operations: to implement in derived classes + virtual bool Create( wxGDIImage* pImage + ,void* pData + ,long lFlags + ,int nWidth + ,int nHeight + ,int nDepth = 1 + ) = 0; + virtual bool Load( wxGDIImage* pImage + ,const wxString& rName + ,long lFlags + ,int nDesiredWidth + ,int nDesiredHeight + ) = 0; + virtual bool Save( wxGDIImage* pImage + ,const wxString& rName + ,int lType + ) = 0; + +protected: + wxString m_sName; + wxString m_sExtension; + long m_lType; +}; + +// ---------------------------------------------------------------------------- +// wxGDIImage: this class supports GDI image handlers which may be registered +// dynamically and will be used for loading/saving the images in the specified +// format. It also falls back to wxImage if no appropriate image is found. +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxGDIImage : public wxGDIObject +{ +public: + // handlers list interface + static wxList& GetHandlers() { return ms_handlers; } + + static void AddHandler(wxGDIImageHandler* hHandler); + static void InsertHandler(wxGDIImageHandler* hHandler); + static bool RemoveHandler(const wxString& rName); + + static wxGDIImageHandler* FindHandler(const wxString& rName); + static wxGDIImageHandler* FindHandler(const wxString& rExtension, long lType); + static wxGDIImageHandler* FindHandler(long lType); + + static void InitStandardHandlers(); + static void CleanUpHandlers(); + + // access to the ref data casted to the right type + wxGDIImageRefData *GetGDIImageData() const + { return (wxGDIImageRefData *)m_refData; } + + // create data if we don't have it yet + void EnsureHasData() { if ( IsNull() ) m_refData = CreateData(); } + + // accessors + WXHANDLE GetHandle() const + { return IsNull() ? 0 : GetGDIImageData()->m_hHandle; } + void SetHandle(WXHANDLE hHandle) + { EnsureHasData(); GetGDIImageData()->m_hHandle = hHandle; } + + bool Ok() const { return GetHandle() != 0; } + + int GetWidth() const { return IsNull() ? 0 : GetGDIImageData()->m_nWidth; } + int GetHeight() const { return IsNull() ? 0 : GetGDIImageData()->m_nHeight; } + int GetDepth() const { return IsNull() ? 0 : GetGDIImageData()->m_nDepth; } + + void SetWidth(int nW) { EnsureHasData(); GetGDIImageData()->m_nWidth = nW; } + void SetHeight(int nH) { EnsureHasData(); GetGDIImageData()->m_nHeight = nH; } + void SetDepth(int nD) { EnsureHasData(); GetGDIImageData()->m_nDepth = nD; } + + void SetSize( int nW + ,int nH + ) + { + EnsureHasData(); + GetGDIImageData()->SetSize(nW, nH); + } + void SetSize(const wxSize& rSize) { SetSize(rSize.x, rSize.y); } + + // forward some of base class virtuals to wxGDIImageRefData + bool FreeResource(bool bForce = FALSE); + virtual WXHANDLE GetResourceHandle(); + +protected: + // create the data for the derived class here + virtual wxGDIImageRefData* CreateData() const = 0; + + static wxList ms_handlers; +}; + +#endif // _WX_MSW_GDIIMAGE_H_ diff --git a/src/os2/bitmap.cpp b/src/os2/bitmap.cpp index 872a468db5..1069f59013 100644 --- a/src/os2/bitmap.cpp +++ b/src/os2/bitmap.cpp @@ -182,12 +182,15 @@ wxBitmap::wxBitmap( vHeader.ulColorEncoding = 0; vHeader.ulIdentifier = 0; - vhPs = ::GpiCreatePS(habMain, hdc, &vSize, GPIA_ASSOC | PU_PELS); - if (vhPs == 0) + hPs = ::GpiCreatePS(habMain, hdc, &vSize, GPIA_ASSOC | PU_PELS); + if (hPs == 0) { wxLogLastError("GpiCreatePS Failure"); } + m_hDc = hDc; + m_hPs = hPs; + m_refData = pRefData; refData->m_width = nTheWidth; @@ -272,20 +275,23 @@ bool wxBitmap::Create( HBITMAP hBmp; BITMAPINFOHEADER2 vHeader; BITMAPINFO2 vInfo; - HDC hDc; - HPS hPs; + HPS hpsScreen; + HDC hdcScreen; DEVOPENSTRUCT vDop = { NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL }; SIZEL vSize = {0, 0}; + LONG lBitCount; wxAssert(vHabmain != NULL); - hDc = ::DevOpenDC(vHabmain, OD_MEMORY, (PSZ)"*", 1L, (PDEVOPENDATA)&vDop, 0L); + hpsScreen = ::WinGetScreenPS(HWND_DESKTOP); + hdcScreen = ::GpiQueryDevice(hpsScreen); + ::DevQueryCaps(hdcScreen, CAPS_COLOR_BITCOUNT, &lBitCount); vHeader.cbFix = sizeof(vHeader); vHeader.cx = (USHORT)nW; vHeader.cy = (USHORT)nH; vHeader.cPlanes = (USHORT)nD; - vHeader.cBitCount = 24; + vHeader.cBitCount = lBitCount; vHeader.ulCompression = BCA_UNCOMP; vHeader.cxResolution = 0; vHeader.cyResolution = 0; @@ -299,12 +305,6 @@ bool wxBitmap::Create( vHeader.ulColorEncoding = 0; vHeader.ulIdentifier = 0; - vhPs = ::GpiCreatePS(habMain, hdc, &vSize, GPIA_ASSOC | PU_PELS); - if (vhPs == 0) - { - wxLogLastError("GpiCreatePS Failure"); - } - UnRef(); m_refData = new wxBitmapRefData; @@ -315,7 +315,7 @@ bool wxBitmap::Create( if (nD > 0) { - hBmp = ::GpiCreateBitmap(hPs, &vHeader, 0L, NULL, &vInfo); + hBmp = ::GpiCreateBitmap(hpsScreen, &vHeader, 0L, NULL, &vInfo); if (!hBmp) { wxLogLastError("CreateBitmap"); @@ -323,84 +323,122 @@ bool wxBitmap::Create( } else { - ScreenHDC dc; - hbmp = ::CreateCompatibleBitmap(dc, w, h); - if ( !hbmp ) + LONG lPlanes; + + ::DevQueryCaps(hdcScreen, CAPS_COLOR_PLANES, &lPlanes); + hBmp = ::GpiCreateBitmap(hpsScreen, &vHeader, 0L, NULL, &vInfo); + if (!hBmp) { - wxLogLastError("CreateCompatibleBitmap"); + wxLogLastError("CreateBitmap"); } - GetBitmapData()->m_depth = wxDisplayDepth(); } - - SetHBITMAP((WXHBITMAP)hbmp); + SetHBITMAP((WXHBITMAP)hBmp); #if WXWIN_COMPATIBILITY_2 - GetBitmapData()->m_ok = hbmp != 0; + GetBitmapData()->m_bOk = hBmp != 0; #endif // WXWIN_COMPATIBILITY_2 return Ok(); } -bool wxBitmap::LoadFile(const wxString& filename, long type) +bool wxBitmap::LoadFile( + const wxString& rFilename +, long lType +) { UnRef(); - wxBitmapHandler *handler = wxDynamicCast(FindHandler(type), wxBitmapHandler); + wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType) + ,wxBitmapHandler + ); - if ( handler ) + if (pHandler) { m_refData = new wxBitmapRefData; - return handler->LoadFile(this, filename, type, -1, -1); + return(pHandler->LoadFile( this + ,rFilename + ,lType + , -1 + , -1 + ); } else { - wxImage image; - if ( !image.LoadFile( filename, type ) || !image.Ok() ) - return FALSE; + wxImage vImage; - *this = image.ConvertToBitmap(); + if (!vImage.LoadFile(rFilename, lType) || !image.Ok() ) + return(FALSE); - return TRUE; + *this = vImage.ConvertToBitmap(); + + return(TRUE); } } -bool wxBitmap::Create(void *data, long type, int width, int height, int depth) +bool wxBitmap::Create( + void* pData +, long lType +, int nWidth +, int nHeight +, int nDepth +) { UnRef(); - wxBitmapHandler *handler = wxDynamicCast(FindHandler(type), wxBitmapHandler); + wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType) + ,wxBitmapHandler + ); - if ( !handler ) + if (!pHandler) { wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for " "type %d defined."), type); - return FALSE; + return(FALSE); } m_refData = new wxBitmapRefData; - return handler->Create(this, data, type, width, height, depth); + return(handler->Create( this + ,pData + ,lType + ,nWidth + ,nHeight + ,nDepth + )); } -bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *palette) +bool wxBitmap::SaveFile( + const wxString& rFilename +, int lType +, const wxPalette* pPalette +) { - wxBitmapHandler *handler = wxDynamicCast(FindHandler(type), wxBitmapHandler); + wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType) + ,wxBitmapHandler + ); - if ( handler ) + if (pHandler) { - return handler->SaveFile(this, filename, type, palette); + return pHandler->SaveFile( this + ,rFilename + ,lType + ,pPalette + ); } else { // FIXME what about palette? shouldn't we use it? - wxImage image( *this ); - if (!image.Ok()) - return FALSE; + wxImage vImage(*this); + + if (!vImage.Ok()) + return(FALSE); - return image.SaveFile( filename, type ); + return(vImage.SaveFile( rFilename + ,lType + )); } } @@ -408,85 +446,68 @@ bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *pal // wxBitmap accessors // ---------------------------------------------------------------------------- -void wxBitmap::SetQuality(int q) +void wxBitmap::SetQuality( + int nQ +) { EnsureHasData(); - GetBitmapData()->m_quality = q; + GetBitmapData()->m_nQuality = nQ; } #if WXWIN_COMPATIBILITY_2 -void wxBitmap::SetOk(bool isOk) +void wxBitmap::SetOk( + bool bOk +) { EnsureHasData(); - GetBitmapData()->m_ok = isOk; + GetBitmapData()->m_bOk = bOk; } #endif // WXWIN_COMPATIBILITY_2 -void wxBitmap::SetPalette(const wxPalette& palette) +void wxBitmap::SetPalette( + const wxPalette& rPalette +) { EnsureHasData(); - GetBitmapData()->m_bitmapPalette = palette; + GetBitmapData()->m_vBitmapPalette = rPalette; } -void wxBitmap::SetMask(wxMask *mask) +void wxBitmap::SetMask( + wxMask* pMask +) { EnsureHasData(); - GetBitmapData()->m_bitmapMask = mask; + GetBitmapData()->m_pBitmapMask = pMask; } -// Creates a bitmap that matches the device context, from -// an arbitray bitmap. At present, the original bitmap must have an -// associated palette. TODO: use a default palette if no palette exists. -// Contributed by Frederic Villeneuve -wxBitmap wxBitmap::GetBitmapForDC(wxDC& dc) const +// Will try something for OS/2 but not really sure how close +// to the msw intent this is. +wxBitmap wxBitmap::GetBitmapForDC( + wxDC& rDc +) const { - wxMemoryDC memDC; - wxBitmap tmpBitmap(this->GetWidth(), this->GetHeight(), dc.GetDepth()); - HPALETTE hPal = (HPALETTE) NULL; - LPBITMAPINFO lpDib; - void *lpBits = (void*) NULL; - - if( GetPalette() && GetPalette()->Ok() ) - { - tmpBitmap.SetPalette(*GetPalette()); - memDC.SelectObject(tmpBitmap); - memDC.SetPalette(*GetPalette()); - hPal = (HPALETTE)GetPalette()->GetHPALETTE(); - } - else - { - hPal = (HPALETTE) ::GetStockObject(DEFAULT_PALETTE); - wxPalette palette; - palette.SetHPALETTE( (WXHPALETTE)hPal ); - tmpBitmap.SetPalette( palette ); - memDC.SelectObject(tmpBitmap); - memDC.SetPalette( palette ); - } - - // set the height negative because in a DIB the order of the lines is - // reversed - if ( !wxCreateDIB(GetWidth(), -GetHeight(), GetDepth(), hPal, &lpDib) ) - { - return wxNullBitmap; - } - - lpBits = malloc(lpDib->bmiHeader.biSizeImage); - - ::GetBitmapBits(GetHbitmap(), lpDib->bmiHeader.biSizeImage, lpBits); - - ::SetDIBitsToDevice(GetHdcOf(memDC), 0, 0, - GetWidth(), GetHeight(), - 0, 0, 0, GetHeight(), - lpBits, lpDib, DIB_RGB_COLORS); + wxMemoryDC vMemDC; + wxBitmap vTmpBitmap( this->GetWidth() + ,this->GetHeight() + ,rDc.GetDepth() + ); + HPS hMemoryPS; + HPS hPs; + POINTL vPoint[4]; + SIZEL vSize = {0,0} - free(lpBits); + hMemoryPS = ::GpiCreatePS(habMain, (HDC)vMemDC.m_hDc, &vSize, PU_PELS | GPIT_MICRO | GPI_ASSOC); + hPs = ::GpiCreatePS(habMain, (HDC)rDc.m_hDc, &vSize, PU_PELS | GPIT_MICRO | GPI_ASSOC); - wxFreeDIB(lpDib); + // TODO: Set the points + rDc.m_oldBitmap = (WXHBITMAP)::GpiSetBitMap(hPs, (HBITMAP)vTmpBitmap.GetHBITMAP()); + :GpiBitBlt(hPs, hMemoryPS, 4L, vPoint, &vSize, PU_PELS | GPI_ASSOC); + return tmpBitmap; } @@ -496,36 +517,48 @@ wxBitmap wxBitmap::GetBitmapForDC(wxDC& dc) const wxMask::wxMask() { - m_maskBitmap = 0; + m_hMaskBitmap = 0; } // Construct a mask from a bitmap and a colour indicating // the transparent area -wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour) +wxMask::wxMask( + const wxBitmap& rBitmap +, const wxColour& rColour +) { - m_maskBitmap = 0; - Create(bitmap, colour); + m_hMaskBitmap = 0; + Create( rBitmap + ,rColour + ); } // Construct a mask from a bitmap and a palette index indicating // the transparent area -wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex) +wxMask::wxMask( + const wxBitmap& rBitmap +, int nPaletteIndex +) { - m_maskBitmap = 0; - Create(bitmap, paletteIndex); + m_hMaskBitmap = 0; + Create( rBitmap + ,nPaletteIndex + ); } // Construct a mask from a mono bitmap (copies the bitmap). -wxMask::wxMask(const wxBitmap& bitmap) +wxMask::wxMask( + const wxBitmap& rBitmap +) { - m_maskBitmap = 0; - Create(bitmap); + m_hMaskBitmap = 0; + Create(rBitmap); } wxMask::~wxMask() { - if ( m_maskBitmap ) - ::DeleteObject((HBITMAP) m_maskBitmap); + if (m_hMaskBitmap) + ::GpiDeleteBitmap((HBITMAP)m_hMaskBitmap); } // Create a mask from a mono bitmap (copies the bitmap). -- 2.45.2