X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/788519c6055dc2290c40fb1569d2889d8ef8e76b..df0e1b64e382510896c2ae3849cca91baede40d7:/src/x11/dcclient.cpp?ds=inline diff --git a/src/x11/dcclient.cpp b/src/x11/dcclient.cpp index 1af88bb272..c6c808c376 100644 --- a/src/x11/dcclient.cpp +++ b/src/x11/dcclient.cpp @@ -255,6 +255,11 @@ void wxWindowDC::SetUpDC() XSetFillStyle( (Display*) m_display, (GC) m_textGC, FillSolid ); +#if wxUSE_NANOX + // By default, draw transparently + GrSetGCUseBackground((GC) m_textGC, FALSE); +#endif + /* m_penGC */ m_pen.GetColour().CalcPixel( m_cmap ); XSetForeground( (Display*) m_display, (GC) m_penGC, m_pen.GetColour().GetPixel() ); @@ -833,8 +838,10 @@ void wxWindowDC::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord hei void wxWindowDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y) { + DoDrawBitmap(icon, x, y, TRUE); } +#if wxUSE_NANOX void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, wxCoord x, wxCoord y, bool useMask ) @@ -889,8 +896,127 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, /* apply mask if any */ WXPixmap mask = NULL; - if (use_bitmap.GetMask()) mask = use_bitmap.GetMask()->GetBitmap(); + if (use_bitmap.GetMask()) + mask = use_bitmap.GetMask()->GetBitmap(); + + if (useMask && mask) + { + Pixmap pixmap = (Pixmap) use_bitmap.GetPixmap() ; + Pixmap maskPixmap = (Pixmap) use_bitmap.GetMask()->GetBitmap() ; + Pixmap bufPixmap = GrNewPixmap(w, h, 0); + GC gc = GrNewGC(); + GrSetGCUseBackground(gc, FALSE); + GrSetGCMode(gc, GR_MODE_COPY); + + // This code assumes that background and foreground + // colours are used in ROPs, like in MSW. + // Not sure if this is true. + + // Copy destination to buffer. + // In DoBlit, we need this step because Blit has + // a ROP argument. Here, we don't need it. + // In DoBlit, we may be able to eliminate this step + // if we check if the rop = copy +#if 0 + GrCopyArea(bufPixmap, gc, 0, 0, w, h, (Window) m_window, + 0, 0, GR_MODE_COPY); +#endif + + // Copy src to buffer using selected raster op (none selected + // in DrawBitmap, so just use Gxcopy) + GrCopyArea(bufPixmap, gc, 0, 0, w, h, pixmap, + 0, 0, GR_MODE_COPY); + + // Set masked area in buffer to BLACK (pixel value 0) + GrSetGCBackground(gc, WHITE); + GrSetGCForeground(gc, BLACK); + GrCopyArea(bufPixmap, gc, 0, 0, w, h, maskPixmap, + 0, 0, GR_MODE_AND); + + // set unmasked area in dest to BLACK + GrSetGCBackground(gc, BLACK); + GrSetGCForeground(gc, WHITE); + GrCopyArea((Window) m_window, gc, xx, yy, w, h, maskPixmap, + 0, 0, GR_MODE_AND); + + // OR buffer to dest + GrCopyArea((Window) m_window, gc, xx, yy, w, h, bufPixmap, + 0, 0, GR_MODE_OR); + + GrDestroyGC(gc); + GrDestroyWindow(bufPixmap); + } + else + XCopyArea( (Display*) m_display, (Pixmap) use_bitmap.GetPixmap(), (Window) m_window, + (GC) m_penGC, 0, 0, w, h, xx, yy ); + + /* remove mask again if any */ + if (useMask && mask) + { + if (!m_currentClippingRegion.IsNull()) + XSetRegion( (Display*) m_display, (GC) m_penGC, (Region) m_currentClippingRegion.GetX11Region() ); + } +} + +#else + +// Normal X11 +void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, + wxCoord x, wxCoord y, + bool useMask ) +{ + wxCHECK_RET( Ok(), wxT("invalid window dc") ); + + wxCHECK_RET( bitmap.Ok(), wxT("invalid bitmap") ); + + bool is_mono = (bitmap.GetBitmap() != NULL); + + // scale/translate size and position + int xx = XLOG2DEV(x); + int yy = YLOG2DEV(y); + + int w = bitmap.GetWidth(); + int h = bitmap.GetHeight(); + + CalcBoundingBox( x, y ); + CalcBoundingBox( x + w, y + h ); + + if (!m_window) return; + + int ww = XLOG2DEVREL(w); + int hh = YLOG2DEVREL(h); + + // compare to current clipping region + if (!m_currentClippingRegion.IsNull()) { + wxRegion tmp( xx,yy,ww,hh ); + tmp.Intersect( m_currentClippingRegion ); + if (tmp.IsEmpty()) + return; + } + + // scale bitmap if required + wxBitmap use_bitmap; + if ((w != ww) || (h != hh)) + { + wxImage image( bitmap ); + image.Rescale( ww, hh ); +#if 0 + if (is_mono) + use_bitmap = image.ConvertToMonoBitmap(255,255,255); + else +#endif + use_bitmap = image.ConvertToBitmap(); + } + else + { + use_bitmap = bitmap; + } + + // apply mask if any + WXPixmap mask = NULL; + if (use_bitmap.GetMask()) mask = use_bitmap.GetMask()->GetBitmap(); + if (useMask && mask) { WXPixmap new_mask = NULL; @@ -935,10 +1061,9 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, if (new_mask) XFreePixmap( (Display*) m_display, (Pixmap) 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) XCopyPlane( (Display*) m_display, (Pixmap) use_bitmap.GetBitmap(), (Window) m_window, (GC) m_textGC, 0, 0, w, h, xx, yy, 1 ); @@ -946,7 +1071,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, XCopyArea( (Display*) m_display, (Pixmap) use_bitmap.GetPixmap(), (Window) m_window, (GC) m_penGC, 0, 0, w, h, xx, yy ); - /* remove mask again if any */ + // remove mask again if any if (useMask && mask) { if (is_mono) @@ -965,9 +1090,11 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, } } } +#endif + // wxUSE_NANOX/!wxUSE_NANOX bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, - wxDC *source, wxCoord xsrc, wxCoord ysrc, int rop, bool useMask, + wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func, bool useMask, wxCoord xsrcMask, wxCoord ysrcMask ) { /* this is the nth try to get this utterly useless function to @@ -991,13 +1118,13 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he 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 0 if (srcDC->m_isMemDC) { if (!memDC->m_selected.Ok()) return FALSE; @@ -1042,14 +1169,14 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he CalcBoundingBox( xdest, ydest ); CalcBoundingBox( xdest + width, ydest + height ); - /* scale/translate size and position */ + // scale/translate size and position wxCoord xx = XLOG2DEV(xdest); wxCoord yy = YLOG2DEV(ydest); wxCoord ww = XLOG2DEVREL(width); wxCoord hh = YLOG2DEVREL(height); - /* compare to current clipping region */ + // compare to current clipping region if (!m_currentClippingRegion.IsNull()) { wxRegion tmp( xx,yy,ww,hh ); @@ -1063,14 +1190,14 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he if (use_bitmap_method) { - /* scale/translate bitmap size */ + // scale/translate bitmap size wxCoord bm_width = memDC->m_selected.GetWidth(); wxCoord bm_height = memDC->m_selected.GetHeight(); wxCoord bm_ww = XLOG2DEVREL( bm_width ); wxCoord bm_hh = YLOG2DEVREL( bm_height ); - /* scale bitmap if required */ + // scale bitmap if required wxBitmap use_bitmap; if ((bm_width != bm_ww) || (bm_height != bm_hh)) @@ -1078,9 +1205,11 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he wxImage image( memDC->m_selected ); image = image.Scale( bm_ww, bm_hh ); +#if 0 if (is_mono) use_bitmap = image.ConvertToMonoBitmap(255,255,255); else +#endif use_bitmap = image.ConvertToBitmap(); } else @@ -1088,13 +1217,14 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he use_bitmap = memDC->m_selected; } - /* apply mask if any */ - GdkBitmap *mask = (GdkBitmap *) NULL; + // apply mask if any + WXPixmap mask = NULL; if (use_bitmap.GetMask()) mask = use_bitmap.GetMask()->GetBitmap(); if (useMask && mask) { - GdkBitmap *new_mask = (GdkBitmap*) NULL; + WXPixmap new_mask = NULL; +#if 0 if (!m_currentClippingRegion.IsNull()) { GdkColor col; @@ -1114,59 +1244,62 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, bm_ww, bm_hh ); gdk_gc_unref( gc ); } - +#endif if (is_mono) { if (new_mask) - gdk_gc_set_clip_mask( m_textGC, new_mask ); + XSetClipMask( (Display*) m_display, (GC) m_textGC, (Pixmap) new_mask ); else - gdk_gc_set_clip_mask( m_textGC, mask ); - gdk_gc_set_clip_origin( m_textGC, xx, yy ); + XSetClipMask( (Display*) m_display, (GC) m_textGC, (Pixmap) mask ); + XSetClipOrigin( (Display*) m_display, (GC) m_textGC, xx, yy ); } else { if (new_mask) - gdk_gc_set_clip_mask( m_penGC, new_mask ); + XSetClipMask( (Display*) m_display, (GC) m_penGC, (Pixmap) new_mask ); else - gdk_gc_set_clip_mask( m_penGC, mask ); - gdk_gc_set_clip_origin( m_penGC, xx, yy ); + XSetClipMask( (Display*) m_display, (GC) m_penGC, (Pixmap) mask ); + XSetClipOrigin( (Display*) m_display, (GC) m_penGC, xx, yy ); } + if (new_mask) - gdk_bitmap_unref( new_mask ); + XFreePixmap( (Display*) m_display, (Pixmap) 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) - gdk_wx_draw_bitmap( m_window, m_textGC, use_bitmap.GetBitmap(), xsrc, ysrc, xx, yy, ww, hh ); + XCopyPlane( (Display*) m_display, (Pixmap) use_bitmap.GetBitmap(), (Window) m_window, + (GC) m_textGC, xsrc, ysrc, width, height, xx, yy, 1 ); else - gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), xsrc, ysrc, xx, yy, ww, hh ); + XCopyArea( (Display*) m_display, (Pixmap) use_bitmap.GetPixmap(), (Window) m_window, + (GC) m_penGC, xsrc, ysrc, width, height, xx, yy ); - /* remove mask again if any */ + // remove mask again if any if (useMask && mask) { if (is_mono) { - gdk_gc_set_clip_mask( m_textGC, (GdkBitmap *) NULL ); - gdk_gc_set_clip_origin( m_textGC, 0, 0 ); + XSetClipMask( (Display*) m_display, (GC) m_textGC, None ); + XSetClipOrigin( (Display*) m_display, (GC) m_textGC, 0, 0 ); if (!m_currentClippingRegion.IsNull()) - gdk_gc_set_clip_region( m_textGC, m_currentClippingRegion.GetRegion() ); + XSetRegion( (Display*) m_display, (GC) m_textGC, (Region) m_currentClippingRegion.GetX11Region() ); } else { - gdk_gc_set_clip_mask( m_penGC, (GdkBitmap *) NULL ); - gdk_gc_set_clip_origin( m_penGC, 0, 0 ); + XSetClipMask( (Display*) m_display, (GC) m_penGC, None ); + XSetClipOrigin( (Display*) m_display, (GC) m_penGC, 0, 0 ); if (!m_currentClippingRegion.IsNull()) - gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() ); + XSetRegion( (Display*) m_display, (GC) m_penGC, (Region) m_currentClippingRegion.GetX11Region() ); } } } - else /* use_bitmap_method */ + else // use_bitmap_method { if ((width != ww) || (height != hh)) { - /* draw source window into a bitmap as we cannot scale + /* Draw source window into a bitmap as we cannot scale a window in contrast to a bitmap. this would actually work with memory dcs as well, but we'd lose the mask information and waste one step in this process since @@ -1181,42 +1314,38 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he wxBitmap bitmap( width, height ); - /* copy including child window contents */ - gdk_gc_set_subwindow( m_penGC, GDK_INCLUDE_INFERIORS ); - gdk_window_copy_area( bitmap.GetPixmap(), m_penGC, 0, 0, - srcDC->GetWindow(), - xsrc, ysrc, width, height ); - gdk_gc_set_subwindow( m_penGC, GDK_CLIP_BY_CHILDREN ); + // copy including child window contents + XSetSubwindowMode( (Display*) m_display, (GC) m_penGC, IncludeInferiors ); + XCopyArea( (Display*) m_display, (Window) srcDC->GetWindow(), (Window) bitmap.GetPixmap(), + (GC) m_penGC, xsrc, ysrc, width, height, 0, 0 ); + XSetSubwindowMode( (Display*) m_display, (GC) m_penGC, ClipByChildren ); - /* scale image */ + // scale image wxImage image( bitmap ); image = image.Scale( ww, hh ); - /* convert to bitmap */ + // convert to bitmap bitmap = image.ConvertToBitmap(); - /* draw scaled bitmap */ - gdk_draw_pixmap( m_window, m_penGC, bitmap.GetPixmap(), 0, 0, xx, yy, -1, -1 ); - + // draw scaled bitmap + XCopyArea( (Display*) m_display, (Window) bitmap.GetPixmap(), (Window) m_window, + (GC) m_penGC, 0, 0, width, height, xx, yy ); } else { - /* No scaling and not a memory dc with a mask either */ - - /* 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(), - xsrc, ysrc, width, height ); - gdk_gc_set_subwindow( m_penGC, GDK_CLIP_BY_CHILDREN ); + // No scaling and not a memory dc with a mask either + + // copy including child window contents + XSetSubwindowMode( (Display*) m_display, (GC) m_penGC, IncludeInferiors ); + XCopyArea( (Display*) m_display, (Window) srcDC->GetWindow(), (Window) m_window, + (GC) m_penGC, xsrc, ysrc, width, height, xx, yy ); + XSetSubwindowMode( (Display*) m_display, (GC) m_penGC, ClipByChildren ); } } SetLogicalFunction( old_logical_func ); + return TRUE; -#endif - - return FALSE; } void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) @@ -1232,17 +1361,32 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) x = XLOG2DEV(x); y = YLOG2DEV(y); -#if 0 - wxCoord width = gdk_string_width( font, text.mbc_str() ); - wxCoord height = font->ascent + font->descent; - - if ( m_backgroundMode == wxSOLID ) + // First draw a rectangle representing the text background, if a text + // background is specified + if (m_textBackgroundColour.Ok () && (m_backgroundMode != wxTRANSPARENT)) { - gdk_gc_set_foreground( m_textGC, m_textBackgroundColour.GetColor() ); - gdk_draw_rectangle( m_window, m_textGC, TRUE, x, y, width, height ); - gdk_gc_set_foreground( m_textGC, m_textForegroundColour.GetColor() ); + // Since X draws from the baseline of the text, must add the text height + int cx = 0; + int cy = 0; + int ascent = 0; + int slen; + int direction, descent; + + slen = strlen(text); + XCharStruct overall_return; + + (void)XTextExtents(xfont, (char*) text.c_str(), slen, &direction, + &ascent, &descent, &overall_return); + + cx = overall_return.width; + cy = ascent + descent; + m_textBackgroundColour.CalcPixel(m_cmap); + XSetForeground ((Display*) m_display, (GC) m_textGC, m_textBackgroundColour.GetPixel()); + XFillRectangle( (Display*) m_display, (Window) m_window, + (GC) m_textGC, x, y, cx, cy ); + XSetForeground ((Display*) m_display, (GC) m_textGC, m_textForegroundColour.GetPixel()); + } -#endif XSetFont( (Display*) m_display, (GC) m_textGC, xfont->fid ); #if !wxUSE_NANOX @@ -1714,6 +1858,10 @@ void wxWindowDC::SetBackgroundMode( int mode ) m_backgroundMode = mode; +#if wxUSE_NANOX + GrSetGCUseBackground((GC) m_textGC, mode == wxTRANSPARENT ? FALSE : TRUE); +#endif + if (!m_window) return; // CMB 21/7/98: fill style of cross-hatch brushes is affected by