X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f9619ece1db7827a08ef7b1c04be60a3e5c88b77..eea4d01c65f9b29baa1193db762b4c6b8144af24:/src/mgl/bitmap.cpp?ds=inline diff --git a/src/mgl/bitmap.cpp b/src/mgl/bitmap.cpp index 0520051d37..bae5a0c596 100644 --- a/src/mgl/bitmap.cpp +++ b/src/mgl/bitmap.cpp @@ -1,15 +1,11 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: bitmap.cpp +// Name: src/mgl/bitmap.cpp // Author: Vaclav Slavik // RCS-ID: $Id$ -// Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com) +// Copyright: (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com) // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "bitmap.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -18,161 +14,145 @@ #endif #include "wx/bitmap.h" -#include "wx/icon.h" + +#ifndef WX_PRECOMP + #include "wx/intl.h" + #include "wx/log.h" + #include "wx/utils.h" + #include "wx/dcmemory.h" + #include "wx/icon.h" + #include "wx/image.h" +#endif + #include "wx/filefn.h" -#include "wx/image.h" -#include "wx/dcmemory.h" -#include "wx/utils.h" -#include "wx/log.h" -#include "wx/intl.h" -#include "wx/image.h" #include "wx/xpmdecod.h" #include "wx/mgl/private.h" #include +static bitmap_t *MyMGL_createBitmap(int width, int height, + int bpp, pixel_format_t *pf) +{ + MGLMemoryDC mdc(width, height, bpp, pf); + return MGL_getBitmapFromDC(mdc.getDC(), 0, 0, width, height, TRUE); +} + //----------------------------------------------------------------------------- // MGL pixel formats: //----------------------------------------------------------------------------- static pixel_format_t gs_pixel_format_15 = - {0x1F,0x0A,3, 0x1F,0x05,3, 0x1F,0x00,3, 0x01,0x0F,7}; // 555 15bpp - + {0x1F,0x0A,3, 0x1F,0x05,3, 0x1F,0x00,3, 0x01,0x0F,7}; // 555 15bpp + static pixel_format_t gs_pixel_format_16 = - {0x1F,0x0B,3, 0x3F,0x05,2, 0x1F,0x00,3, 0x00,0x00,0}; // 565 16bpp + {0x1F,0x0B,3, 0x3F,0x05,2, 0x1F,0x00,3, 0x00,0x00,0}; // 565 16bpp static pixel_format_t gs_pixel_format_24 = - {0xFF,0x10,0, 0xFF,0x08,0, 0xFF,0x00,0, 0x00,0x00,0}; // RGB 24bpp + {0xFF,0x10,0, 0xFF,0x08,0, 0xFF,0x00,0, 0x00,0x00,0}; // RGB 24bpp static pixel_format_t gs_pixel_format_32 = - {0xFF,0x18,0, 0xFF,0x10,0, 0xFF,0x08,0, 0xFF,0x00,0}; // RGBA 32bpp + {0xFF,0x18,0, 0xFF,0x10,0, 0xFF,0x08,0, 0xFF,0x00,0}; // RGBA 32bpp static pixel_format_t gs_pixel_format_wxImage = - {0xFF,0x00,0, 0xFF,0x08,0, 0xFF,0x10,0, 0x00,0x00,0}; // RGB 24bpp for wxImage - -//----------------------------------------------------------------------------- -// helpers -//----------------------------------------------------------------------------- - -// Convert wxColour into it's quantized value in lower-precision -// pixel format (needed for masking by colour). -static wxColour wxQuantizeColour(const wxColour& clr, const wxBitmap& bmp) -{ - pixel_format_t *pf = bmp.GetMGLbitmap_t()->pf; - - if ( pf->redAdjust == 0 && pf->greenAdjust == 0 && pf->blueAdjust == 0 ) - return clr; - else - return wxColour((clr.Red() >> pf->redAdjust) << pf->redAdjust, - (clr.Green() >> pf->greenAdjust) << pf->greenAdjust, - (clr.Blue() >> pf->blueAdjust) << pf->blueAdjust); -} - - + {0xFF,0x00,0, 0xFF,0x08,0, 0xFF,0x10,0, 0x00,0x00,0}; // RGB 24bpp for wxImage //----------------------------------------------------------------------------- -// wxMask +// wxBitmapRefData //----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxMask,wxObject) - -wxMask::wxMask() +class wxBitmapRefData: public wxGDIRefData { - m_bitmap = NULL; -} +public: + wxBitmapRefData(); + wxBitmapRefData(int width, int height, int bpp); + wxBitmapRefData(const wxBitmapRefData& data); + virtual ~wxBitmapRefData(); -wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour) -{ - m_bitmap = NULL; - Create(bitmap, colour); -} + virtual bool IsOk() const { return m_bitmap != NULL; } -wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex) -{ - m_bitmap = NULL; - Create(bitmap, paletteIndex); -} + int m_width; + int m_height; + int m_bpp; + wxPalette *m_palette; + wxMask *m_mask; + bitmap_t *m_bitmap; -wxMask::wxMask(const wxBitmap& bitmap) -{ - m_bitmap = NULL; - Create(bitmap); -} +private: + void DoCreateBitmap(int width, int height, int depth); +}; -wxMask::~wxMask() +void wxBitmapRefData::DoCreateBitmap(int width, int height, int depth) { - delete m_bitmap; -} + m_width = width; + m_height = height; + m_bpp = depth; -bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour) -{ - delete m_bitmap; - m_bitmap = NULL; - - wxColour clr(wxQuantizeColour(colour, bitmap)); + pixel_format_t pf_dummy; + pixel_format_t *pf; + int mglDepth = depth; - wxImage imgSrc(bitmap.ConvertToImage()); - imgSrc.SetMask(FALSE); - wxImage image(imgSrc.ConvertToMono(clr.Red(), clr.Green(), clr.Blue())); - if ( !image.Ok() ) return FALSE; + switch ( depth ) + { + case -1: + wxASSERT_MSG( g_displayDC, wxT("MGL display DC not created yet.") ); - m_bitmap = new wxBitmap(image, 1); + g_displayDC->getPixelFormat(pf_dummy); + mglDepth = g_displayDC->getBitsPerPixel(); + pf = &pf_dummy; + break; + case 1: + case 8: + pf = NULL; + mglDepth = 8; // we emulate monochrome bitmaps using 8 bit ones + break; + case 15: + pf = &gs_pixel_format_15; + break; + case 16: + pf = &gs_pixel_format_16; + break; + case 24: + pf = &gs_pixel_format_24; + break; + case 32: + pf = &gs_pixel_format_32; + break; + default: + wxFAIL_MSG(wxT("invalid bitmap depth")); + m_bitmap = NULL; + return; + } - return m_bitmap->Ok(); + m_bitmap = MyMGL_createBitmap(width, height, mglDepth, pf); } -bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex) +wxBitmapRefData::wxBitmapRefData() { - unsigned char r,g,b; - wxPalette *pal = bitmap.GetPalette(); + m_width = + m_height = + m_bpp = 0; - wxCHECK_MSG( pal, FALSE, wxT("Cannot create mask from bitmap without palette") ); - - pal->GetRGB(paletteIndex, &r, &g, &b); + m_palette = NULL; + m_mask = NULL; - return Create(bitmap, wxColour(r, g, b)); + m_bitmap = NULL; } -bool wxMask::Create(const wxBitmap& bitmap) +wxBitmapRefData::wxBitmapRefData(int width, int height, int bpp) { - delete m_bitmap; - m_bitmap = NULL; + DoCreateBitmap(width, height, bpp); - wxCHECK_MSG( bitmap.Ok(), FALSE, wxT("Invalid bitmap") ); - wxCHECK_MSG( bitmap.GetDepth() == 1, FALSE, wxT("Cannot create mask from colour bitmap") ); - - m_bitmap = new wxBitmap(bitmap); - return TRUE; + m_palette = NULL; + m_mask = NULL; } - -//----------------------------------------------------------------------------- -// wxBitmap -//----------------------------------------------------------------------------- - -class wxBitmapRefData: public wxObjectRefData +wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData& data) { -public: - wxBitmapRefData(); - ~wxBitmapRefData(); + DoCreateBitmap(data.m_width, data.m_height, data.m_bpp); - int m_width; - int m_height; - int m_bpp; - wxPalette *m_palette; - wxMask *m_mask; - bitmap_t *m_bitmap; -}; - -wxBitmapRefData::wxBitmapRefData() -{ - m_mask = NULL; - m_width = 0; - m_height = 0; - m_bpp = 0; - m_palette = NULL; - m_bitmap = NULL; + m_palette = NULL; // FIXME: should copy + m_mask = NULL; // FIXME: should copy } wxBitmapRefData::~wxBitmapRefData() @@ -183,124 +163,55 @@ wxBitmapRefData::~wxBitmapRefData() delete m_palette; } + +//----------------------------------------------------------------------------- +// wxBitmap //----------------------------------------------------------------------------- #define M_BMPDATA ((wxBitmapRefData *)m_refData) - -IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandler,wxObject) IMPLEMENT_DYNAMIC_CLASS(wxBitmap,wxBitmapBase) -wxBitmap::wxBitmap() -{ - if ( wxTheBitmapList ) wxTheBitmapList->AddBitmap(this); -} - -wxBitmap::wxBitmap(int width, int height, int depth) +wxGDIRefData *wxBitmap::CreateGDIRefData() const { - Create(width, height, depth); - - if ( wxTheBitmapList ) wxTheBitmapList->AddBitmap(this); + return new wxBitmapRefData; } - -static bitmap_t *MyMGL_createBitmap(int width, int height, - int bpp, pixel_format_t *pf) +wxGDIRefData *wxBitmap::CloneGDIRefData(const wxGDIRefData *data) const { - MGLMemoryDC mdc(width, height, bpp, pf); - return MGL_getBitmapFromDC(mdc.getDC(), 0, 0, width, height, TRUE); + return new wxBitmapRefData(*static_cast(data)); } bool wxBitmap::Create(int width, int height, int depth) { UnRef(); - wxCHECK_MSG( (width > 0) && (height > 0), FALSE, wxT("invalid bitmap size") ) - - pixel_format_t pf_dummy, *pf; - int mglDepth = depth; - - switch ( depth ) - { - case -1: - wxASSERT_MSG( g_displayDC, wxT("MGL display DC not created yet.") ); - - g_displayDC->getPixelFormat(pf_dummy); - mglDepth = g_displayDC->getBitsPerPixel(); - pf = &pf_dummy; - break; - case 1: - case 8: - pf = NULL; - break; - case 15: - pf = &gs_pixel_format_15; - break; - case 16: - pf = &gs_pixel_format_16; - break; - case 24: - pf = &gs_pixel_format_24; - break; - case 32: - pf = &gs_pixel_format_32; - break; - default: - wxASSERT_MSG( 0, wxT("invalid bitmap depth") ); - return FALSE; - break; - } + wxCHECK_MSG( (width > 0) && (height > 0), false, wxT("invalid bitmap size") ); - m_refData = new wxBitmapRefData(); - M_BMPDATA->m_mask = (wxMask *) NULL; - M_BMPDATA->m_palette = (wxPalette *) NULL; - M_BMPDATA->m_width = width; - M_BMPDATA->m_height = height; - M_BMPDATA->m_bpp = mglDepth; + m_refData = new wxBitmapRefData(width, height, depth); - if ( mglDepth != 1 ) - { - M_BMPDATA->m_bitmap = MyMGL_createBitmap(width, height, mglDepth, pf); - } - else + if ( depth == 1 ) { // MGL does not support mono DCs, so we have to emulate them with // 8bpp ones. We do that by using a special palette with color 0 - // set to black and all other colors set to white. - - M_BMPDATA->m_bitmap = MyMGL_createBitmap(width, height, 8, pf); + // set to black and all other colors set to white. SetMonoPalette(wxColour(255, 255, 255), wxColour(0, 0, 0)); } - return Ok(); -} - -bool wxBitmap::CreateFromXpm(const char **bits) -{ - wxCHECK_MSG( bits != NULL, FALSE, wxT("invalid bitmap data") ) - - wxXPMDecoder decoder; - wxImage img = decoder.ReadData(bits); - wxCHECK_MSG( img.Ok(), FALSE, wxT("invalid bitmap data") ) - - *this = wxBitmap(img); - - if ( wxTheBitmapList ) wxTheBitmapList->AddBitmap(this); - - return TRUE; + return IsOk(); } -wxBitmap::wxBitmap(const wxImage& image, int depth = -1) +wxBitmap::wxBitmap(const wxImage& image, int depth) { long width, height; - wxCHECK_RET( image.Ok(), wxT("invalid image") ) - + wxCHECK_RET( image.IsOk(), wxT("invalid image") ); + width = image.GetWidth(); height = image.GetHeight(); if ( !Create(width, height, depth) ) return; - + MGLMemoryDC idc(width, height, 24, &gs_pixel_format_wxImage, width * 3, (void*)image.GetData(), NULL); wxASSERT_MSG( idc.isValid(), wxT("cannot create custom MGLDC") ); @@ -312,13 +223,13 @@ wxBitmap::wxBitmap(const wxImage& image, int depth = -1) bdc->bitBlt(idc, 0, 0, width, height, 0, 0, MGL_REPLACE_MODE); delete bdc; - + if ( image.HasMask() ) { wxImage mask_image = image.ConvertToMono(image.GetMaskRed(), image.GetMaskGreen(), image.GetMaskBlue()); - mask_image.SetMask(FALSE); + mask_image.SetMask(false); wxBitmap mask_bmp(mask_image, 1); SetMask(new wxMask(mask_bmp)); } @@ -326,22 +237,22 @@ wxBitmap::wxBitmap(const wxImage& image, int depth = -1) wxImage wxBitmap::ConvertToImage() const { - wxCHECK_MSG( Ok(), FALSE, wxT("invalid bitmap") ); + wxCHECK_MSG( IsOk(), wxImage(), wxT("invalid bitmap") ); int width, height; width = GetWidth(); height = GetHeight(); - + wxImage image(width, height); - wxASSERT_MSG( image.Ok(), wxT("cannot create image") ); - + wxASSERT_MSG( image.IsOk(), wxT("cannot create image") ); + MGLMemoryDC idc(width, height, 24, &gs_pixel_format_wxImage, width * 3, (void*)image.GetData(), NULL); wxASSERT_MSG( idc.isValid(), wxT("cannot create custom MGLDC") ); if ( M_BMPDATA->m_palette ) image.SetPalette(*(M_BMPDATA->m_palette)); - + if ( GetMask() ) { // in consistency with other ports, we convert parts covered @@ -350,35 +261,26 @@ wxImage wxBitmap::ConvertToImage() const // bg colour set to black and fg colour to <16,16,16> image.SetMaskColour(16, 16, 16); - image.SetMask(TRUE); + image.SetMask(true); wxDC tmpDC; - tmpDC.SetMGLDC(&idc, FALSE); + tmpDC.SetMGLDC(&idc, false); tmpDC.SetBackground(wxBrush(wxColour(16,16,16), wxSOLID)); tmpDC.Clear(); - tmpDC.DrawBitmap(*this, 0, 0, TRUE); + tmpDC.DrawBitmap(*this, 0, 0, true); } else { - image.SetMask(FALSE); + image.SetMask(false); idc.putBitmap(0, 0, M_BMPDATA->m_bitmap, MGL_REPLACE_MODE); } return image; } -wxBitmap::wxBitmap(const wxBitmap& bmp) -{ - Ref(bmp); - - if ( wxTheBitmapList ) wxTheBitmapList->AddBitmap(this); -} - wxBitmap::wxBitmap(const wxString &filename, wxBitmapType type) { LoadFile(filename, type); - - if ( wxTheBitmapList ) wxTheBitmapList->AddBitmap(this); } wxBitmap::wxBitmap(const char bits[], int width, int height, int depth) @@ -393,69 +295,41 @@ wxBitmap::wxBitmap(const char bits[], int width, int height, int depth) bdc->clearDevice(); bdc->putMonoImage(0, 0, width, (width + 7) / 8, height, (void*)bits); delete bdc; - - if ( wxTheBitmapList ) wxTheBitmapList->AddBitmap(this); -} - -wxBitmap::~wxBitmap() -{ - if ( wxTheBitmapList ) wxTheBitmapList->DeleteObject(this); -} - -wxBitmap& wxBitmap::operator = (const wxBitmap& bmp) -{ - if ( *this == bmp ) return (*this); - Ref(bmp); - return *this; -} - -bool wxBitmap::operator == (const wxBitmap& bmp) const -{ - return (m_refData == bmp.m_refData); -} - -bool wxBitmap::operator != (const wxBitmap& bmp) const -{ - return (m_refData != bmp.m_refData); -} - -bool wxBitmap::Ok() const -{ - return (m_refData != NULL && M_BMPDATA->m_bitmap != NULL); } int wxBitmap::GetHeight() const { - wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); + wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") ); return M_BMPDATA->m_height; } int wxBitmap::GetWidth() const { - wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); + wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") ); return M_BMPDATA->m_width; } int wxBitmap::GetDepth() const { - wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); + wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") ); return M_BMPDATA->m_bpp; } wxMask *wxBitmap::GetMask() const { - wxCHECK_MSG( Ok(), (wxMask *) NULL, wxT("invalid bitmap") ); + wxCHECK_MSG( IsOk(), NULL, wxT("invalid bitmap") ); return M_BMPDATA->m_mask; } void wxBitmap::SetMask(wxMask *mask) { - wxCHECK_RET( Ok(), wxT("invalid bitmap") ); + wxCHECK_RET( IsOk(), wxT("invalid bitmap") ); + AllocExclusive(); delete M_BMPDATA->m_mask; M_BMPDATA->m_mask = mask; } @@ -464,31 +338,31 @@ bool wxBitmap::CopyFromIcon(const wxIcon& icon) { wxBitmap *bmp = (wxBitmap*)(&icon); *this = *bmp; - return TRUE; + return true; } wxBitmap wxBitmap::GetSubBitmap(const wxRect& rect) const { - wxCHECK_MSG( Ok() && + wxCHECK_MSG( IsOk() && (rect.x >= 0) && (rect.y >= 0) && (rect.x+rect.width <= M_BMPDATA->m_width) && (rect.y+rect.height <= M_BMPDATA->m_height), wxNullBitmap, wxT("invalid bitmap or bitmap region") ); wxBitmap ret( rect.width, rect.height, M_BMPDATA->m_bpp ); - wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") ); + wxASSERT_MSG( ret.IsOk(), wxT("GetSubBitmap error") ); if ( GetPalette() ) ret.SetPalette(*GetPalette()); MGLDevCtx *tdc = ret.CreateTmpDC(); - tdc->putBitmapSection(rect.x, rect.y, + tdc->putBitmapSection(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height, 0, 0, M_BMPDATA->m_bitmap, MGL_REPLACE_MODE); delete tdc; if ( GetMask() ) { - wxBitmap submask = GetMask()->GetBitmap()->GetSubBitmap(rect); + wxBitmap submask = GetMask()->GetBitmap().GetSubBitmap(rect); ret.SetMask(new wxMask(submask)); } @@ -497,8 +371,9 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect& rect) const void wxBitmap::SetMonoPalette(const wxColour& fg, const wxColour& bg) { - wxCHECK_RET( Ok(), wxT("invalid bitmap") ); + wxCHECK_RET( IsOk(), wxT("invalid bitmap") ); + AllocExclusive(); palette_t *mono = M_BMPDATA->m_bitmap->pal; wxCHECK_RET( M_BMPDATA->m_bpp == 1, wxT("bitmap is not 1bpp") ); @@ -519,20 +394,20 @@ void wxBitmap::SetMonoPalette(const wxColour& fg, const wxColour& bg) MGLDevCtx *wxBitmap::CreateTmpDC() const { - wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); + wxCHECK_MSG( IsOk(), NULL, wxT("invalid bitmap") ); MGLDevCtx *tdc = new MGLMemoryDC(GetWidth(), GetHeight(), M_BMPDATA->m_bitmap->bitsPerPixel, M_BMPDATA->m_bitmap->pf, M_BMPDATA->m_bitmap->bytesPerLine, - M_BMPDATA->m_bitmap->surface, + M_BMPDATA->m_bitmap->surface, NULL); wxCHECK_MSG( tdc->isValid(), NULL, wxT("cannot create temporary MGLDC") ); if ( M_BMPDATA->m_bitmap->pal != NULL ) { int cnt; - + switch (M_BMPDATA->m_bitmap->bitsPerPixel) { case 2: cnt = 2; break; @@ -543,69 +418,67 @@ MGLDevCtx *wxBitmap::CreateTmpDC() const wxFAIL_MSG( wxT("bitmap with this depth cannot have palette") ); break; } - + tdc->setPalette(M_BMPDATA->m_bitmap->pal, cnt, 0); tdc->realizePalette(cnt, 0, FALSE); } - + return tdc; } bool wxBitmap::LoadFile(const wxString &name, wxBitmapType type) { - UnRef(); - - if ( type == wxBITMAP_TYPE_BMP || type == wxBITMAP_TYPE_PNG || + AllocExclusive(); + + if ( type == wxBITMAP_TYPE_BMP || type == wxBITMAP_TYPE_PNG || type == wxBITMAP_TYPE_PCX || type == wxBITMAP_TYPE_JPEG ) { // prevent accidental loading of bitmap from $MGL_ROOT: if ( !wxFileExists(name) ) { wxLogError(_("File %s does not exist."), name.c_str()); - return FALSE; + return false; } } - + wxBitmapHandler *handler = FindHandler(type); - if ( handler == NULL ) + if ( handler == NULL ) { wxImage image; - if ( !image.LoadFile(name, type) || !image.Ok() ) + if ( !image.LoadFile(name, type) || !image.IsOk() ) { - wxLogError("no bitmap handler for type %d defined.", type); - return FALSE; + wxLogError("no bitmap handler for type %d defined.", type); + return false; } else { *this = wxBitmap(image); - return TRUE; + return true; } } - m_refData = new wxBitmapRefData(); - return handler->LoadFile(this, name, type, -1, -1); } bool wxBitmap::SaveFile(const wxString& filename, wxBitmapType type, const wxPalette *palette) const { - wxCHECK_MSG( Ok(), FALSE, wxT("invalid bitmap") ); + wxCHECK_MSG( IsOk(), false, wxT("invalid bitmap") ); wxBitmapHandler *handler = FindHandler(type); - if ( handler == NULL ) + if ( handler == NULL ) { wxImage image = ConvertToImage(); if ( palette ) image.SetPalette(*palette); - if ( image.Ok() ) + if ( image.IsOk() ) return image.SaveFile(filename, type); else { wxLogError("no bitmap handler for type %d defined.", type); - return FALSE; + return false; } } @@ -614,21 +487,21 @@ bool wxBitmap::SaveFile(const wxString& filename, wxBitmapType type, const wxPal wxPalette *wxBitmap::GetPalette() const { - wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); + wxCHECK_MSG( IsOk(), NULL, wxT("invalid bitmap") ); return M_BMPDATA->m_palette; } void wxBitmap::SetPalette(const wxPalette& palette) { - wxCHECK_RET( Ok(), wxT("invalid bitmap") ); + wxCHECK_RET( IsOk(), wxT("invalid bitmap") ); wxCHECK_RET( GetDepth() > 1 && GetDepth() <= 8, wxT("cannot set palette for bitmap of this depth") ); - delete M_BMPDATA->m_palette; - M_BMPDATA->m_palette = NULL; + AllocExclusive(); + wxDELETE(M_BMPDATA->m_palette); + + if ( !palette.IsOk() ) return; - if ( !palette.Ok() ) return; - M_BMPDATA->m_palette = new wxPalette(palette); int cnt = palette.GetColoursCount(); @@ -638,21 +511,21 @@ void wxBitmap::SetPalette(const wxPalette& palette) void wxBitmap::SetHeight(int height) { - if (!m_refData) m_refData = new wxBitmapRefData(); + AllocExclusive(); M_BMPDATA->m_height = height; } void wxBitmap::SetWidth(int width) { - if (!m_refData) m_refData = new wxBitmapRefData(); + AllocExclusive(); M_BMPDATA->m_width = width; } void wxBitmap::SetDepth(int depth) { - if (!m_refData) m_refData = new wxBitmapRefData(); + AllocExclusive(); M_BMPDATA->m_bpp = depth; } @@ -662,6 +535,19 @@ bitmap_t *wxBitmap::GetMGLbitmap_t() const return M_BMPDATA->m_bitmap; } +// Convert wxColour into it's quantized value in lower-precision +// pixel format (needed for masking by colour). +wxColour wxBitmap::QuantizeColour(const wxColour& clr) const +{ + pixel_format_t *pf = GetMGLbitmap_t()->pf; + + if ( pf->redAdjust == 0 && pf->greenAdjust == 0 && pf->blueAdjust == 0 ) + return clr; + else + return wxColour((unsigned char)((clr.Red() >> pf->redAdjust) << pf->redAdjust), + (unsigned char)((clr.Green() >> pf->greenAdjust) << pf->greenAdjust), + (unsigned char)((clr.Blue() >> pf->blueAdjust) << pf->blueAdjust)); +} //----------------------------------------------------------------------------- @@ -674,17 +560,21 @@ public: wxMGLBitmapHandler(wxBitmapType type, const wxString& extension, const wxString& name); - virtual bool Create(wxBitmap *bitmap, void *data, long flags, - int width, int height, int depth = 1) - { return FALSE; } + virtual bool Create(wxBitmap *WXUNUSED(bitmap), + const void* WXUNUSED(data), + long WXUNUSED(flags), + int WXUNUSED(width), + int WXUNUSED(height), + int WXUNUSED(depth) = 1) + { return false; } virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags, int desiredWidth, int desiredHeight); - virtual bool SaveFile(const wxBitmap *bitmap, const wxString& name, + virtual bool SaveFile(const wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL); }; -wxMGLBitmapHandler::wxMGLBitmapHandler(wxBitmapType type, +wxMGLBitmapHandler::wxMGLBitmapHandler(wxBitmapType type, const wxString& extension, const wxString& name) : wxBitmapHandler() @@ -694,16 +584,16 @@ wxMGLBitmapHandler::wxMGLBitmapHandler(wxBitmapType type, SetExtension(extension); } -bool wxMGLBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, - long flags, - int WXUNUSED(desiredWidth), +bool wxMGLBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, + long flags, + int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight)) { int width, height, bpp; pixel_format_t pf; wxString fullname; wxMemoryDC dc; - + switch (flags) { case wxBITMAP_TYPE_BMP_RESOURCE: @@ -715,52 +605,52 @@ bool wxMGLBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, default: fullname= name; break; - } + } switch (flags) { case wxBITMAP_TYPE_BMP: case wxBITMAP_TYPE_BMP_RESOURCE: if ( !MGL_getBitmapSize(fullname.mb_str(), &width, &height, &bpp, &pf) ) - return FALSE; + return false; bitmap->Create(width, height, -1); - if ( !bitmap->Ok() ) return FALSE; + if ( !bitmap->IsOk() ) return false; dc.SelectObject(*bitmap); if ( !dc.GetMGLDC()->loadBitmapIntoDC(fullname.mb_str(), 0, 0, TRUE) ) - return FALSE; + return false; break; case wxBITMAP_TYPE_JPEG: case wxBITMAP_TYPE_JPEG_RESOURCE: if ( !MGL_getJPEGSize(fullname.mb_str(), &width, &height, &bpp, &pf) ) - return FALSE; + return false; bitmap->Create(width, height, -1); - if ( !bitmap->Ok() ) return FALSE; + if ( !bitmap->IsOk() ) return false; dc.SelectObject(*bitmap); if ( !dc.GetMGLDC()->loadJPEGIntoDC(fullname.mb_str(), 0, 0, TRUE) ) - return FALSE; + return false; break; case wxBITMAP_TYPE_PNG: case wxBITMAP_TYPE_PNG_RESOURCE: if ( !MGL_getPNGSize(fullname.mb_str(), &width, &height, &bpp, &pf) ) - return FALSE; + return false; bitmap->Create(width, height, -1); - if ( !bitmap->Ok() ) return FALSE; + if ( !bitmap->IsOk() ) return false; dc.SelectObject(*bitmap); if ( !dc.GetMGLDC()->loadPNGIntoDC(fullname.mb_str(), 0, 0, TRUE) ) - return FALSE; + return false; break; case wxBITMAP_TYPE_PCX: case wxBITMAP_TYPE_PCX_RESOURCE: if ( !MGL_getPCXSize(fullname.mb_str(), &width, &height, &bpp) ) - return FALSE; + return false; bitmap->Create(width, height, -1); - if ( !bitmap->Ok() ) return FALSE; + if ( !bitmap->IsOk() ) return false; dc.SelectObject(*bitmap); if ( !dc.GetMGLDC()->loadPCXIntoDC(fullname.mb_str(), 0, 0, TRUE) ) - return FALSE; + return false; break; default: @@ -768,10 +658,10 @@ bool wxMGLBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, break; } - return TRUE; + return true; } -bool wxMGLBitmapHandler::SaveFile(const wxBitmap *bitmap, const wxString& name, +bool wxMGLBitmapHandler::SaveFile(const wxBitmap *bitmap, const wxString& name, int type, const wxPalette * WXUNUSED(palette)) { wxMemoryDC mem; @@ -779,32 +669,27 @@ bool wxMGLBitmapHandler::SaveFile(const wxBitmap *bitmap, const wxString& name, int w = bitmap->GetWidth(), h = bitmap->GetHeight(); - mem.SelectObject(*bitmap); + mem.SelectObjectAsSource(*bitmap); tdc = mem.GetMGLDC(); switch (type) { case wxBITMAP_TYPE_BMP: - return tdc->saveBitmapFromDC(name.mb_str(), 0, 0, w, h); - break; + return (bool)tdc->saveBitmapFromDC(name.mb_str(), 0, 0, w, h); case wxBITMAP_TYPE_JPEG: - return tdc->saveJPEGFromDC(name.mb_str(), 0, 0, w, h, 75); - break; + return (bool)tdc->saveJPEGFromDC(name.mb_str(), 0, 0, w, h, 75); case wxBITMAP_TYPE_PNG: - return tdc->savePNGFromDC(name.mb_str(), 0, 0, w, h); - break; + return (bool)tdc->savePNGFromDC(name.mb_str(), 0, 0, w, h); case wxBITMAP_TYPE_PCX: - return tdc->savePCXFromDC(name.mb_str(), 0, 0, w, h); - break; - default: - return FALSE; - break; + return (bool)tdc->savePCXFromDC(name.mb_str(), 0, 0, w, h); } + + return false; } -// let's handle PNGs in special way because they have alpha channel +// let's handle PNGs in special way because they have alpha channel // which we can access via bitmap_t most easily class wxPNGBitmapHandler: public wxMGLBitmapHandler { @@ -817,8 +702,8 @@ public: int desiredWidth, int desiredHeight); }; -bool wxPNGBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, - long flags, +bool wxPNGBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, + long flags, int desiredWidth, int desiredHeight) { int width, height, bpp; @@ -831,30 +716,30 @@ bool wxPNGBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, fullname = name; if ( !MGL_getPNGSize(fullname.mb_str(), &width, &height, &bpp, &pf) ) - return FALSE; + return false; if ( bpp != 32 ) { // We can load ordinary PNGs faster with 'normal' MGL handler. // Only RGBA PNGs need to be processed in special way because // we have to convert alpha channel to mask - return wxMGLBitmapHandler::LoadFile(bitmap, name, flags, + return wxMGLBitmapHandler::LoadFile(bitmap, name, flags, desiredWidth, desiredHeight); } - + bitmap_t *bmp = MGL_loadPNG(fullname.mb_str(), TRUE); - - if ( bmp == NULL ) return FALSE; + + if ( bmp == NULL ) return false; bitmap->Create(bmp->width, bmp->height, -1); - if ( !bitmap->Ok() ) return FALSE; - + if ( !bitmap->IsOk() ) return false; + // convert bmp to display's depth and write it to *bitmap: wxMemoryDC dc; dc.SelectObject(*bitmap); dc.GetMGLDC()->putBitmap(0, 0, bmp, MGL_REPLACE_MODE); dc.SelectObject(wxNullBitmap); - + // create mask, if bmp contains alpha channel (ARGB format): if ( bmp->bitsPerPixel == 32 ) { @@ -865,8 +750,8 @@ bool wxPNGBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, s = ((wxUint32*)bmp->surface) + y * bmp->bytesPerLine/4; for (x = 0; x < bmp->width; x++, s ++) { - if ( ((((*s) >> bmp->pf->rsvdPos) & bmp->pf->rsvdMask) - << bmp->pf->rsvdAdjust) < 128 ) + if ( ((((*s) >> bmp->pf->alphaPos) & bmp->pf->alphaMask) + << bmp->pf->alphaAdjust) < 128 ) *s = 0; else *s = 0x00FFFFFF; // white @@ -878,10 +763,10 @@ bool wxPNGBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, dc.SelectObject(wxNullBitmap); bitmap->SetMask(new wxMask(mask)); } - + MGL_unloadBitmap(bmp); - - return TRUE; + + return true; } @@ -892,18 +777,22 @@ class wxICOBitmapHandler: public wxBitmapHandler public: wxICOBitmapHandler(wxBitmapType type, const wxString& extension, const wxString& name); - - virtual bool Create(wxBitmap *bitmap, void *data, long flags, - int width, int height, int depth = 1) - { return FALSE; } - + + virtual bool Create(wxBitmap *WXUNUSED(bitmap), + const void* WXUNUSED(data), + long WXUNUSED(flags), + int WXUNUSED(width), + int WXUNUSED(height), + int WXUNUSED(depth) = 1) + { return false; } + virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags, int desiredWidth, int desiredHeight); - virtual bool SaveFile(const wxBitmap *bitmap, const wxString& name, + virtual bool SaveFile(const wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL); }; -wxICOBitmapHandler::wxICOBitmapHandler(wxBitmapType type, +wxICOBitmapHandler::wxICOBitmapHandler(wxBitmapType type, const wxString& extension, const wxString& name) : wxBitmapHandler() @@ -913,9 +802,9 @@ wxICOBitmapHandler::wxICOBitmapHandler(wxBitmapType type, SetExtension(extension); } -bool wxICOBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, - long flags, - int WXUNUSED(desiredWidth), +bool wxICOBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, + long flags, + int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight)) { icon_t *icon = NULL; @@ -923,10 +812,10 @@ bool wxICOBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, if ( flags == wxBITMAP_TYPE_ICO_RESOURCE ) icon = MGL_loadIcon(wxString(name + wxT(".ico")).mb_str(), TRUE); - else + else icon = MGL_loadIcon(name.mb_str(), TRUE); - if ( icon == NULL ) return FALSE; + if ( icon == NULL ) return false; bitmap->Create(icon->xorMask.width, icon->xorMask.height); @@ -946,18 +835,20 @@ bool wxICOBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, dc->clearDevice(); dc->putMonoImage(0, 0, icon->xorMask.width, icon->byteWidth, icon->xorMask.height, (void*)icon->andMask); - + bitmap->SetMask(new wxMask(mask)); MGL_unloadIcon(icon); - - return TRUE; + + return true; } -bool wxICOBitmapHandler::SaveFile(const wxBitmap *bitmap, const wxString& name, - int type, const wxPalette * WXUNUSED(palette)) +bool wxICOBitmapHandler::SaveFile(const wxBitmap *WXUNUSED(bitmap), + const wxString& WXUNUSED(name), + int WXUNUSED(type), + const wxPalette * WXUNUSED(palette)) { - return FALSE; + return false; }