Combine two wxImage-to-pixmap creation functions into one.

Use consistent method for creating mono bitmap in wxBitmap and wxMask.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@40607 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Paul Cornett
2006-08-14 06:26:35 +00:00
parent 8f3773fdfd
commit 5ac1d44aa4
2 changed files with 99 additions and 209 deletions

View File

@@ -78,81 +78,55 @@ bool wxMask::Create( const wxBitmap& bitmap,
const int w = bitmap.GetWidth();
const int h = bitmap.GetHeight();
m_bitmap = gdk_pixmap_new(wxGetRootWindow()->window, w, h, 1);
GdkGC *gc = gdk_gc_new( m_bitmap );
GdkColor color;
color.pixel = 1;
gdk_gc_set_foreground( gc, &color );
gdk_draw_rectangle(m_bitmap, gc, true, 0, 0, w, h);
unsigned char red = colour.Red();
unsigned char green = colour.Green();
unsigned char blue = colour.Blue();
GdkImage* image = NULL;
wxByte* data = NULL;
guint32 mask_pixel = 1;
int rowpadding = 0;
int data_inc = 0;
// create mask as XBM format bitmap
// one bit per pixel, each row starts on a byte boundary
const size_t out_size = size_t((w + 7) / 8) * unsigned(h);
wxByte* out = new wxByte[out_size];
// set bits are white
memset(out, 0xff, out_size);
unsigned bit_index = 0;
if (bitmap.HasPixbuf())
{
const wxByte r_mask = colour.Red();
const wxByte g_mask = colour.Green();
const wxByte b_mask = colour.Blue();
GdkPixbuf* pixbuf = bitmap.GetPixbuf();
data = gdk_pixbuf_get_pixels(pixbuf);
data_inc = 3 + int(gdk_pixbuf_get_has_alpha(pixbuf) != 0);
rowpadding = gdk_pixbuf_get_rowstride(pixbuf) - data_inc * w;
const wxByte* in = gdk_pixbuf_get_pixels(pixbuf);
const int inc = 3 + int(gdk_pixbuf_get_has_alpha(pixbuf) != 0);
const int rowpadding = gdk_pixbuf_get_rowstride(pixbuf) - inc * w;
for (int y = 0; y < h; y++, in += rowpadding)
{
for (int x = 0; x < w; x++, in += inc, bit_index++)
if (in[0] == r_mask && in[1] == g_mask && in[2] == b_mask)
out[bit_index >> 3] ^= 1 << (bit_index & 7);
// move index to next byte boundary
bit_index = (bit_index + 7) & ~7u;
}
}
else
{
image = gdk_drawable_get_image(bitmap.GetPixmap(), 0, 0, w, h);
GdkImage* image = gdk_drawable_get_image(bitmap.GetPixmap(), 0, 0, w, h);
GdkColormap* colormap = gdk_image_get_colormap(image);
guint32 mask_pixel = 1;
if (colormap != NULL)
{
wxColor c(colour);
c.CalcPixel(colormap);
mask_pixel = c.GetPixel();
}
}
color.pixel = 0;
gdk_gc_set_foreground( gc, &color );
for (int y = 0; y < h; y++)
{
int start_x = -1;
int x;
for (x = 0; x < w; x++)
for (int y = 0; y < h; y++)
{
bool isMask;
if (image != NULL)
isMask = gdk_image_get_pixel(image, x, y) == mask_pixel;
else
{
isMask = data[0] == red && data[1] == green && data[2] == blue;
data += data_inc;
}
if (isMask)
{
if (start_x == -1)
start_x = x;
}
else
{
if (start_x != -1)
{
gdk_draw_line(m_bitmap, gc, start_x, y, x - 1, y);
start_x = -1;
}
}
for (int x = 0; x < w; x++, bit_index++)
if (gdk_image_get_pixel(image, x, y) == mask_pixel)
out[bit_index >> 3] ^= 1 << (bit_index & 7);
bit_index = (bit_index + 7) & ~7u;
}
if (start_x != -1)
gdk_draw_line(m_bitmap, gc, start_x, y, x, y);
data += rowpadding;
}
if (image != NULL)
g_object_unref(image);
g_object_unref (gc);
}
m_bitmap = gdk_bitmap_create_from_data(wxGetRootWindow()->window, (char*)out, w, h);
delete[] out;
return true;
}
@@ -500,171 +474,89 @@ bool wxBitmap::CreateFromImage(const wxImage& image, int depth)
return false;
if (depth == 1)
return CreateFromImageAsBitmap(image);
return CreateFromImageAsPixmap(image, depth);
if (image.HasAlpha())
return CreateFromImageAsPixbuf(image);
return CreateFromImageAsPixmap(image);
return CreateFromImageAsPixmap(image, depth);
}
// conversion to mono bitmap:
bool wxBitmap::CreateFromImageAsBitmap(const wxImage& img)
bool wxBitmap::CreateFromImageAsPixmap(const wxImage& image, int depth)
{
// convert alpha channel to mask, if it is present:
wxImage image(img);
image.ConvertAlphaToMask();
int width = image.GetWidth();
int height = image.GetHeight();
SetPixmap( gdk_pixmap_new( wxGetRootWindow()->window, width, height, 1 ) );
// Create picture image
GdkGC* data_gc = gdk_gc_new(M_BMPDATA->m_pixmap);
GdkColor color;
color.pixel = 1;
gdk_gc_set_foreground(data_gc, &color);
gdk_draw_rectangle(M_BMPDATA->m_pixmap, data_gc, true, 0, 0, width, height);
GdkImage* data_image = gdk_drawable_get_image(M_BMPDATA->m_pixmap, 0, 0, width, height);
// Create mask image
GdkImage *mask_image = (GdkImage*) NULL;
GdkGC* mask_gc = NULL;
if (image.HasMask())
const int w = image.GetWidth();
const int h = image.GetHeight();
if (depth == 1)
{
wxMask* mask = new wxMask;
mask->m_bitmap = gdk_pixmap_new( wxGetRootWindow()->window, width, height, 1 );
mask_gc = gdk_gc_new(mask->m_bitmap);
gdk_gc_set_foreground(mask_gc, &color);
gdk_draw_rectangle(mask->m_bitmap, mask_gc, true, 0, 0, width, height);
mask_image = gdk_drawable_get_image(mask->m_bitmap, 0, 0, width, height);
// create XBM format bitmap
SetMask( mask );
// one bit per pixel, each row starts on a byte boundary
const size_t out_size = size_t((w + 7) / 8) * unsigned(h);
wxByte* out = new wxByte[out_size];
// set bits are white
memset(out, 0xff, out_size);
const wxByte* in = image.GetData();
unsigned bit_index = 0;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++, in += 3, bit_index++)
if (in[0] == 255 && in[1] == 255 && in[2] == 255)
out[bit_index >> 3] ^= 1 << (bit_index & 7);
// move index to next byte boundary
bit_index = (bit_index + 7) & ~7u;
}
SetPixmap(gdk_bitmap_create_from_data(wxGetRootWindow()->window, (char*)out, w, h));
delete[] out;
}
else
{
SetPixmap(gdk_pixmap_new(wxGetRootWindow()->window, w, h, depth));
GdkGC* gc = gdk_gc_new(M_BMPDATA->m_pixmap);
gdk_draw_rgb_image(
M_BMPDATA->m_pixmap, gc,
0, 0, w, h,
GDK_RGB_DITHER_NONE, image.GetData(), w * 3);
g_object_unref(gc);
}
int r_mask = image.GetMaskRed();
int g_mask = image.GetMaskGreen();
int b_mask = image.GetMaskBlue();
unsigned char* data = image.GetData();
int index = 0;
for (int y = 0; y < height; y++)
const wxByte* alpha = image.GetAlpha();
if (alpha != NULL || image.HasMask())
{
for (int x = 0; x < width; x++)
{
int r = data[index];
index++;
int g = data[index];
index++;
int b = data[index];
index++;
// create mask as XBM format bitmap
if (mask_image != NULL)
const size_t out_size = size_t((w + 7) / 8) * unsigned(h);
wxByte* out = new wxByte[out_size];
memset(out, 0xff, out_size);
unsigned bit_index = 0;
if (alpha != NULL)
{
for (int y = 0; y < h; y++)
{
if ((r == r_mask) && (b == b_mask) && (g == g_mask))
gdk_image_put_pixel( mask_image, x, y, 0 );
for (int x = 0; x < w; x++, bit_index++)
if (*alpha++ < wxIMAGE_ALPHA_THRESHOLD)
out[bit_index >> 3] ^= 1 << (bit_index & 7);
bit_index = (bit_index + 7) & ~7u;
}
if ((r == 255) && (b == 255) && (g == 255))
gdk_image_put_pixel( data_image, x, y, 0 );
} // for
} // for
// Blit picture
gdk_draw_image( GetPixmap(), data_gc, data_image, 0, 0, 0, 0, width, height );
g_object_unref (data_image);
g_object_unref (data_gc);
// Blit mask
if (mask_image != NULL)
{
gdk_draw_image( GetMask()->GetBitmap(), mask_gc, mask_image, 0, 0, 0, 0, width, height );
g_object_unref (mask_image);
g_object_unref (mask_gc);
}
return true;
}
// conversion to colour bitmap:
bool wxBitmap::CreateFromImageAsPixmap(const wxImage& image)
{
// alpha is handled by CreateFromImageAsPixbuf
wxASSERT(!image.HasAlpha());
int width = image.GetWidth();
int height = image.GetHeight();
SetPixmap( gdk_pixmap_new( wxGetRootWindow()->window, width, height, -1 ) );
GdkGC *gc = gdk_gc_new( GetPixmap() );
gdk_draw_rgb_image( GetPixmap(),
gc,
0, 0,
width, height,
GDK_RGB_DITHER_NONE,
image.GetData(),
width*3 );
g_object_unref (gc);
// Create mask image
if (!image.HasMask())
return true;
wxMask* mask = new wxMask;
mask->m_bitmap = gdk_pixmap_new( wxGetRootWindow()->window, width, height, 1 );
GdkGC* mask_gc = gdk_gc_new(mask->m_bitmap);
GdkColor color;
color.pixel = 1;
gdk_gc_set_foreground(mask_gc, &color);
gdk_draw_rectangle(mask->m_bitmap, mask_gc, true, 0, 0, width, height);
GdkImage* mask_image = gdk_drawable_get_image(mask->m_bitmap, 0, 0, width, height);
SetMask( mask );
int r_mask = image.GetMaskRed();
int g_mask = image.GetMaskGreen();
int b_mask = image.GetMaskBlue();
unsigned char* data = image.GetData();
int index = 0;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
}
else
{
int r = data[index];
index++;
int g = data[index];
index++;
int b = data[index];
index++;
if ((r == r_mask) && (b == b_mask) && (g == g_mask))
gdk_image_put_pixel( mask_image, x, y, 0 );
} // for
} // for
// Blit mask
gdk_draw_image( GetMask()->GetBitmap(), mask_gc, mask_image, 0, 0, 0, 0, width, height );
g_object_unref (mask_image);
g_object_unref (mask_gc);
const wxByte r_mask = image.GetMaskRed();
const wxByte g_mask = image.GetMaskGreen();
const wxByte b_mask = image.GetMaskBlue();
const wxByte* in = image.GetData();
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++, in += 3, bit_index++)
if (in[0] == r_mask && in[1] == g_mask && in[2] == b_mask)
out[bit_index >> 3] ^= 1 << (bit_index & 7);
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);
delete[] out;
}
return true;
}