All (GUI):
+- Added wxDC::StretchBlit() for wxMac and wxMSW (Vince Harron)
- Added wxEventBlocker class (Francesco Montorsi).
- Added wxFile/DirPickerCtrl::Get/SetFile/DirName() (Francesco Montorsi).
- Added wxSizerFlags::Top() and Bottom().
\wxheading{See also}
-\helpref{wxMemoryDC}{wxmemorydc}, \helpref{wxBitmap}{wxbitmap}, \helpref{wxMask}{wxmask}
+\helpref{wxDC::StretchBlit}{wxdcstretchblit}, \helpref{wxMemoryDC}{wxmemorydc}, \helpref{wxBitmap}{wxbitmap}, \helpref{wxMask}{wxmask}
\begin{comment}
Starts a document page (only relevant when outputting to a printer).
+
+\membersection{wxDC::StretchBlit}\label{wxdcstretchblit}
+
+\func{bool}{StretchBlit}{\param{wxCoord}{ xdest}, \param{wxCoord}{ ydest}, \param{wxCoord}{ dstWidth}, \param{wxCoord}{ dstHeight},
+ \param{wxDC* }{source}, \param{wxCoord}{ xsrc}, \param{wxCoord}{ ysrc}, \param{wxCoord}{ srcWidth}, \param{wxCoord}{ srcHeight},
+ \param{int}{ logicalFunc = wxCOPY}, \param{bool }{useMask = false}, \param{wxCoord}{ xsrcMask = -1}, \param{wxCoord}{ ysrcMask = -1}}
+
+Copy from a source DC to this DC, specifying the destination
+coordinates, destination size, source DC, source coordinates,
+size of source area to copy, logical function, whether to use a bitmap mask,
+and mask source position.
+
+\wxheading{Parameters}
+
+\docparam{xdest}{Destination device context x position.}
+
+\docparam{ydest}{Destination device context y position.}
+
+\docparam{dstWidth}{Width of destination area.}
+
+\docparam{dstHeight}{Height of destination area.}
+
+\docparam{source}{Source device context.}
+
+\docparam{xsrc}{Source device context x position.}
+
+\docparam{ysrc}{Source device context y position.}
+
+\docparam{srcWidth}{Width of source area to be copied.}
+
+\docparam{srcHeight}{Height of source area to be copied.}
+
+\docparam{logicalFunc}{Logical function to use: see \helpref{wxDC::SetLogicalFunction}{wxdcsetlogicalfunction}.}
+
+\docparam{useMask}{If true, Blit does a transparent blit using the mask that is associated with the bitmap
+selected into the source device context. The Windows implementation does the following if \texttt{MaskBlt} cannot be used:
+
+\begin{enumerate}
+\item Creates a temporary bitmap and copies the destination area into it.
+\item Copies the source area into the temporary bitmap using the specified logical function.
+\item Sets the masked area in the temporary bitmap to BLACK by ANDing the
+mask bitmap with the temp bitmap with the foreground colour set to WHITE
+and the background colour set to BLACK.
+\item Sets the unmasked area in the destination area to BLACK by ANDing the
+mask bitmap with the destination area with the foreground colour set to BLACK
+and the background colour set to WHITE.
+\item ORs the temporary bitmap with the destination area.
+\item Deletes the temporary bitmap.
+\end{enumerate}
+
+This sequence of operations ensures that the source's transparent area need not be black,
+and logical functions are supported.
+
+{\bf Note:} on Windows, blitting with masks can be speeded up considerably by compiling
+wxWidgets with the \texttt{wxUSE\_DC\_CACHE} option enabled. You can also influence whether \texttt{MaskBlt}
+or the explicit mask blitting code above is used, by using \helpref{wxSystemOptions}{wxsystemoptions} and
+setting the {\bf no-maskblt} option to 1.
+
+}
+
+\docparam{xsrcMask}{Source x position on the mask. If both xsrcMask and ysrcMask are -1, xsrc and ysrc
+will be assumed for the mask source position. Currently only implemented on Windows.}
+
+\docparam{ysrcMask}{Source y position on the mask. If both xsrcMask and ysrcMask are -1, xsrc and ysrc
+will be assumed for the mask source position. Currently only implemented on Windows.}
+
+
+\wxheading{Remarks}
+
+There is partial support for Blit in wxPostScriptDC, under X.
+
+wxDC::StretchBlit is only implemented under wxMAC and wxMSW.
+
+See \helpref{wxMemoryDC}{wxmemorydc} for typical usage.
+
+\newsince{2.9.0}
+
+\wxheading{See also}
+
+\helpref{wxDC::Blit}{wxdcblit}, \helpref{wxMemoryDC}{wxmemorydc}, \helpref{wxBitmap}{wxbitmap}, \helpref{wxMask}{wxmask}
+
return DoBlit(destPt.x, destPt.y, sz.x, sz.y,
source, srcPt.x, srcPt.y, rop, useMask, srcPtMask.x, srcPtMask.y);
}
-
+
+ bool StretchBlit(wxCoord dstX, wxCoord dstY,
+ wxCoord dstWidth, wxCoord dstHeight,
+ wxDC *source,
+ wxCoord srcX, wxCoord srcY,
+ wxCoord srcWidth, wxCoord srcHeight,
+ int rop = wxCOPY, bool useMask = false,
+ wxCoord srcMaskX = wxDefaultCoord, wxCoord srcMaskY = wxDefaultCoord)
+ {
+ return DoStretchBlit(dstX, dstY, dstWidth, dstHeight,
+ source, srcX, srcY, srcWidth, srcHeight, rop, useMask, srcMaskX, srcMaskY);
+ }
+ bool StretchBlit(const wxPoint& dstPt, const wxSize& dstSize,
+ wxDC *source, const wxPoint& srcPt, const wxSize& srcSize,
+ int rop = wxCOPY, bool useMask = false, const wxPoint& srcMaskPt = wxDefaultPosition)
+ {
+ return DoStretchBlit(dstPt.x, dstPt.y, dstSize.x, dstSize.y,
+ source, srcPt.x, srcPt.y, srcSize.x, srcSize.y, rop, useMask, srcMaskPt.x, srcMaskPt.y);
+ }
+
wxBitmap GetAsBitmap(const wxRect *subrect = (const wxRect *) NULL) const
{
return DoGetAsBitmap(subrect);
virtual bool DoBlit(wxCoord xdest, wxCoord ydest,
wxCoord width, wxCoord height,
- wxDC *source, wxCoord xsrc, wxCoord ysrc,
- int rop = wxCOPY, bool useMask = false, wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord) = 0;
-
- virtual wxBitmap DoGetAsBitmap(const wxRect *WXUNUSED(subrect)) const { return wxNullBitmap; }
+ wxDC *source,
+ wxCoord xsrc, wxCoord ysrc,
+ int rop = wxCOPY,
+ bool useMask = false,
+ wxCoord xsrcMask = wxDefaultCoord,
+ wxCoord ysrcMask = wxDefaultCoord) = 0;
+
+ virtual bool DoStretchBlit(wxCoord xdest, wxCoord ydest,
+ wxCoord dstWidth, wxCoord dstHeight,
+ wxDC *source,
+ wxCoord xsrc, wxCoord ysrc,
+ wxCoord srcWidth, wxCoord srcHeight,
+ int rop = wxCOPY,
+ bool useMask = false,
+ wxCoord xsrcMask = wxDefaultCoord,
+ wxCoord ysrcMask = wxDefaultCoord);
+
+ virtual wxBitmap DoGetAsBitmap(const wxRect *WXUNUSED(subrect)) const
+ { return wxNullBitmap; }
virtual void DoGetSize(int *width, int *height) const = 0;
virtual void DoGetSizeMM(int* width, int* height) const = 0;
wxDC *source, wxCoord xsrc, wxCoord ysrc,
int rop = wxCOPY, bool useMask = false, wxCoord xsrcMask = -1, wxCoord ysrcMask = -1);
+ virtual bool DoStretchBlit(wxCoord xdest, wxCoord ydest,
+ wxCoord dstWidth, wxCoord dstHeight,
+ wxDC *source,
+ wxCoord xsrc, wxCoord ysrc,
+ wxCoord srcWidth, wxCoord srcHeight,
+ int rop = wxCOPY, bool useMask = false,
+ wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord);
+
virtual void DoGetSize(int *,int *) const;
virtual void DoGetSizeMM(int* width, int* height) const;
wxDC *source, wxCoord xsrc, wxCoord ysrc,
int rop = wxCOPY, bool useMask = false, wxCoord xsrcMask = -1, wxCoord ysrcMask = -1);
+ virtual bool DoStretchBlit(wxCoord xdest, wxCoord ydest,
+ wxCoord dstWidth, wxCoord dstHeight,
+ wxDC *source,
+ wxCoord xsrc, wxCoord ysrc,
+ wxCoord srcWidth, wxCoord srcHeight,
+ int rop = wxCOPY, bool useMask = false,
+ wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord);
+
// this is gnarly - we can't even call this function DoSetClippingRegion()
// because of virtual function hiding
wxDC *source, wxCoord xsrc, wxCoord ysrc,
int rop = wxCOPY, bool useMask = false, wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord);
+ virtual bool DoStretchBlit(wxCoord xdest, wxCoord ydest,
+ wxCoord dstWidth, wxCoord dstHeight,
+ wxDC *source,
+ wxCoord xsrc, wxCoord ysrc,
+ wxCoord srcWidth, wxCoord srcHeight,
+ int rop = wxCOPY, bool useMask = false,
+ wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord);
+
// this is gnarly - we can't even call this function DoSetClippingRegion()
// because of virtual function hiding
virtual void DoSetClippingRegionAsRegion(const wxRegion& region);
Show_Brushes,
Show_Polygons,
Show_Mask,
+ Show_Mask_Stretch,
Show_Ops,
Show_Regions,
Show_Circles,
#endif
protected:
+ enum DrawMode
+ {
+ Draw_Normal,
+ Draw_Stretch
+ };
+
void DrawTestLines( int x, int y, int width, wxDC &dc );
void DrawTestPoly(wxDC& dc);
void DrawTestBrushes(wxDC& dc);
void DrawText(wxDC& dc);
- void DrawImages(wxDC& dc);
+ void DrawImages(wxDC& dc, DrawMode mode);
void DrawWithLogicalOps(wxDC& dc);
#if wxUSE_GRAPHICS_CONTEXT
void DrawAlpha(wxDC& dc);
File_ShowBrushes,
File_ShowPolygons,
File_ShowMask,
+ File_ShowMaskStretch,
File_ShowOps,
File_ShowRegions,
File_ShowCircles,
wxPathList pathList;
pathList.Add(_T("."));
pathList.Add(_T(".."));
+ pathList.Add(_T("../.."));
wxString path = pathList.FindValidPath(_T("pat4.bmp"));
if ( !path )
{ wxT("wxXOR"), wxXOR },
};
-void MyCanvas::DrawImages(wxDC& dc)
+void MyCanvas::DrawImages(wxDC& dc, DrawMode mode)
{
dc.DrawText(_T("original image"), 0, 0);
dc.DrawBitmap(*gs_bmpNoMask, 0, 20, 0);
dc.DrawText(rasterOperations[n].name, x, y - 20);
memDC.SelectObject(*gs_bmpWithColMask);
- dc.Blit(x, y, cx, cy, &memDC, 0, 0, rasterOperations[n].rop, true);
+ if ( mode == Draw_Stretch )
+ {
+ dc.StretchBlit(x, y, cx, cy, &memDC, 0, 0, cx/2, cy/2,
+ rasterOperations[n].rop, true);
+ }
+ else
+ {
+ dc.Blit(x, y, cx, cy, &memDC, 0, 0, rasterOperations[n].rop, true);
+ }
}
}
wxDouble margin = 20 ;
wxDouble width = 180 ;
wxDouble radius = 30 ;
-
+
dc.SetPen( wxPen( wxColour( 128, 0, 0, 255 ),12, wxSOLID));
dc.SetBrush( wxBrush( wxColour( 255, 0, 0, 255),wxSOLID));
-
+
wxRect r(margin,margin+width*0.66,width,width) ;
-
+
dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ;
-
+
dc.SetPen( wxPen( wxColour( 0, 0, 128, 255 ),12, wxSOLID));
dc.SetBrush( wxBrush( wxColour( 0, 0, 255, 255),wxSOLID));
-
+
r.Offset( width * 0.8 , - width * 0.66 ) ;
-
+
dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ;
-
+
dc.SetPen( wxPen( wxColour( 128, 128, 0, 255 ),12, wxSOLID));
dc.SetBrush( wxBrush( wxColour( 192, 192, 0, 255),wxSOLID));
r.Offset( width * 0.8 , width *0.5 ) ;
-
+
dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ;
-
+
dc.SetPen( *wxTRANSPARENT_PEN ) ;
dc.SetBrush( wxBrush( wxColour(255,255,128,128) ) );
dc.DrawRoundedRectangle( 0 , margin + width / 2 , width * 3 , 100 , radius) ;
-
+
dc.SetTextForeground( wxColour(255,255,0,128) );
dc.SetFont( wxFont( 40, wxFONTFAMILY_SWISS, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL ) );
dc.DrawText( wxT("Hello!"), 120, 80 );
dc.DrawEllipticArc(x + r, y, 2*r, r, 90, 180);
dc.DrawEllipticArc(x + 3*r, y, 2*r, r, 180, 270);
dc.DrawEllipticArc(x + 5*r, y, 2*r, r, 270, 360);
-
+
// same as above, just transparent brush
-
+
dc.SetPen( *wxRED_PEN );
dc.SetBrush( *wxTRANSPARENT_BRUSH );
dc.DrawEllipticArc(x + r, y, 2*r, r, 90, 180);
dc.DrawEllipticArc(x + 3*r, y, 2*r, r, 180, 270);
dc.DrawEllipticArc(x + 5*r, y, 2*r, r, 270, 360);
-
+
}
void MyCanvas::DrawSplines(wxDC& dc)
break;
case Show_Mask:
- DrawImages(dc);
+ DrawImages(dc, Draw_Normal);
+ break;
+
+ case Show_Mask_Stretch:
+ DrawImages(dc, Draw_Stretch);
break;
case Show_Ops:
DrawWithLogicalOps(dc);
break;
-
+
#if wxUSE_GRAPHICS_CONTEXT
case Show_Alpha:
DrawAlpha(dc);
menuFile->Append(File_ShowBrushes, _T("&Brushes screen\tF4"));
menuFile->Append(File_ShowPolygons, _T("&Polygons screen\tF5"));
menuFile->Append(File_ShowMask, _T("&Mask screen\tF6"));
+ menuFile->Append(File_ShowMaskStretch, _T("1/&2 scaled mask\tShift-F6"));
menuFile->Append(File_ShowOps, _T("&ROP screen\tF7"));
menuFile->Append(File_ShowRegions, _T("Re&gions screen\tF8"));
menuFile->Append(File_ShowCircles, _T("&Circles screen\tF9"));
CalcBoundingBox(x2, y2);
}
+// ----------------------------------------------------------------------------
+// stubs for functions not implemented in all ports
+// ----------------------------------------------------------------------------
+
+bool
+wxDCBase::DoStretchBlit(wxCoord xdest, wxCoord ydest,
+ wxCoord dstWidth, wxCoord dstHeight,
+ wxDC *source,
+ wxCoord xsrc, wxCoord ysrc,
+ wxCoord WXUNUSED(srcWidth), wxCoord WXUNUSED(srcHeight),
+ int rop,
+ bool useMask,
+ wxCoord xsrcMask,
+ wxCoord ysrcMask)
+{
+ // temporary default implementation to avoid breaking platforms that don't
+ // have DoStretchBlit
+ return DoBlit(xdest, ydest, dstWidth, dstHeight, source,
+ xsrc, ysrc, rop, useMask, xsrcMask, ysrcMask);
+}
+
// ----------------------------------------------------------------------------
// line/polygons
// ----------------------------------------------------------------------------
else
nB = nB1 + (nB2-nB1)*(w-x)/w;
- wxColour colour(nR,nG,nB);
+ wxColour colour(nR,nG,nB);
SetPen(wxPen(colour, 1, wxSOLID));
SetBrush(wxBrush(colour));
if(nDirection == wxEAST)
else
nB = nB1 + (nB2-nB1)*(w-y)/w;
- wxColour colour(nR,nG,nB);
+ wxColour colour(nR,nG,nB);
SetPen(wxPen(colour, 1, wxSOLID));
SetBrush(wxBrush(colour));
if(nDirection == wxNORTH)
} // not iUseAngles
} // CalculateEllipticPoints
-#endif
+#endif // __WXWINCE__
bool wxGCDC::DoBlit(
wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
- wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func , bool WXUNUSED(useMask),
+ wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func , bool useMask,
wxCoord xsrcMask, wxCoord ysrcMask )
{
- wxCHECK_MSG( Ok(), false, wxT("wxGCDC(cg)::DoBlit - invalid DC") );
- wxCHECK_MSG( source->Ok(), false, wxT("wxGCDC(cg)::DoBlit - invalid source DC") );
+ return DoStretchBlit( xdest, ydest, width, height,
+ source, xsrc, ysrc, width, height, logical_func, useMask,
+ xsrcMask,ysrcMask );
+}
+
+bool wxGCDC::DoStretchBlit(
+ wxCoord xdest, wxCoord ydest, wxCoord dstWidth, wxCoord dstHeight,
+ wxDC *source, wxCoord xsrc, wxCoord ysrc, wxCoord srcWidth, wxCoord srcHeight,
+ int logical_func , bool WXUNUSED(useMask),
+ wxCoord xsrcMask, wxCoord ysrcMask )
+{
+ wxCHECK_MSG( Ok(), false, wxT("wxGCDC(cg)::DoStretchBlit - invalid DC") );
+ wxCHECK_MSG( source->Ok(), false, wxT("wxGCDC(cg)::DoStretchBlit - invalid source DC") );
if ( logical_func == wxNO_OP )
return true;
wxRect subrect(source->LogicalToDeviceX(xsrc),
source->LogicalToDeviceY(ysrc),
- source->LogicalToDeviceXRel(width),
- source->LogicalToDeviceYRel(height));
+ source->LogicalToDeviceXRel(srcWidth),
+ source->LogicalToDeviceYRel(srcHeight));
// if needed clip the subrect down to the size of the source DC
wxCoord sw, sh;
if ( blit.Ok() )
{
m_graphicContext->DrawBitmap( blit, xdest, ydest,
- wxMin(width, blit.GetWidth()),
- wxMin(height, blit.GetHeight()));
+ dstWidth, dstHeight);
}
else
{
return true ;
}
-bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
+bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord dstWidth, wxCoord dstHeight,
wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func , bool useMask,
wxCoord xsrcMask, wxCoord ysrcMask )
{
- wxCHECK_MSG(Ok(), false, wxT("wxDC::DoBlit - invalid DC"));
- wxCHECK_MSG(source->Ok(), false, wxT("wxDC::DoBlit - invalid source DC"));
+ return DoStretchBlit( xdest, ydest, dstWidth, dstHeight,
+ source, xsrc, ysrc, dstWidth, dstHeight,
+ logical_func, useMask,
+ xsrcMask, ysrcMask );
+}
+
+bool wxDC::DoStretchBlit(wxCoord xdest, wxCoord ydest,
+ wxCoord dstWidth, wxCoord dstHeight,
+ wxDC *source,
+ wxCoord xsrc, wxCoord ysrc,
+ wxCoord srcWidth, wxCoord srcHeight,
+ int logical_func = wxCOPY, bool useMask = false,
+ wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord);
+{
+ wxCHECK_MSG(Ok(), false, wxT("wxDC::DoStretchBlit - invalid DC"));
+ wxCHECK_MSG(source->Ok(), false, wxT("wxDC::DoStretchBlit - invalid source DC"));
if ( logical_func == wxNO_OP )
return true ;
Rect srcrect , dstrect ;
srcrect.top = source->YLOG2DEVMAC(ysrc) ;
srcrect.left = source->XLOG2DEVMAC(xsrc) ;
- srcrect.right = source->XLOG2DEVMAC(xsrc + width ) ;
- srcrect.bottom = source->YLOG2DEVMAC(ysrc + height) ;
+ srcrect.right = source->XLOG2DEVMAC(xsrc + srcWidth ) ;
+ srcrect.bottom = source->YLOG2DEVMAC(ysrc + srcHeight) ;
dstrect.top = YLOG2DEVMAC(ydest) ;
dstrect.left = XLOG2DEVMAC(xdest) ;
- dstrect.bottom = YLOG2DEVMAC(ydest + height ) ;
- dstrect.right = XLOG2DEVMAC(xdest + width ) ;
+ dstrect.bottom = YLOG2DEVMAC(ydest + dstHeight ) ;
+ dstrect.right = XLOG2DEVMAC(xdest + dstWidth ) ;
short mode = kUnsupportedMode ;
bool invertDestinationFirst = false ;
wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func , bool useMask,
wxCoord xsrcMask, wxCoord ysrcMask )
{
- wxCHECK_MSG( Ok(), false, wxT("wxDC(cg)::DoBlit - invalid DC") );
- wxCHECK_MSG( source->Ok(), false, wxT("wxDC(cg)::DoBlit - invalid source DC") );
+ return DoStretchBlit( xdest, ydest, width, height,
+ source, xsrc, ysrc, width, height,
+ logical_func, useMask,
+ xsrcMask, ysrcMask );
+}
+
+bool wxDC::DoStretchBlit(wxCoord xdest, wxCoord ydest,
+ wxCoord dstWidth, wxCoord dstHeight,
+ wxDC *source,
+ wxCoord xsrc, wxCoord ysrc,
+ wxCoord srcWidth, wxCoord srcHeight,
+ int logical_func = wxCOPY, bool useMask = false,
+ wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord);
+{
+ wxCHECK_MSG( Ok(), false, wxT("wxDC(cg)::DoStretchBlit - invalid DC") );
+ wxCHECK_MSG( source->Ok(), false, wxT("wxDC(cg)::DoStretchBlit - invalid source DC") );
if ( logical_func == wxNO_OP )
return true ;
wxCoord yysrc = source->YLOG2DEVMAC(ysrc) ;
wxCoord xxsrc = source->XLOG2DEVMAC(xsrc) ;
- wxCoord wwsrc = source->XLOG2DEVREL(width) ;
- wxCoord hhsrc = source->YLOG2DEVREL(height) ;
+ wxCoord wwsrc = source->XLOG2DEVREL(srcWidth) ;
+ wxCoord hhsrc = source->YLOG2DEVREL(srcHeight) ;
wxCoord yydest = YLOG2DEVMAC(ydest) ;
wxCoord xxdest = XLOG2DEVMAC(xdest) ;
- wxCoord wwdest = XLOG2DEVREL(width) ;
- wxCoord hhdest = YLOG2DEVREL(height) ;
+ wxCoord wwdest = XLOG2DEVREL(dstWidth) ;
+ wxCoord hhdest = YLOG2DEVREL(dstHeight) ;
wxMemoryDC* memdc = dynamic_cast<wxMemoryDC*>(source) ;
if ( memdc && logical_func == wxCOPY )
// return true if we could draw the bitmap in one way or the other, false
// otherwise
static bool AlphaBlt(HDC hdcDst,
- int x, int y, int w, int h,
- int srcX, int srcY, HDC hdcSrc,
- const wxBitmap& bmpSrc);
+ int x, int y, int dstWidth, int dstHeight,
+ int srcX, int srcY,
+ int srcWidth, int srcHeight,
+ HDC hdcSrc,
+ const wxBitmap& bmp);
#ifdef wxHAVE_RAW_BITMAP
// our (limited) AlphaBlend() replacement for Windows versions not providing it
static void
-wxAlphaBlend(HDC hdcDst, int x, int y, int w, int h,
- int srcX, int srcY, const wxBitmap& bmp);
+wxAlphaBlend(HDC hdcDst, int xDst, int yDst,
+ int dstWidth, int dstHeight,
+ int srcX, int srcY,
+ int srcWidth, int srcHeight,
+ const wxBitmap& bmpSrc);
#endif // wxHAVE_RAW_BITMAP
MemoryHDC hdcMem;
SelectInHDC select(hdcMem, GetHbitmapOf(bmp));
- if ( AlphaBlt(GetHdc(), x, y, width, height, 0, 0, hdcMem, bmp) )
+ if ( AlphaBlt(GetHdc(), x, y, width, height, 0, 0, width, height, hdcMem, bmp) )
return;
}
// ---------------------------------------------------------------------------
// bit blit
// ---------------------------------------------------------------------------
-
-bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
- wxCoord width, wxCoord height,
- wxDC *source, wxCoord xsrc, wxCoord ysrc,
+bool wxDC::DoBlit(wxCoord dstX, wxCoord dstY,
+ wxCoord dstWidth, wxCoord dstHeight,
+ wxDC *source,
+ wxCoord srcX, wxCoord srcY,
int rop, bool useMask,
- wxCoord xsrcMask, wxCoord ysrcMask)
+ wxCoord srcMaskX, wxCoord srcMaskY)
+{
+ return DoStretchBlit(dstX, dstY, dstWidth, dstHeight, source, srcX, srcY, dstWidth, dstHeight, rop, useMask, srcMaskX, srcMaskY);
+}
+
+bool wxDC::DoStretchBlit(wxCoord xdest, wxCoord ydest,
+ wxCoord dstWidth, wxCoord dstHeight,
+ wxDC *source,
+ wxCoord xsrc, wxCoord ysrc,
+ wxCoord srcWidth, wxCoord srcHeight,
+ int rop, bool useMask,
+ wxCoord xsrcMask, wxCoord ysrcMask)
{
wxCHECK_MSG( source, false, _T("wxDC::Blit(): NULL wxDC pointer") );
if ( bmpSrc.Ok() && (bmpSrc.HasAlpha() ||
(m_selectedBitmap.Ok() && m_selectedBitmap.HasAlpha())) )
{
- if ( AlphaBlt(GetHdc(), xdest, ydest, width, height,
- xsrc, ysrc, GetHdcOf(*source), bmpSrc) )
+ if ( AlphaBlt(GetHdc(), xdest, ydest, dstWidth, dstHeight,
+ xsrc, ysrc, srcWidth, srcHeight, GetHdcOf(*source), bmpSrc) )
return true;
}
if (wxSystemOptions::GetOptionInt(wxT("no-maskblt")) == 0)
#endif
{
- success = ::MaskBlt
- (
+ if ( dstWidth == srcWidth && dstHeight == srcHeight )
+ {
+ success = ::MaskBlt
+ (
GetHdc(),
- xdest, ydest, width, height,
+ xdest, ydest, dstWidth, dstHeight,
GetHdcOf(*source),
xsrc, ysrc,
(HBITMAP)mask->GetMaskBitmap(),
xsrcMask, ysrcMask,
MAKEROP4(dwRop, DSTCOPY)
- ) != 0;
+ ) != 0;
+ }
}
if ( !success )
dc_buffer = (HDC) dcCacheEntry2->m_dc;
wxDCCacheEntry* bitmapCacheEntry = FindBitmapInCache(GetHDC(),
- width, height);
+ dstWidth, dstHeight);
buffer_bmap = (HBITMAP) bitmapCacheEntry->m_bitmap;
#else // !wxUSE_DC_CACHEING
// create a temp buffer bitmap and DCs to access it and the mask
dc_mask = ::CreateCompatibleDC(GetHdcOf(*source));
dc_buffer = ::CreateCompatibleDC(GetHdc());
- buffer_bmap = ::CreateCompatibleBitmap(GetHdc(), width, height);
+ buffer_bmap = ::CreateCompatibleBitmap(GetHdc(), dstWidth, dstHeight);
#endif // wxUSE_DC_CACHEING/!wxUSE_DC_CACHEING
HGDIOBJ hOldMaskBitmap = ::SelectObject(dc_mask, (HBITMAP) mask->GetMaskBitmap());
HGDIOBJ hOldBufferBitmap = ::SelectObject(dc_buffer, buffer_bmap);
// copy dest to buffer
- if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
+ if ( !::BitBlt(dc_buffer, 0, 0, (int)dstWidth, (int)dstHeight,
GetHdc(), xdest, ydest, SRCCOPY) )
{
wxLogLastError(wxT("BitBlt"));
}
+#ifndef __WXWINCE__
+ StretchBltModeChanger changeMode(dc_buffer, COLORONCOLOR);
+#endif
+
// copy src to buffer using selected raster op
- if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
- GetHdcOf(*source), xsrc, ysrc, dwRop) )
+ if ( !::StretchBlt(dc_buffer, 0, 0, (int)dstWidth, (int)dstHeight,
+ GetHdcOf(*source), xsrc, ysrc, srcWidth, srcHeight, dwRop) )
{
- wxLogLastError(wxT("BitBlt"));
+ wxLogLastError(wxT("StretchBlt"));
}
// set masked area in buffer to BLACK (pixel value 0)
COLORREF prevBkCol = ::SetBkColor(GetHdc(), RGB(255, 255, 255));
COLORREF prevCol = ::SetTextColor(GetHdc(), RGB(0, 0, 0));
- if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
- dc_mask, xsrcMask, ysrcMask, SRCAND) )
+ if ( !::StretchBlt(dc_buffer, 0, 0, (int)dstWidth, (int)dstHeight,
+ dc_mask, xsrcMask, ysrcMask, srcWidth, srcHeight, SRCAND) )
{
- wxLogLastError(wxT("BitBlt"));
+ wxLogLastError(wxT("StretchBlt"));
}
// set unmasked area in dest to BLACK
::SetBkColor(GetHdc(), RGB(0, 0, 0));
::SetTextColor(GetHdc(), RGB(255, 255, 255));
- if ( !::BitBlt(GetHdc(), xdest, ydest, (int)width, (int)height,
- dc_mask, xsrcMask, ysrcMask, SRCAND) )
+ if ( !::StretchBlt(GetHdc(), xdest, ydest, (int)dstWidth, (int)dstHeight,
+ dc_mask, xsrcMask, ysrcMask, srcWidth, srcHeight, SRCAND) )
{
- wxLogLastError(wxT("BitBlt"));
+ wxLogLastError(wxT("StretchBlt"));
}
::SetBkColor(GetHdc(), prevBkCol); // restore colours to original values
::SetTextColor(GetHdc(), prevCol);
// OR buffer to dest
success = ::BitBlt(GetHdc(), xdest, ydest,
- (int)width, (int)height,
+ (int)dstWidth, (int)dstHeight,
dc_buffer, 0, 0, SRCPAINT) != 0;
if ( !success )
{
if ( hDIB > 0 )
{
// reflect ysrc
- ysrc = hDIB - (ysrc + height);
+ ysrc = hDIB - (ysrc + dstHeight);
}
if ( ::StretchDIBits(GetHdc(),
xdest, ydest,
- width, height,
+ dstWidth, dstHeight,
xsrc, ysrc,
- width, height,
+ srcWidth, srcHeight,
ds.dsBm.bmBits,
(LPBITMAPINFO)&ds.dsBmih,
DIB_RGB_COLORS,
if ( !::StretchBlt
(
GetHdc(),
- xdest, ydest, width, height,
+ xdest, ydest, dstWidth, dstHeight,
GetHdcOf(*source),
- xsrc, ysrc, width, height,
+ xsrc, ysrc, srcWidth, srcHeight,
dwRop
) )
{
(
GetHdc(),
xdest, ydest,
- (int)width, (int)height,
+ (int)dstWidth, (int)dstHeight,
GetHdcOf(*source),
xsrc, ysrc,
dwRop
// ----------------------------------------------------------------------------
static bool AlphaBlt(HDC hdcDst,
- int x, int y, int width, int height,
- int srcX, int srcY, HDC hdcSrc,
+ int x, int y, int dstWidth, int dstHeight,
+ int srcX, int srcY,
+ int srcWidth, int srcHeight,
+ HDC hdcSrc,
const wxBitmap& bmp)
{
wxASSERT_MSG( bmp.Ok() && bmp.HasAlpha(), _T("AlphaBlt(): invalid bitmap") );
bf.SourceConstantAlpha = 0xff;
bf.AlphaFormat = AC_SRC_ALPHA;
- if ( pfnAlphaBlend(hdcDst, x, y, width, height,
- hdcSrc, srcX, srcY, width, height,
+ if ( pfnAlphaBlend(hdcDst, x, y, dstWidth, dstHeight,
+ hdcSrc, srcX, srcY, srcWidth, srcHeight,
bf) )
{
// skip wxAlphaBlend() call below
// AlphaBlend() unavailable of failed: use our own (probably much slower)
// implementation
#ifdef wxHAVE_RAW_BITMAP
- wxAlphaBlend(hdcDst, x, y, width, height, srcX, srcY, bmp);
+ wxAlphaBlend(hdcDst, x, y, dstWidth, dstHeight, srcX, srcY, srcWidth, srcHeight, bmp);
return true;
#else // !wxHAVE_RAW_BITMAP
static void
wxAlphaBlend(HDC hdcDst, int xDst, int yDst,
- int w, int h,
- int srcX, int srcY, const wxBitmap& bmpSrc)
+ int dstWidth, int dstHeight,
+ int srcX, int srcY,
+ int srcWidth, int srcHeight,
+ const wxBitmap& bmpSrc)
{
// get the destination DC pixels
- wxBitmap bmpDst(w, h, 32 /* force creating RGBA DIB */);
+ wxBitmap bmpDst(dstWidth, dstHeight, 32 /* force creating RGBA DIB */);
MemoryHDC hdcMem;
SelectInHDC select(hdcMem, GetHbitmapOf(bmpDst));
- if ( !::BitBlt(hdcMem, 0, 0, w, h, hdcDst, xDst, yDst, SRCCOPY) )
+ if ( !::BitBlt(hdcMem, 0, 0, dstWidth, dstHeight, hdcDst, xDst, yDst, SRCCOPY) )
{
wxLogLastError(_T("BitBlt"));
}
wxAlphaPixelData::Iterator pDst(dataDst),
pSrc(dataSrc);
- pSrc.Offset(dataSrc, srcX, srcY);
- for ( int y = 0; y < h; y++ )
+ for ( int y = 0; y < dstHeight; y++ )
{
- wxAlphaPixelData::Iterator pDstRowStart = pDst,
- pSrcRowStart = pSrc;
+ wxAlphaPixelData::Iterator pDstRowStart = pDst;
- for ( int x = 0; x < w; x++ )
+ for ( int x = 0; x < dstWidth; x++ )
{
+ // source is point sampled, Alpha StretchBlit is ugly on Win95
+ // (but does not impact performance)
+ pSrc.MoveTo(dataSrc, srcX + (srcWidth*x/dstWidth), srcY + (srcHeight*y/dstHeight));
+
// note that source bitmap uses premultiplied alpha (as required by
// the real AlphaBlend)
const unsigned beta = 255 - pSrc.Alpha();
pDst.Green() = pSrc.Green() + (beta * pDst.Green() + 127) / 255;
++pDst;
- ++pSrc;
}
pDst = pDstRowStart;
- pSrc = pSrcRowStart;
pDst.OffsetY(dataDst, 1);
- pSrc.OffsetY(dataSrc, 1);
}
// and finally blit them back to the destination DC
- if ( !::BitBlt(hdcDst, xDst, yDst, w, h, hdcMem, 0, 0, SRCCOPY) )
+ if ( !::BitBlt(hdcDst, xDst, yDst, dstWidth, dstHeight, hdcMem, 0, 0, SRCCOPY) )
{
wxLogLastError(_T("BitBlt"));
}