#include "wx/rawbmp.h"
#include "wx/gtk/private/object.h"
+#include "wx/gtk/private.h"
#include <gtk/gtk.h>
m_bitmap = NULL;
}
+wxMask::wxMask(const wxMask& mask)
+{
+ if ( !mask.m_bitmap )
+ {
+ m_bitmap = NULL;
+ return;
+ }
+
+ // create a copy of an existing mask
+ gint w, h;
+ gdk_drawable_get_size(mask.m_bitmap, &w, &h);
+ m_bitmap = gdk_pixmap_new(mask.m_bitmap, w, h, 1);
+
+ wxGtkObject<GdkGC> gc(gdk_gc_new(m_bitmap));
+ gdk_draw_drawable(m_bitmap, gc, mask.m_bitmap, 0, 0, 0, 0, -1, -1);
+}
+
wxMask::wxMask( const wxBitmap& bitmap, const wxColour& colour )
{
m_bitmap = NULL;
InitFromMonoBitmap(bitmap);
}
+wxMask::wxMask(GdkPixmap* bitmap)
+{
+ m_bitmap = bitmap;
+}
+
wxMask::~wxMask()
{
if (m_bitmap)
return true;
}
-GdkBitmap *wxMask::GetBitmap() const
+GdkPixmap* wxMask::GetBitmap() const
{
return m_bitmap;
}
int m_height;
int m_bpp;
bool m_alphaRequested;
+
+private:
+ // We don't provide a copy ctor as copying m_pixmap and m_pixbuf properly
+ // is expensive and we don't want to do it implicitly (and possibly
+ // accidentally). wxBitmap::CloneGDIRefData() which does need to do it does
+ // it explicitly itself.
+ wxDECLARE_NO_COPY_CLASS(wxBitmapRefData);
};
wxBitmapRefData::wxBitmapRefData(int width, int height, int depth)
if (M_BMPDATA->m_pixmap != NULL && mask != NULL)
{
- M_BMPDATA->m_mask = new wxMask;
- M_BMPDATA->m_mask->m_bitmap = mask;
+ M_BMPDATA->m_mask = new wxMask(mask);
+ }
+}
+
+wxBitmap::wxBitmap(GdkPixbuf* pixbuf)
+{
+ if (pixbuf)
+ {
+ wxBitmapRefData* bmpData = new wxBitmapRefData(
+ gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf),
+ gdk_pixbuf_get_n_channels(pixbuf) * 8);
+ m_refData = bmpData;
+ bmpData->m_pixbuf = pixbuf;
}
}
UnRef();
wxCHECK_MSG( image.IsOk(), false, wxT("invalid image") );
- wxCHECK_MSG( depth == -1 || depth == 1, false, wxT("invalid bitmap depth") );
if (image.GetWidth() <= 0 || image.GetHeight() <= 0)
return false;
- // create pixbuf if image has alpha and requested depth is compatible
- if (image.HasAlpha() && (depth == -1 || depth == 32))
+ if (depth == 32 || (depth == -1 && image.HasAlpha()))
return CreateFromImageAsPixbuf(image);
// otherwise create pixmap, if alpha is present it will be converted to mask
bit_index = (bit_index + 7) & ~7u;
}
}
- wxMask* mask = new wxMask;
- mask->m_bitmap = gdk_bitmap_create_from_data(M_BMPDATA->m_pixmap, (char*)out, w, h);
- SetMask(mask);
+ SetMask(new wxMask(gdk_bitmap_create_from_data(M_BMPDATA->m_pixmap, (char*)out, w, h)));
delete[] out;
}
return IsOk();
bool wxBitmap::CreateFromImageAsPixbuf(const wxImage& image)
{
- wxASSERT(image.HasAlpha());
-
int width = image.GetWidth();
int height = image.GetHeight();
for (int y = 0; y < height; y++, out += rowpad)
{
- for (int x = 0; x < width; x++, alpha++, out += 4, in += 3)
+ for (int x = 0; x < width; x++, out += 4, in += 3)
{
out[0] = in[0];
out[1] = in[1];
out[2] = in[2];
- out[3] = *alpha;
+ if (alpha)
+ out[3] = *alpha++;
}
}
rect.y + h <= bmpData->m_height,
ret, wxT("invalid bitmap region"));
- wxBitmapRefData* newRef = new wxBitmapRefData(*bmpData);
+ wxBitmapRefData * const newRef = new wxBitmapRefData(w, h, bmpData->m_bpp);
ret.m_refData = newRef;
- newRef->m_width = w;
- newRef->m_height = h;
if (bmpData->m_pixbuf)
{
newRef->m_pixmap, gc, bmpData->m_pixmap, rect.x, rect.y, 0, 0, w, h);
g_object_unref(gc);
}
- newRef->m_mask = NULL;
- if (bmpData->m_mask && bmpData->m_mask->m_bitmap)
+ GdkPixmap* mask = NULL;
+ if (bmpData->m_mask)
+ mask = bmpData->m_mask->GetBitmap();
+ if (mask)
{
- GdkPixmap* sub_mask = gdk_pixmap_new(bmpData->m_mask->m_bitmap, w, h, 1);
- newRef->m_mask = new wxMask;
- newRef->m_mask->m_bitmap = sub_mask;
+ GdkPixmap* sub_mask = gdk_pixmap_new(mask, w, h, 1);
+ newRef->m_mask = new wxMask(sub_mask);
GdkGC* gc = gdk_gc_new(sub_mask);
gdk_draw_drawable(
- sub_mask, gc, bmpData->m_mask->m_bitmap, rect.x, rect.y, 0, 0, w, h);
+ sub_mask, gc, mask, rect.x, rect.y, 0, 0, w, h);
g_object_unref(gc);
}
default: break;
}
return type_name &&
- gdk_pixbuf_save(GetPixbuf(), name.fn_str(), type_name, NULL, NULL);
+ gdk_pixbuf_save(GetPixbuf(), wxGTK_CONV_FN(name), type_name, NULL, NULL);
}
bool wxBitmap::LoadFile( const wxString &name, wxBitmapType type )
else
#endif
{
- UnRef();
- GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file(name.fn_str(), NULL);
- if (pixbuf)
- SetPixbuf(pixbuf);
+ wxUnusedVar(type); // The type is detected automatically by GDK.
+
+ *this = wxBitmap(gdk_pixbuf_new_from_file(wxGTK_CONV_FN(name), NULL));
}
return IsOk();
if (bmpData->m_pixbuf)
{
+ GdkPixmap* pixmap = NULL;
GdkPixmap** mask_pixmap = NULL;
if (gdk_pixbuf_get_has_alpha(bmpData->m_pixbuf))
{
// make new mask from alpha
- delete bmpData->m_mask;
- bmpData->m_mask = new wxMask;
- mask_pixmap = &bmpData->m_mask->m_bitmap;
+ mask_pixmap = &pixmap;
}
gdk_pixbuf_render_pixmap_and_mask(
bmpData->m_pixbuf, &bmpData->m_pixmap, mask_pixmap, 128);
+ if (pixmap)
+ {
+ delete bmpData->m_mask;
+ bmpData->m_mask = new wxMask(pixmap);
+ }
}
else
{
const int h = bmpData->m_height;
GdkPixmap* mask = NULL;
if (bmpData->m_mask)
- mask = bmpData->m_mask->m_bitmap;
+ mask = bmpData->m_mask->GetBitmap();
const bool useAlpha = bmpData->m_alphaRequested || mask;
bmpData->m_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, useAlpha, 8, w, h);
if (bmpData->m_pixmap)
return M_BMPDATA->m_pixbuf != NULL;
}
-void wxBitmap::SetPixbuf(GdkPixbuf* pixbuf)
-{
- UnRef();
-
- if (!pixbuf)
- return;
-
- int depth = -1;
- if (gdk_pixbuf_get_has_alpha(pixbuf))
- depth = 32;
- m_refData = new wxBitmapRefData(
- gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), depth);
-
- M_BMPDATA->m_pixbuf = pixbuf;
-}
-
void wxBitmap::PurgeOtherRepresentations(wxBitmap::Representation keep)
{
if (keep == Pixmap && HasPixbuf())
wxGDIRefData* wxBitmap::CloneGDIRefData(const wxGDIRefData* data) const
{
const wxBitmapRefData* oldRef = static_cast<const wxBitmapRefData*>(data);
- wxBitmapRefData* newRef = new wxBitmapRefData(*oldRef);
+ wxBitmapRefData * const newRef = new wxBitmapRefData(oldRef->m_width,
+ oldRef->m_height,
+ oldRef->m_bpp);
if (oldRef->m_pixmap != NULL)
{
newRef->m_pixmap = gdk_pixmap_new(
}
if (oldRef->m_mask != NULL)
{
- newRef->m_mask = new wxMask;
- newRef->m_mask->m_bitmap = gdk_pixmap_new(
- oldRef->m_mask->m_bitmap, oldRef->m_width, oldRef->m_height, 1);
- wxGtkObject<GdkGC> gc(gdk_gc_new(newRef->m_mask->m_bitmap));
- gdk_draw_drawable(newRef->m_mask->m_bitmap,
- gc, oldRef->m_mask->m_bitmap, 0, 0, 0, 0, -1, -1);
+ newRef->m_mask = new wxMask(*oldRef->m_mask);
}
return newRef;