Further work on bitmap drawing and rescaling.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_4_BRANCH@24132 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2003-10-09 00:24:12 +00:00
parent 5d0f365456
commit 5e4e624b51
4 changed files with 372 additions and 240 deletions

View File

@@ -1047,7 +1047,7 @@ wxBitmap wxBitmap::Rescale( int clipx, int clipy, int clipwidth, int clipheight,
tabley[y] = (int) floor(0.5 + scy * (y+clipy));
// Main rescaling routine starts here
for(int h=0; h<height; h++)
for (int h = 0; h < height; h++)
{
char outbyte = 0;
@@ -1080,23 +1080,65 @@ wxBitmap wxBitmap::Rescale( int clipx, int clipy, int clipwidth, int clipheight,
// do not forget the last byte
if (bpp == 1)
dst[h*dstbyteperline+width/8] = ~outbyte;
dst[h*dstbyteperline+width/8] = ~outbyte;
}
free( tablex );
free( tabley );
gdk_image_destroy( img );
if (gc) gdk_gc_unref( gc );
if (bpp == 1)
{
bmp = wxBitmap( (const char *)dst, width, height, 1 );
wxMask* bmask= new wxMask(bmp);
bmp.SetMask(bmask);
free(dst);
free( dst );
}
if (GetMask())
{
bpp = 1;
dstbyteperline = width/8*bpp;
if (width*bpp % 8 != 0)
dstbyteperline++;
dst = (char*) malloc(dstbyteperline*height);
img = gdk_image_get( GetMask()->GetBitmap(), 0, 0, GetWidth(), GetHeight() );
for (int h = 0; h < height; h++)
{
char outbyte = 0;
for (int w=0; w<width; w++)
{
guint32 pixval = gdk_image_get_pixel( img, tablex[w], tabley[h] );
if (pixval)
{
char bit=1;
char shift = bit << w % 8;
outbyte |= shift;
}
if ((w+1)%8==0)
{
dst[h*dstbyteperline+w/8]=~outbyte;
outbyte = 0;
}
}
// do not forget the last byte
if (bpp == 1)
dst[h*dstbyteperline+width/8] = ~outbyte;
}
wxBitmap mask_bmp( (const char *)dst, width, height, 1 );
wxMask* mask = new wxMask(mask_bmp);
bmp.SetMask(mask);
free( dst );
gdk_image_destroy( img );
}
return bmp;
free( tablex );
free( tabley );
return bmp;
}

View File

@@ -89,48 +89,42 @@ void gdk_wx_draw_bitmap(GdkDrawable *drawable,
gint width,
gint height)
{
gint src_width, src_height;
#ifndef __WXGTK20__
GdkWindowPrivate *drawable_private;
GdkWindowPrivate *src_private;
GdkGCPrivate *gc_private;
#endif
g_return_if_fail (drawable != NULL);
g_return_if_fail (src != NULL);
g_return_if_fail (gc != NULL);
#ifdef __WXGTK20__
// This doesn't seem to exist for bitmaps (1-bit)
// if (GDK_WINDOW_DESTROYED(drawable) || GDK_WINDOW_DESTROYED(src))
// return;
gint src_width, src_height;
gdk_drawable_get_size(src, &src_width, &src_height);
#else
drawable_private = (GdkWindowPrivate*) drawable;
src_private = (GdkWindowPrivate*) src;
if (drawable_private->destroyed || src_private->destroyed)
return;
src_width = src_private->width;
src_height = src_private->height;
gc_private = (GdkGCPrivate*) gc;
#endif
if (width == -1) width = src_width;
if (height == -1) height = src_height;
#ifdef __WXGTK20__
XCopyPlane( GDK_WINDOW_XDISPLAY(drawable),
GDK_WINDOW_XID(src),
GDK_WINDOW_XID(drawable),
GDK_GC_XGC(gc),
xsrc, ysrc,
width, height,
xdest, ydest,
0, 0,
1 );
#else
GdkWindowPrivate *drawable_private;
GdkWindowPrivate *src_private;
GdkGCPrivate *gc_private;
drawable_private = (GdkWindowPrivate*) drawable;
src_private = (GdkWindowPrivate*) src;
if (drawable_private->destroyed || src_private->destroyed)
return;
gint src_width = src_private->width;
gint src_height = src_private->height;
gc_private = (GdkGCPrivate*) gc;
if (width == -1) width = src_width;
if (height == -1) height = src_height;
XCopyPlane( drawable_private->xdisplay,
src_private->xwindow,
drawable_private->xwindow,
@@ -1041,7 +1035,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
bool is_mono = (bitmap.GetBitmap() != NULL);
/* scale/translate size and position */
// scale/translate size and position
int xx = XLOG2DEV(x);
int yy = YLOG2DEV(y);
@@ -1056,7 +1050,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
int ww = XLOG2DEVREL(w);
int hh = YLOG2DEVREL(h);
/* compare to current clipping region */
// compare to current clipping region
if (!m_currentClippingRegion.IsNull())
{
wxRegion tmp( xx,yy,ww,hh );
@@ -1065,7 +1059,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
return;
}
/* scale bitmap if required */
// scale bitmap if required
wxBitmap use_bitmap;
if ((w != ww) || (h != hh))
{
@@ -1081,63 +1075,77 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
use_bitmap = bitmap;
}
/* apply mask if any */
// apply mask if any
GdkBitmap *mask = (GdkBitmap *) NULL;
if (use_bitmap.GetMask()) mask = use_bitmap.GetMask()->GetBitmap();
if (useMask && mask)
GdkBitmap *new_mask = (GdkBitmap*) NULL;
if (useMask && mask)
{
if (!m_currentClippingRegion.IsNull())
{
GdkBitmap *new_mask = (GdkBitmap*) NULL;
#ifndef __WXGTK20__ // TODO fix crash
if (!m_currentClippingRegion.IsNull())
{
GdkColor col;
new_mask = gdk_pixmap_new( wxGetRootWindow()->window, ww, hh, 1 );
GdkGC *gc = gdk_gc_new( new_mask );
col.pixel = 0;
gdk_gc_set_foreground( gc, &col );
gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh );
col.pixel = 0;
gdk_gc_set_background( gc, &col );
col.pixel = 1;
gdk_gc_set_foreground( gc, &col );
gdk_gc_set_clip_region( gc, m_currentClippingRegion.GetRegion() );
gdk_gc_set_clip_origin( gc, -xx, -yy );
gdk_gc_set_fill( gc, GDK_OPAQUE_STIPPLED );
gdk_gc_set_stipple( gc, mask );
gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh );
gdk_gc_unref( gc );
}
#endif
if (is_mono)
{
if (new_mask)
gdk_gc_set_clip_mask( m_textGC, new_mask );
else
gdk_gc_set_clip_mask( m_textGC, mask );
gdk_gc_set_clip_origin( m_textGC, xx, yy );
}
else
{
if (new_mask)
gdk_gc_set_clip_mask( m_penGC, new_mask );
else
gdk_gc_set_clip_mask( m_penGC, mask );
gdk_gc_set_clip_origin( m_penGC, xx, yy );
}
if (new_mask)
gdk_bitmap_unref( new_mask );
GdkColor col;
new_mask = gdk_pixmap_new( wxGetRootWindow()->window, ww, hh, 1 );
GdkGC *gc = gdk_gc_new( new_mask );
col.pixel = 0;
gdk_gc_set_foreground( gc, &col );
gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh );
col.pixel = 0;
gdk_gc_set_background( gc, &col );
col.pixel = 1;
gdk_gc_set_foreground( gc, &col );
gdk_gc_set_clip_region( gc, m_currentClippingRegion.GetRegion() );
gdk_gc_set_clip_origin( gc, -xx, -yy );
gdk_gc_set_fill( gc, GDK_OPAQUE_STIPPLED );
gdk_gc_set_stipple( gc, mask );
gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh );
gdk_gc_unref( gc );
}
if (is_mono)
{
if (new_mask)
gdk_gc_set_clip_mask( m_textGC, new_mask );
else
gdk_gc_set_clip_mask( m_textGC, mask );
gdk_gc_set_clip_origin( m_textGC, xx, yy );
}
else
{
if (new_mask)
gdk_gc_set_clip_mask( m_penGC, new_mask );
else
gdk_gc_set_clip_mask( m_penGC, mask );
gdk_gc_set_clip_origin( m_penGC, xx, yy );
}
}
/* Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
drawing a mono-bitmap (XBitmap) we use the current text GC */
// Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
// drawing a mono-bitmap (XBitmap) we use the current text GC
if (is_mono)
{
#ifdef __WXGTK20__
GdkPixmap *bitmap = gdk_pixmap_new( wxGetRootWindow()->window, ww, hh, -1 );
GdkGC *gc = gdk_gc_new( bitmap );
gdk_gc_set_foreground( gc, m_textForegroundColour.GetColor() );
gdk_gc_set_background( gc, m_textBackgroundColour.GetColor() );
gdk_wx_draw_bitmap( bitmap, gc, use_bitmap.GetBitmap(), 0, 0, 0, 0, -1, -1 );
gdk_draw_drawable( m_window, m_textGC, bitmap, 0, 0, xx, yy, -1, -1 );
gdk_bitmap_unref( bitmap );
gdk_gc_unref( gc );
#else
gdk_wx_draw_bitmap( m_window, m_textGC, use_bitmap.GetBitmap(), 0, 0, xx, yy, -1, -1 );
#endif
}
else
{
gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), 0, 0, xx, yy, -1, -1 );
}
/* remove mask again if any */
// remove mask again if any
if (useMask && mask)
{
if (is_mono)
@@ -1155,6 +1163,9 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() );
}
}
if (new_mask)
gdk_bitmap_unref( new_mask );
}
bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
@@ -1165,22 +1176,15 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
bool useMask,
wxCoord xsrcMask, wxCoord ysrcMask )
{
/* this is the nth try to get this utterly useless function to
work. it now completely ignores the scaling or translation
of the source dc, but scales correctly on the target dc and
knows about possible mask information in a memory dc. */
wxCHECK_MSG( Ok(), FALSE, wxT("invalid window dc") );
wxCHECK_MSG( source, FALSE, wxT("invalid source dc") );
if (!m_window) return FALSE;
#if 1
// transform the source DC coords to the device ones
xsrc = source->XLOG2DEV(xsrc);
ysrc = source->YLOG2DEV(ysrc);
#endif
wxClientDC *srcDC = (wxClientDC*)source;
wxMemoryDC *memDC = (wxMemoryDC*)source;
@@ -1188,10 +1192,11 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
bool use_bitmap_method = FALSE;
bool is_mono = FALSE;
/* TODO: use the mask origin when drawing transparently */
// TODO: use the mask origin when drawing transparently
if (xsrcMask == -1 && ysrcMask == -1)
{
xsrcMask = xsrc; ysrcMask = ysrc;
xsrcMask = xsrc;
ysrcMask = ysrc;
}
if (srcDC->m_isMemDC)
@@ -1200,34 +1205,34 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
is_mono = (memDC->m_selected.GetDepth() == 1);
/* we use the "XCopyArea" way to copy a memory dc into
y different window if the memory dc BOTH
a) doesn't have any mask or its mask isn't used
b) it is clipped
c) is not 1-bit */
// we use the "XCopyArea" way to copy a memory dc into
// a different window if the memory dc BOTH
// a) doesn't have any mask or its mask isn't used
// b) it is clipped
// c) is not 1-bit
if (useMask && (memDC->m_selected.GetMask()))
{
/* we HAVE TO use the direct way for memory dcs
that have mask since the XCopyArea doesn't know
about masks */
// we HAVE TO use the direct way for memory dcs
// that have mask since the XCopyArea doesn't know
// about masks
use_bitmap_method = TRUE;
}
else if (is_mono)
{
/* we HAVE TO use the direct way for memory dcs
that are bitmaps because XCopyArea doesn't cope
with different bit depths */
// we HAVE TO use the direct way for memory dcs
// that are bitmaps because XCopyArea doesn't cope
// with different bit depths
use_bitmap_method = TRUE;
}
else if ((xsrc == 0) && (ysrc == 0) &&
(width == memDC->m_selected.GetWidth()) &&
(height == memDC->m_selected.GetHeight()))
{
/* we SHOULD use the direct way if all of the bitmap
in the memory dc is copied in which case XCopyArea
wouldn't be able able to boost performace by reducing
the area to be scaled */
// we SHOULD use the direct way if all of the bitmap
// in the memory dc is copied in which case XCopyArea
// wouldn't be able able to boost performace by reducing
// the area to be scaled
use_bitmap_method = TRUE;
}
else
@@ -1284,7 +1289,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
if ((bm_width != bm_ww) || (bm_height != bm_hh))
{
use_bitmap = memDC->m_selected.Rescale(cx-xx,cy-yy,cw,ch,bm_ww,bm_hh);
use_bitmap = memDC->m_selected.Rescale(cx-xx,cy-yy,cw,ch,bm_ww,bm_hh);
}
else
{
@@ -1296,10 +1301,10 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
GdkBitmap *mask = (GdkBitmap *) NULL;
if (use_bitmap.GetMask()) mask = use_bitmap.GetMask()->GetBitmap();
GdkBitmap *new_mask = (GdkBitmap*) NULL;
if (useMask && mask)
{
GdkBitmap *new_mask = (GdkBitmap*) NULL;
#ifndef __WXGTK20__ // TODO fix crash
if (!m_currentClippingRegion.IsNull())
{
GdkColor col;
@@ -1320,7 +1325,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, bm_ww, bm_hh );
gdk_gc_unref( gc );
}
#endif
if (is_mono)
{
if (new_mask)
@@ -1339,21 +1344,36 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
// was: gdk_gc_set_clip_origin( m_penGC, xx, yy );
gdk_gc_set_clip_origin( m_penGC, cx, cy );
}
if (new_mask)
gdk_bitmap_unref( new_mask );
}
/* Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
drawing a mono-bitmap (XBitmap) we use the current text GC */
// Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
// drawing a mono-bitmap (XBitmap) we use the current text GC
if (is_mono)
{
#ifdef __WXGTK20__
GdkPixmap *bitmap = gdk_pixmap_new( wxGetRootWindow()->window, bm_ww, bm_hh, -1 );
GdkGC *gc = gdk_gc_new( bitmap );
gdk_gc_set_foreground( gc, m_textForegroundColour.GetColor() );
gdk_gc_set_background( gc, m_textBackgroundColour.GetColor() );
gdk_wx_draw_bitmap( bitmap, gc, use_bitmap.GetBitmap(), 0, 0, 0, 0, -1, -1 );
gdk_draw_drawable( m_window, m_textGC, bitmap, xsrc, ysrc, cx, cy, cw, ch );
gdk_bitmap_unref( bitmap );
gdk_gc_unref( gc );
#else
// was: gdk_wx_draw_bitmap( m_window, m_textGC, use_bitmap.GetBitmap(), xsrc, ysrc, xx, yy, ww, hh );
gdk_wx_draw_bitmap( m_window, m_textGC, use_bitmap.GetBitmap(), xsrc, ysrc, cx, cy, cw, ch );
#endif
}
else
{
// was: gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), xsrc, ysrc, xx, yy, ww, hh );
gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), xsrc, ysrc, cx, cy, cw, ch );
}
/* remove mask again if any */
// remove mask again if any
if (useMask && mask)
{
if (is_mono)
@@ -1371,8 +1391,11 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() );
}
}
if (new_mask)
gdk_bitmap_unref( new_mask );
}
else /* use_bitmap_method */
else // use_bitmap_method
{
if ((width != ww) || (height != hh))
{
@@ -1382,7 +1405,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
wxCoord cx,cy,cw,ch;
tmp.GetBox(cx,cy,cw,ch);
// rescale bitmap
// rescale bitmap
wxBitmap bitmap = memDC->m_selected.Rescale( cx-xx, cy-yy, cw, ch, ww, hh );
// draw scaled bitmap
@@ -1391,9 +1414,9 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
}
else
{
/* No scaling and not a memory dc with a mask either */
// No scaling and not a memory dc with a mask either
/* copy including child window contents */
// copy including child window contents
gdk_gc_set_subwindow( m_penGC, GDK_INCLUDE_INFERIORS );
gdk_window_copy_area( m_window, m_penGC, xx, yy,
srcDC->GetWindow(),
@@ -1403,6 +1426,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
}
SetLogicalFunction( old_logical_func );
return TRUE;
}

View File

@@ -1047,7 +1047,7 @@ wxBitmap wxBitmap::Rescale( int clipx, int clipy, int clipwidth, int clipheight,
tabley[y] = (int) floor(0.5 + scy * (y+clipy));
// Main rescaling routine starts here
for(int h=0; h<height; h++)
for (int h = 0; h < height; h++)
{
char outbyte = 0;
@@ -1080,23 +1080,65 @@ wxBitmap wxBitmap::Rescale( int clipx, int clipy, int clipwidth, int clipheight,
// do not forget the last byte
if (bpp == 1)
dst[h*dstbyteperline+width/8] = ~outbyte;
dst[h*dstbyteperline+width/8] = ~outbyte;
}
free( tablex );
free( tabley );
gdk_image_destroy( img );
if (gc) gdk_gc_unref( gc );
if (bpp == 1)
{
bmp = wxBitmap( (const char *)dst, width, height, 1 );
wxMask* bmask= new wxMask(bmp);
bmp.SetMask(bmask);
free(dst);
free( dst );
}
if (GetMask())
{
bpp = 1;
dstbyteperline = width/8*bpp;
if (width*bpp % 8 != 0)
dstbyteperline++;
dst = (char*) malloc(dstbyteperline*height);
img = gdk_image_get( GetMask()->GetBitmap(), 0, 0, GetWidth(), GetHeight() );
for (int h = 0; h < height; h++)
{
char outbyte = 0;
for (int w=0; w<width; w++)
{
guint32 pixval = gdk_image_get_pixel( img, tablex[w], tabley[h] );
if (pixval)
{
char bit=1;
char shift = bit << w % 8;
outbyte |= shift;
}
if ((w+1)%8==0)
{
dst[h*dstbyteperline+w/8]=~outbyte;
outbyte = 0;
}
}
// do not forget the last byte
if (bpp == 1)
dst[h*dstbyteperline+width/8] = ~outbyte;
}
wxBitmap mask_bmp( (const char *)dst, width, height, 1 );
wxMask* mask = new wxMask(mask_bmp);
bmp.SetMask(mask);
free( dst );
gdk_image_destroy( img );
}
return bmp;
free( tablex );
free( tabley );
return bmp;
}

View File

@@ -89,48 +89,42 @@ void gdk_wx_draw_bitmap(GdkDrawable *drawable,
gint width,
gint height)
{
gint src_width, src_height;
#ifndef __WXGTK20__
GdkWindowPrivate *drawable_private;
GdkWindowPrivate *src_private;
GdkGCPrivate *gc_private;
#endif
g_return_if_fail (drawable != NULL);
g_return_if_fail (src != NULL);
g_return_if_fail (gc != NULL);
#ifdef __WXGTK20__
// This doesn't seem to exist for bitmaps (1-bit)
// if (GDK_WINDOW_DESTROYED(drawable) || GDK_WINDOW_DESTROYED(src))
// return;
gint src_width, src_height;
gdk_drawable_get_size(src, &src_width, &src_height);
#else
drawable_private = (GdkWindowPrivate*) drawable;
src_private = (GdkWindowPrivate*) src;
if (drawable_private->destroyed || src_private->destroyed)
return;
src_width = src_private->width;
src_height = src_private->height;
gc_private = (GdkGCPrivate*) gc;
#endif
if (width == -1) width = src_width;
if (height == -1) height = src_height;
#ifdef __WXGTK20__
XCopyPlane( GDK_WINDOW_XDISPLAY(drawable),
GDK_WINDOW_XID(src),
GDK_WINDOW_XID(drawable),
GDK_GC_XGC(gc),
xsrc, ysrc,
width, height,
xdest, ydest,
0, 0,
1 );
#else
GdkWindowPrivate *drawable_private;
GdkWindowPrivate *src_private;
GdkGCPrivate *gc_private;
drawable_private = (GdkWindowPrivate*) drawable;
src_private = (GdkWindowPrivate*) src;
if (drawable_private->destroyed || src_private->destroyed)
return;
gint src_width = src_private->width;
gint src_height = src_private->height;
gc_private = (GdkGCPrivate*) gc;
if (width == -1) width = src_width;
if (height == -1) height = src_height;
XCopyPlane( drawable_private->xdisplay,
src_private->xwindow,
drawable_private->xwindow,
@@ -1041,7 +1035,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
bool is_mono = (bitmap.GetBitmap() != NULL);
/* scale/translate size and position */
// scale/translate size and position
int xx = XLOG2DEV(x);
int yy = YLOG2DEV(y);
@@ -1056,7 +1050,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
int ww = XLOG2DEVREL(w);
int hh = YLOG2DEVREL(h);
/* compare to current clipping region */
// compare to current clipping region
if (!m_currentClippingRegion.IsNull())
{
wxRegion tmp( xx,yy,ww,hh );
@@ -1065,7 +1059,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
return;
}
/* scale bitmap if required */
// scale bitmap if required
wxBitmap use_bitmap;
if ((w != ww) || (h != hh))
{
@@ -1081,63 +1075,77 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
use_bitmap = bitmap;
}
/* apply mask if any */
// apply mask if any
GdkBitmap *mask = (GdkBitmap *) NULL;
if (use_bitmap.GetMask()) mask = use_bitmap.GetMask()->GetBitmap();
if (useMask && mask)
GdkBitmap *new_mask = (GdkBitmap*) NULL;
if (useMask && mask)
{
if (!m_currentClippingRegion.IsNull())
{
GdkBitmap *new_mask = (GdkBitmap*) NULL;
#ifndef __WXGTK20__ // TODO fix crash
if (!m_currentClippingRegion.IsNull())
{
GdkColor col;
new_mask = gdk_pixmap_new( wxGetRootWindow()->window, ww, hh, 1 );
GdkGC *gc = gdk_gc_new( new_mask );
col.pixel = 0;
gdk_gc_set_foreground( gc, &col );
gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh );
col.pixel = 0;
gdk_gc_set_background( gc, &col );
col.pixel = 1;
gdk_gc_set_foreground( gc, &col );
gdk_gc_set_clip_region( gc, m_currentClippingRegion.GetRegion() );
gdk_gc_set_clip_origin( gc, -xx, -yy );
gdk_gc_set_fill( gc, GDK_OPAQUE_STIPPLED );
gdk_gc_set_stipple( gc, mask );
gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh );
gdk_gc_unref( gc );
}
#endif
if (is_mono)
{
if (new_mask)
gdk_gc_set_clip_mask( m_textGC, new_mask );
else
gdk_gc_set_clip_mask( m_textGC, mask );
gdk_gc_set_clip_origin( m_textGC, xx, yy );
}
else
{
if (new_mask)
gdk_gc_set_clip_mask( m_penGC, new_mask );
else
gdk_gc_set_clip_mask( m_penGC, mask );
gdk_gc_set_clip_origin( m_penGC, xx, yy );
}
if (new_mask)
gdk_bitmap_unref( new_mask );
GdkColor col;
new_mask = gdk_pixmap_new( wxGetRootWindow()->window, ww, hh, 1 );
GdkGC *gc = gdk_gc_new( new_mask );
col.pixel = 0;
gdk_gc_set_foreground( gc, &col );
gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh );
col.pixel = 0;
gdk_gc_set_background( gc, &col );
col.pixel = 1;
gdk_gc_set_foreground( gc, &col );
gdk_gc_set_clip_region( gc, m_currentClippingRegion.GetRegion() );
gdk_gc_set_clip_origin( gc, -xx, -yy );
gdk_gc_set_fill( gc, GDK_OPAQUE_STIPPLED );
gdk_gc_set_stipple( gc, mask );
gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh );
gdk_gc_unref( gc );
}
if (is_mono)
{
if (new_mask)
gdk_gc_set_clip_mask( m_textGC, new_mask );
else
gdk_gc_set_clip_mask( m_textGC, mask );
gdk_gc_set_clip_origin( m_textGC, xx, yy );
}
else
{
if (new_mask)
gdk_gc_set_clip_mask( m_penGC, new_mask );
else
gdk_gc_set_clip_mask( m_penGC, mask );
gdk_gc_set_clip_origin( m_penGC, xx, yy );
}
}
/* Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
drawing a mono-bitmap (XBitmap) we use the current text GC */
// Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
// drawing a mono-bitmap (XBitmap) we use the current text GC
if (is_mono)
{
#ifdef __WXGTK20__
GdkPixmap *bitmap = gdk_pixmap_new( wxGetRootWindow()->window, ww, hh, -1 );
GdkGC *gc = gdk_gc_new( bitmap );
gdk_gc_set_foreground( gc, m_textForegroundColour.GetColor() );
gdk_gc_set_background( gc, m_textBackgroundColour.GetColor() );
gdk_wx_draw_bitmap( bitmap, gc, use_bitmap.GetBitmap(), 0, 0, 0, 0, -1, -1 );
gdk_draw_drawable( m_window, m_textGC, bitmap, 0, 0, xx, yy, -1, -1 );
gdk_bitmap_unref( bitmap );
gdk_gc_unref( gc );
#else
gdk_wx_draw_bitmap( m_window, m_textGC, use_bitmap.GetBitmap(), 0, 0, xx, yy, -1, -1 );
#endif
}
else
{
gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), 0, 0, xx, yy, -1, -1 );
}
/* remove mask again if any */
// remove mask again if any
if (useMask && mask)
{
if (is_mono)
@@ -1155,6 +1163,9 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() );
}
}
if (new_mask)
gdk_bitmap_unref( new_mask );
}
bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
@@ -1165,22 +1176,15 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
bool useMask,
wxCoord xsrcMask, wxCoord ysrcMask )
{
/* this is the nth try to get this utterly useless function to
work. it now completely ignores the scaling or translation
of the source dc, but scales correctly on the target dc and
knows about possible mask information in a memory dc. */
wxCHECK_MSG( Ok(), FALSE, wxT("invalid window dc") );
wxCHECK_MSG( source, FALSE, wxT("invalid source dc") );
if (!m_window) return FALSE;
#if 1
// transform the source DC coords to the device ones
xsrc = source->XLOG2DEV(xsrc);
ysrc = source->YLOG2DEV(ysrc);
#endif
wxClientDC *srcDC = (wxClientDC*)source;
wxMemoryDC *memDC = (wxMemoryDC*)source;
@@ -1188,10 +1192,11 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
bool use_bitmap_method = FALSE;
bool is_mono = FALSE;
/* TODO: use the mask origin when drawing transparently */
// TODO: use the mask origin when drawing transparently
if (xsrcMask == -1 && ysrcMask == -1)
{
xsrcMask = xsrc; ysrcMask = ysrc;
xsrcMask = xsrc;
ysrcMask = ysrc;
}
if (srcDC->m_isMemDC)
@@ -1200,34 +1205,34 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
is_mono = (memDC->m_selected.GetDepth() == 1);
/* we use the "XCopyArea" way to copy a memory dc into
y different window if the memory dc BOTH
a) doesn't have any mask or its mask isn't used
b) it is clipped
c) is not 1-bit */
// we use the "XCopyArea" way to copy a memory dc into
// a different window if the memory dc BOTH
// a) doesn't have any mask or its mask isn't used
// b) it is clipped
// c) is not 1-bit
if (useMask && (memDC->m_selected.GetMask()))
{
/* we HAVE TO use the direct way for memory dcs
that have mask since the XCopyArea doesn't know
about masks */
// we HAVE TO use the direct way for memory dcs
// that have mask since the XCopyArea doesn't know
// about masks
use_bitmap_method = TRUE;
}
else if (is_mono)
{
/* we HAVE TO use the direct way for memory dcs
that are bitmaps because XCopyArea doesn't cope
with different bit depths */
// we HAVE TO use the direct way for memory dcs
// that are bitmaps because XCopyArea doesn't cope
// with different bit depths
use_bitmap_method = TRUE;
}
else if ((xsrc == 0) && (ysrc == 0) &&
(width == memDC->m_selected.GetWidth()) &&
(height == memDC->m_selected.GetHeight()))
{
/* we SHOULD use the direct way if all of the bitmap
in the memory dc is copied in which case XCopyArea
wouldn't be able able to boost performace by reducing
the area to be scaled */
// we SHOULD use the direct way if all of the bitmap
// in the memory dc is copied in which case XCopyArea
// wouldn't be able able to boost performace by reducing
// the area to be scaled
use_bitmap_method = TRUE;
}
else
@@ -1284,7 +1289,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
if ((bm_width != bm_ww) || (bm_height != bm_hh))
{
use_bitmap = memDC->m_selected.Rescale(cx-xx,cy-yy,cw,ch,bm_ww,bm_hh);
use_bitmap = memDC->m_selected.Rescale(cx-xx,cy-yy,cw,ch,bm_ww,bm_hh);
}
else
{
@@ -1296,10 +1301,10 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
GdkBitmap *mask = (GdkBitmap *) NULL;
if (use_bitmap.GetMask()) mask = use_bitmap.GetMask()->GetBitmap();
GdkBitmap *new_mask = (GdkBitmap*) NULL;
if (useMask && mask)
{
GdkBitmap *new_mask = (GdkBitmap*) NULL;
#ifndef __WXGTK20__ // TODO fix crash
if (!m_currentClippingRegion.IsNull())
{
GdkColor col;
@@ -1320,7 +1325,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, bm_ww, bm_hh );
gdk_gc_unref( gc );
}
#endif
if (is_mono)
{
if (new_mask)
@@ -1339,21 +1344,36 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
// was: gdk_gc_set_clip_origin( m_penGC, xx, yy );
gdk_gc_set_clip_origin( m_penGC, cx, cy );
}
if (new_mask)
gdk_bitmap_unref( new_mask );
}
/* Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
drawing a mono-bitmap (XBitmap) we use the current text GC */
// Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For
// drawing a mono-bitmap (XBitmap) we use the current text GC
if (is_mono)
{
#ifdef __WXGTK20__
GdkPixmap *bitmap = gdk_pixmap_new( wxGetRootWindow()->window, bm_ww, bm_hh, -1 );
GdkGC *gc = gdk_gc_new( bitmap );
gdk_gc_set_foreground( gc, m_textForegroundColour.GetColor() );
gdk_gc_set_background( gc, m_textBackgroundColour.GetColor() );
gdk_wx_draw_bitmap( bitmap, gc, use_bitmap.GetBitmap(), 0, 0, 0, 0, -1, -1 );
gdk_draw_drawable( m_window, m_textGC, bitmap, xsrc, ysrc, cx, cy, cw, ch );
gdk_bitmap_unref( bitmap );
gdk_gc_unref( gc );
#else
// was: gdk_wx_draw_bitmap( m_window, m_textGC, use_bitmap.GetBitmap(), xsrc, ysrc, xx, yy, ww, hh );
gdk_wx_draw_bitmap( m_window, m_textGC, use_bitmap.GetBitmap(), xsrc, ysrc, cx, cy, cw, ch );
#endif
}
else
{
// was: gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), xsrc, ysrc, xx, yy, ww, hh );
gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), xsrc, ysrc, cx, cy, cw, ch );
}
/* remove mask again if any */
// remove mask again if any
if (useMask && mask)
{
if (is_mono)
@@ -1371,8 +1391,11 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() );
}
}
if (new_mask)
gdk_bitmap_unref( new_mask );
}
else /* use_bitmap_method */
else // use_bitmap_method
{
if ((width != ww) || (height != hh))
{
@@ -1382,7 +1405,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
wxCoord cx,cy,cw,ch;
tmp.GetBox(cx,cy,cw,ch);
// rescale bitmap
// rescale bitmap
wxBitmap bitmap = memDC->m_selected.Rescale( cx-xx, cy-yy, cw, ch, ww, hh );
// draw scaled bitmap
@@ -1391,9 +1414,9 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
}
else
{
/* No scaling and not a memory dc with a mask either */
// No scaling and not a memory dc with a mask either
/* copy including child window contents */
// copy including child window contents
gdk_gc_set_subwindow( m_penGC, GDK_INCLUDE_INFERIORS );
gdk_window_copy_area( m_window, m_penGC, xx, yy,
srcDC->GetWindow(),
@@ -1403,6 +1426,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest,
}
SetLogicalFunction( old_logical_func );
return TRUE;
}