X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/de6185e212ebc37ff11ff70278e3c4f68419b097..f050bdbd5b69ed1a6752102f0c4c13bc7cb4ed3c:/src/mgl/bitmap.cpp?ds=sidebyside diff --git a/src/mgl/bitmap.cpp b/src/mgl/bitmap.cpp index 7f5df13f1f..3c717d4fe9 100644 --- a/src/mgl/bitmap.cpp +++ b/src/mgl/bitmap.cpp @@ -19,19 +19,25 @@ #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/icon.h" #include "wx/filefn.h" -#include "wx/image.h" -#include "wx/dcmemory.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: //----------------------------------------------------------------------------- @@ -52,128 +58,101 @@ 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((unsigned char)((clr.Red() >> pf->redAdjust) << pf->redAdjust), - (unsigned char)((clr.Green() >> pf->greenAdjust) << pf->greenAdjust), - (unsigned char)((clr.Blue() >> pf->blueAdjust) << pf->blueAdjust)); -} - - - -//----------------------------------------------------------------------------- -// wxMask +// wxBitmapRefData //----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxMask,wxObject) - -wxMask::wxMask() -{ - m_bitmap = NULL; -} - -wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour) +class wxBitmapRefData: public wxGDIRefData { - m_bitmap = NULL; - Create(bitmap, colour); -} +public: + wxBitmapRefData(); + wxBitmapRefData(int width, int height, int bpp); + wxBitmapRefData(const wxBitmapRefData& data); + virtual ~wxBitmapRefData(); -wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex) -{ - m_bitmap = NULL; - Create(bitmap, paletteIndex); -} + virtual bool IsOk() const { return m_bitmap != NULL; } -wxMask::wxMask(const wxBitmap& bitmap) -{ - m_bitmap = NULL; - Create(bitmap); -} + int m_width; + int m_height; + int m_bpp; + wxPalette *m_palette; + wxMask *m_mask; + bitmap_t *m_bitmap; -wxMask::~wxMask() -{ - delete m_bitmap; -} +private: + void DoCreateBitmap(int width, int height, int depth); +}; -bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour) +void wxBitmapRefData::DoCreateBitmap(int width, int height, int depth) { - delete m_bitmap; - m_bitmap = NULL; + m_width = width; + m_height = height; + m_bpp = depth; - 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(); - - wxCHECK_MSG( pal, false, wxT("Cannot create mask from bitmap without palette") ); + m_width = + m_height = + m_bpp = 0; - 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(); - - int m_width; - int m_height; - int m_bpp; - wxPalette *m_palette; - wxMask *m_mask; - bitmap_t *m_bitmap; -}; + DoCreateBitmap(data.m_width, data.m_height, data.m_bpp); -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() @@ -184,25 +163,23 @@ wxBitmapRefData::~wxBitmapRefData() delete m_palette; } + +//----------------------------------------------------------------------------- +// wxBitmap //----------------------------------------------------------------------------- #define M_BMPDATA ((wxBitmapRefData *)m_refData) - -IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandler,wxObject) IMPLEMENT_DYNAMIC_CLASS(wxBitmap,wxBitmapBase) -wxBitmap::wxBitmap(int width, int height, int depth) +wxGDIRefData *wxBitmap::CreateGDIRefData() const { - Create(width, height, depth); + 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) @@ -211,77 +188,19 @@ bool wxBitmap::Create(int width, int height, int depth) wxCHECK_MSG( (width > 0) && (height > 0), false, wxT("invalid bitmap size") ); - pixel_format_t pf_dummy; - pixel_format_t *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: - wxFAIL_MSG(wxT("invalid bitmap depth")); - return false; - } - - 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); 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); - - return true; -} - wxBitmap::wxBitmap(const wxImage& image, int depth) { long width, height; @@ -378,21 +297,6 @@ wxBitmap::wxBitmap(const char bits[], int width, int height, int depth) delete bdc; } -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") ); @@ -416,7 +320,7 @@ int wxBitmap::GetDepth() const wxMask *wxBitmap::GetMask() const { - wxCHECK_MSG( Ok(), (wxMask *) NULL, wxT("invalid bitmap") ); + wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); return M_BMPDATA->m_mask; } @@ -425,6 +329,7 @@ void wxBitmap::SetMask(wxMask *mask) { wxCHECK_RET( Ok(), wxT("invalid bitmap") ); + AllocExclusive(); delete M_BMPDATA->m_mask; M_BMPDATA->m_mask = mask; } @@ -457,7 +362,7 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect& rect) const if ( GetMask() ) { - wxBitmap submask = GetMask()->GetBitmap()->GetSubBitmap(rect); + wxBitmap submask = GetMask()->GetBitmap().GetSubBitmap(rect); ret.SetMask(new wxMask(submask)); } @@ -468,6 +373,7 @@ void wxBitmap::SetMonoPalette(const wxColour& fg, const wxColour& bg) { wxCHECK_RET( Ok(), wxT("invalid bitmap") ); + AllocExclusive(); palette_t *mono = M_BMPDATA->m_bitmap->pal; wxCHECK_RET( M_BMPDATA->m_bpp == 1, wxT("bitmap is not 1bpp") ); @@ -522,7 +428,7 @@ MGLDevCtx *wxBitmap::CreateTmpDC() const bool wxBitmap::LoadFile(const wxString &name, wxBitmapType type) { - UnRef(); + AllocExclusive(); if ( type == wxBITMAP_TYPE_BMP || type == wxBITMAP_TYPE_PNG || type == wxBITMAP_TYPE_PCX || type == wxBITMAP_TYPE_JPEG ) @@ -552,8 +458,6 @@ bool wxBitmap::LoadFile(const wxString &name, wxBitmapType type) } } - m_refData = new wxBitmapRefData(); - return handler->LoadFile(this, name, type, -1, -1); } @@ -593,6 +497,7 @@ void wxBitmap::SetPalette(const wxPalette& palette) wxCHECK_RET( Ok(), wxT("invalid bitmap") ); wxCHECK_RET( GetDepth() > 1 && GetDepth() <= 8, wxT("cannot set palette for bitmap of this depth") ); + AllocExclusive(); delete M_BMPDATA->m_palette; M_BMPDATA->m_palette = NULL; @@ -607,21 +512,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; } @@ -631,6 +536,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)); +} //----------------------------------------------------------------------------- @@ -644,7 +562,7 @@ public: const wxString& extension, const wxString& name); virtual bool Create(wxBitmap *WXUNUSED(bitmap), - void *WXUNUSED(data), + const void* WXUNUSED(data), long WXUNUSED(flags), int WXUNUSED(width), int WXUNUSED(height), @@ -752,7 +670,7 @@ 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) @@ -862,7 +780,7 @@ class wxICOBitmapHandler: public wxBitmapHandler const wxString& extension, const wxString& name); virtual bool Create(wxBitmap *WXUNUSED(bitmap), - void *WXUNUSED(data), + const void* WXUNUSED(data), long WXUNUSED(flags), int WXUNUSED(width), int WXUNUSED(height),