wxDC::StretchBlit() for wxMac and wxMSW (patch 1611973)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@44892 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2007-03-18 15:32:27 +00:00
parent fa3b08caf1
commit e3b81044ee
12 changed files with 347 additions and 100 deletions

View File

@@ -65,6 +65,7 @@ All:
All (GUI): All (GUI):
- Added wxDC::StretchBlit() for wxMac and wxMSW (Vince Harron)
- Added wxEventBlocker class (Francesco Montorsi). - Added wxEventBlocker class (Francesco Montorsi).
- Added wxFile/DirPickerCtrl::Get/SetFile/DirName() (Francesco Montorsi). - Added wxFile/DirPickerCtrl::Get/SetFile/DirName() (Francesco Montorsi).
- Added wxSizerFlags::Top() and Bottom(). - Added wxSizerFlags::Top() and Bottom().

View File

@@ -108,7 +108,7 @@ See \helpref{wxMemoryDC}{wxmemorydc} for typical usage.
\wxheading{See also} \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} \begin{comment}
@@ -1198,3 +1198,84 @@ Message is a message to show while printing.
Starts a document page (only relevant when outputting to a printer). 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}

View File

@@ -313,7 +313,26 @@ public:
return DoBlit(destPt.x, destPt.y, sz.x, sz.y, return DoBlit(destPt.x, destPt.y, sz.x, sz.y,
source, srcPt.x, srcPt.y, rop, useMask, srcPtMask.x, srcPtMask.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 wxBitmap GetAsBitmap(const wxRect *subrect = (const wxRect *) NULL) const
{ {
return DoGetAsBitmap(subrect); return DoGetAsBitmap(subrect);
@@ -723,10 +742,25 @@ protected:
virtual bool DoBlit(wxCoord xdest, wxCoord ydest, virtual bool DoBlit(wxCoord xdest, wxCoord ydest,
wxCoord width, wxCoord height, wxCoord width, wxCoord height,
wxDC *source, wxCoord xsrc, wxCoord ysrc, wxDC *source,
int rop = wxCOPY, bool useMask = false, wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord) = 0; 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; } 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 DoGetSize(int *width, int *height) const = 0;
virtual void DoGetSizeMM(int* width, int* height) const = 0; virtual void DoGetSizeMM(int* width, int* height) const = 0;

View File

@@ -145,6 +145,14 @@ protected:
wxDC *source, wxCoord xsrc, wxCoord ysrc, wxDC *source, wxCoord xsrc, wxCoord ysrc,
int rop = wxCOPY, bool useMask = false, wxCoord xsrcMask = -1, wxCoord ysrcMask = -1); 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 DoGetSize(int *,int *) const;
virtual void DoGetSizeMM(int* width, int* height) const; virtual void DoGetSizeMM(int* width, int* height) const;

View File

@@ -255,6 +255,14 @@ protected:
wxDC *source, wxCoord xsrc, wxCoord ysrc, wxDC *source, wxCoord xsrc, wxCoord ysrc,
int rop = wxCOPY, bool useMask = false, wxCoord xsrcMask = -1, wxCoord ysrcMask = -1); 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() // this is gnarly - we can't even call this function DoSetClippingRegion()
// because of virtual function hiding // because of virtual function hiding

View File

@@ -214,6 +214,14 @@ protected:
wxDC *source, wxCoord xsrc, wxCoord ysrc, wxDC *source, wxCoord xsrc, wxCoord ysrc,
int rop = wxCOPY, bool useMask = false, wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord); 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() // this is gnarly - we can't even call this function DoSetClippingRegion()
// because of virtual function hiding // because of virtual function hiding
virtual void DoSetClippingRegionAsRegion(const wxRegion& region); virtual void DoSetClippingRegionAsRegion(const wxRegion& region);

View File

@@ -70,6 +70,7 @@ enum ScreenToShow
Show_Brushes, Show_Brushes,
Show_Polygons, Show_Polygons,
Show_Mask, Show_Mask,
Show_Mask_Stretch,
Show_Ops, Show_Ops,
Show_Regions, Show_Regions,
Show_Circles, Show_Circles,
@@ -178,11 +179,17 @@ public:
#endif #endif
protected: protected:
enum DrawMode
{
Draw_Normal,
Draw_Stretch
};
void DrawTestLines( int x, int y, int width, wxDC &dc ); void DrawTestLines( int x, int y, int width, wxDC &dc );
void DrawTestPoly(wxDC& dc); void DrawTestPoly(wxDC& dc);
void DrawTestBrushes(wxDC& dc); void DrawTestBrushes(wxDC& dc);
void DrawText(wxDC& dc); void DrawText(wxDC& dc);
void DrawImages(wxDC& dc); void DrawImages(wxDC& dc, DrawMode mode);
void DrawWithLogicalOps(wxDC& dc); void DrawWithLogicalOps(wxDC& dc);
#if wxUSE_GRAPHICS_CONTEXT #if wxUSE_GRAPHICS_CONTEXT
void DrawAlpha(wxDC& dc); void DrawAlpha(wxDC& dc);
@@ -227,6 +234,7 @@ enum
File_ShowBrushes, File_ShowBrushes,
File_ShowPolygons, File_ShowPolygons,
File_ShowMask, File_ShowMask,
File_ShowMaskStretch,
File_ShowOps, File_ShowOps,
File_ShowRegions, File_ShowRegions,
File_ShowCircles, File_ShowCircles,
@@ -310,6 +318,7 @@ bool MyApp::LoadImages()
wxPathList pathList; wxPathList pathList;
pathList.Add(_T(".")); pathList.Add(_T("."));
pathList.Add(_T("..")); pathList.Add(_T(".."));
pathList.Add(_T("../.."));
wxString path = pathList.FindValidPath(_T("pat4.bmp")); wxString path = pathList.FindValidPath(_T("pat4.bmp"));
if ( !path ) if ( !path )
@@ -835,7 +844,7 @@ static const struct
{ wxT("wxXOR"), wxXOR }, { wxT("wxXOR"), wxXOR },
}; };
void MyCanvas::DrawImages(wxDC& dc) void MyCanvas::DrawImages(wxDC& dc, DrawMode mode)
{ {
dc.DrawText(_T("original image"), 0, 0); dc.DrawText(_T("original image"), 0, 0);
dc.DrawBitmap(*gs_bmpNoMask, 0, 20, 0); dc.DrawBitmap(*gs_bmpNoMask, 0, 20, 0);
@@ -857,7 +866,15 @@ void MyCanvas::DrawImages(wxDC& dc)
dc.DrawText(rasterOperations[n].name, x, y - 20); dc.DrawText(rasterOperations[n].name, x, y - 20);
memDC.SelectObject(*gs_bmpWithColMask); 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);
}
} }
} }
@@ -912,32 +929,32 @@ void MyCanvas::DrawAlpha(wxDC& dc)
wxDouble margin = 20 ; wxDouble margin = 20 ;
wxDouble width = 180 ; wxDouble width = 180 ;
wxDouble radius = 30 ; wxDouble radius = 30 ;
dc.SetPen( wxPen( wxColour( 128, 0, 0, 255 ),12, wxSOLID)); dc.SetPen( wxPen( wxColour( 128, 0, 0, 255 ),12, wxSOLID));
dc.SetBrush( wxBrush( wxColour( 255, 0, 0, 255),wxSOLID)); dc.SetBrush( wxBrush( wxColour( 255, 0, 0, 255),wxSOLID));
wxRect r(margin,margin+width*0.66,width,width) ; wxRect r(margin,margin+width*0.66,width,width) ;
dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ; dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ;
dc.SetPen( wxPen( wxColour( 0, 0, 128, 255 ),12, wxSOLID)); dc.SetPen( wxPen( wxColour( 0, 0, 128, 255 ),12, wxSOLID));
dc.SetBrush( wxBrush( wxColour( 0, 0, 255, 255),wxSOLID)); dc.SetBrush( wxBrush( wxColour( 0, 0, 255, 255),wxSOLID));
r.Offset( width * 0.8 , - width * 0.66 ) ; r.Offset( width * 0.8 , - width * 0.66 ) ;
dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ; dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ;
dc.SetPen( wxPen( wxColour( 128, 128, 0, 255 ),12, wxSOLID)); dc.SetPen( wxPen( wxColour( 128, 128, 0, 255 ),12, wxSOLID));
dc.SetBrush( wxBrush( wxColour( 192, 192, 0, 255),wxSOLID)); dc.SetBrush( wxBrush( wxColour( 192, 192, 0, 255),wxSOLID));
r.Offset( width * 0.8 , width *0.5 ) ; r.Offset( width * 0.8 , width *0.5 ) ;
dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ; dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ;
dc.SetPen( *wxTRANSPARENT_PEN ) ; dc.SetPen( *wxTRANSPARENT_PEN ) ;
dc.SetBrush( wxBrush( wxColour(255,255,128,128) ) ); dc.SetBrush( wxBrush( wxColour(255,255,128,128) ) );
dc.DrawRoundedRectangle( 0 , margin + width / 2 , width * 3 , 100 , radius) ; dc.DrawRoundedRectangle( 0 , margin + width / 2 , width * 3 , 100 , radius) ;
dc.SetTextForeground( wxColour(255,255,0,128) ); dc.SetTextForeground( wxColour(255,255,0,128) );
dc.SetFont( wxFont( 40, wxFONTFAMILY_SWISS, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL ) ); dc.SetFont( wxFont( 40, wxFONTFAMILY_SWISS, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL ) );
dc.DrawText( wxT("Hello!"), 120, 80 ); dc.DrawText( wxT("Hello!"), 120, 80 );
@@ -976,9 +993,9 @@ void MyCanvas::DrawCircles(wxDC& dc)
dc.DrawEllipticArc(x + r, y, 2*r, r, 90, 180); dc.DrawEllipticArc(x + r, y, 2*r, r, 90, 180);
dc.DrawEllipticArc(x + 3*r, y, 2*r, r, 180, 270); dc.DrawEllipticArc(x + 3*r, y, 2*r, r, 180, 270);
dc.DrawEllipticArc(x + 5*r, y, 2*r, r, 270, 360); dc.DrawEllipticArc(x + 5*r, y, 2*r, r, 270, 360);
// same as above, just transparent brush // same as above, just transparent brush
dc.SetPen( *wxRED_PEN ); dc.SetPen( *wxRED_PEN );
dc.SetBrush( *wxTRANSPARENT_BRUSH ); dc.SetBrush( *wxTRANSPARENT_BRUSH );
@@ -1005,7 +1022,7 @@ void MyCanvas::DrawCircles(wxDC& dc)
dc.DrawEllipticArc(x + r, y, 2*r, r, 90, 180); dc.DrawEllipticArc(x + r, y, 2*r, r, 90, 180);
dc.DrawEllipticArc(x + 3*r, y, 2*r, r, 180, 270); dc.DrawEllipticArc(x + 3*r, y, 2*r, r, 180, 270);
dc.DrawEllipticArc(x + 5*r, y, 2*r, r, 270, 360); dc.DrawEllipticArc(x + 5*r, y, 2*r, r, 270, 360);
} }
void MyCanvas::DrawSplines(wxDC& dc) void MyCanvas::DrawSplines(wxDC& dc)
@@ -1280,13 +1297,17 @@ void MyCanvas::OnPaint(wxPaintEvent &WXUNUSED(event))
break; break;
case Show_Mask: case Show_Mask:
DrawImages(dc); DrawImages(dc, Draw_Normal);
break;
case Show_Mask_Stretch:
DrawImages(dc, Draw_Stretch);
break; break;
case Show_Ops: case Show_Ops:
DrawWithLogicalOps(dc); DrawWithLogicalOps(dc);
break; break;
#if wxUSE_GRAPHICS_CONTEXT #if wxUSE_GRAPHICS_CONTEXT
case Show_Alpha: case Show_Alpha:
DrawAlpha(dc); DrawAlpha(dc);
@@ -1355,6 +1376,7 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
menuFile->Append(File_ShowBrushes, _T("&Brushes screen\tF4")); menuFile->Append(File_ShowBrushes, _T("&Brushes screen\tF4"));
menuFile->Append(File_ShowPolygons, _T("&Polygons screen\tF5")); menuFile->Append(File_ShowPolygons, _T("&Polygons screen\tF5"));
menuFile->Append(File_ShowMask, _T("&Mask screen\tF6")); 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_ShowOps, _T("&ROP screen\tF7"));
menuFile->Append(File_ShowRegions, _T("Re&gions screen\tF8")); menuFile->Append(File_ShowRegions, _T("Re&gions screen\tF8"));
menuFile->Append(File_ShowCircles, _T("&Circles screen\tF9")); menuFile->Append(File_ShowCircles, _T("&Circles screen\tF9"));

View File

@@ -78,6 +78,27 @@ void wxDCBase::DoDrawCheckMark(wxCoord x1, wxCoord y1,
CalcBoundingBox(x2, y2); 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 // line/polygons
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -734,7 +755,7 @@ void wxDCBase::DoGradientFillLinear(const wxRect& rect,
else else
nB = nB1 + (nB2-nB1)*(w-x)/w; nB = nB1 + (nB2-nB1)*(w-x)/w;
wxColour colour(nR,nG,nB); wxColour colour(nR,nG,nB);
SetPen(wxPen(colour, 1, wxSOLID)); SetPen(wxPen(colour, 1, wxSOLID));
SetBrush(wxBrush(colour)); SetBrush(wxBrush(colour));
if(nDirection == wxEAST) if(nDirection == wxEAST)
@@ -771,7 +792,7 @@ void wxDCBase::DoGradientFillLinear(const wxRect& rect,
else else
nB = nB1 + (nB2-nB1)*(w-y)/w; nB = nB1 + (nB2-nB1)*(w-y)/w;
wxColour colour(nR,nG,nB); wxColour colour(nR,nG,nB);
SetPen(wxPen(colour, 1, wxSOLID)); SetPen(wxPen(colour, 1, wxSOLID));
SetBrush(wxBrush(colour)); SetBrush(wxBrush(colour));
if(nDirection == wxNORTH) if(nDirection == wxNORTH)
@@ -1156,4 +1177,4 @@ void wxDCBase::CalculateEllipticPoints( wxList* points,
} // not iUseAngles } // not iUseAngles
} // CalculateEllipticPoints } // CalculateEllipticPoints
#endif #endif // __WXWINCE__

View File

@@ -718,11 +718,22 @@ bool wxGCDC::CanDrawBitmap() const
bool wxGCDC::DoBlit( bool wxGCDC::DoBlit(
wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, 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 ) wxCoord xsrcMask, wxCoord ysrcMask )
{ {
wxCHECK_MSG( Ok(), false, wxT("wxGCDC(cg)::DoBlit - invalid DC") ); return DoStretchBlit( xdest, ydest, width, height,
wxCHECK_MSG( source->Ok(), false, wxT("wxGCDC(cg)::DoBlit - invalid source DC") ); 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 ) if ( logical_func == wxNO_OP )
return true; return true;
@@ -740,8 +751,8 @@ bool wxGCDC::DoBlit(
wxRect subrect(source->LogicalToDeviceX(xsrc), wxRect subrect(source->LogicalToDeviceX(xsrc),
source->LogicalToDeviceY(ysrc), source->LogicalToDeviceY(ysrc),
source->LogicalToDeviceXRel(width), source->LogicalToDeviceXRel(srcWidth),
source->LogicalToDeviceYRel(height)); source->LogicalToDeviceYRel(srcHeight));
// if needed clip the subrect down to the size of the source DC // if needed clip the subrect down to the size of the source DC
wxCoord sw, sh; wxCoord sw, sh;
@@ -758,8 +769,7 @@ bool wxGCDC::DoBlit(
if ( blit.Ok() ) if ( blit.Ok() )
{ {
m_graphicContext->DrawBitmap( blit, xdest, ydest, m_graphicContext->DrawBitmap( blit, xdest, ydest,
wxMin(width, blit.GetWidth()), dstWidth, dstHeight);
wxMin(height, blit.GetHeight()));
} }
else else
{ {

View File

@@ -1175,12 +1175,26 @@ bool wxDC::CanDrawBitmap(void) const
return true ; 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, wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func , bool useMask,
wxCoord xsrcMask, wxCoord ysrcMask ) wxCoord xsrcMask, wxCoord ysrcMask )
{ {
wxCHECK_MSG(Ok(), false, wxT("wxDC::DoBlit - invalid DC")); return DoStretchBlit( xdest, ydest, dstWidth, dstHeight,
wxCHECK_MSG(source->Ok(), false, wxT("wxDC::DoBlit - invalid source DC")); 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 ) if ( logical_func == wxNO_OP )
return true ; return true ;
@@ -1198,12 +1212,12 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
Rect srcrect , dstrect ; Rect srcrect , dstrect ;
srcrect.top = source->YLOG2DEVMAC(ysrc) ; srcrect.top = source->YLOG2DEVMAC(ysrc) ;
srcrect.left = source->XLOG2DEVMAC(xsrc) ; srcrect.left = source->XLOG2DEVMAC(xsrc) ;
srcrect.right = source->XLOG2DEVMAC(xsrc + width ) ; srcrect.right = source->XLOG2DEVMAC(xsrc + srcWidth ) ;
srcrect.bottom = source->YLOG2DEVMAC(ysrc + height) ; srcrect.bottom = source->YLOG2DEVMAC(ysrc + srcHeight) ;
dstrect.top = YLOG2DEVMAC(ydest) ; dstrect.top = YLOG2DEVMAC(ydest) ;
dstrect.left = XLOG2DEVMAC(xdest) ; dstrect.left = XLOG2DEVMAC(xdest) ;
dstrect.bottom = YLOG2DEVMAC(ydest + height ) ; dstrect.bottom = YLOG2DEVMAC(ydest + dstHeight ) ;
dstrect.right = XLOG2DEVMAC(xdest + width ) ; dstrect.right = XLOG2DEVMAC(xdest + dstWidth ) ;
short mode = kUnsupportedMode ; short mode = kUnsupportedMode ;
bool invertDestinationFirst = false ; bool invertDestinationFirst = false ;

View File

@@ -2021,8 +2021,22 @@ bool wxDC::DoBlit(
wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func , bool useMask, wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func , bool useMask,
wxCoord xsrcMask, wxCoord ysrcMask ) wxCoord xsrcMask, wxCoord ysrcMask )
{ {
wxCHECK_MSG( Ok(), false, wxT("wxDC(cg)::DoBlit - invalid DC") ); return DoStretchBlit( xdest, ydest, width, height,
wxCHECK_MSG( source->Ok(), false, wxT("wxDC(cg)::DoBlit - invalid source DC") ); 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 ) if ( logical_func == wxNO_OP )
return true ; return true ;
@@ -2035,13 +2049,13 @@ bool wxDC::DoBlit(
wxCoord yysrc = source->YLOG2DEVMAC(ysrc) ; wxCoord yysrc = source->YLOG2DEVMAC(ysrc) ;
wxCoord xxsrc = source->XLOG2DEVMAC(xsrc) ; wxCoord xxsrc = source->XLOG2DEVMAC(xsrc) ;
wxCoord wwsrc = source->XLOG2DEVREL(width) ; wxCoord wwsrc = source->XLOG2DEVREL(srcWidth) ;
wxCoord hhsrc = source->YLOG2DEVREL(height) ; wxCoord hhsrc = source->YLOG2DEVREL(srcHeight) ;
wxCoord yydest = YLOG2DEVMAC(ydest) ; wxCoord yydest = YLOG2DEVMAC(ydest) ;
wxCoord xxdest = XLOG2DEVMAC(xdest) ; wxCoord xxdest = XLOG2DEVMAC(xdest) ;
wxCoord wwdest = XLOG2DEVREL(width) ; wxCoord wwdest = XLOG2DEVREL(dstWidth) ;
wxCoord hhdest = YLOG2DEVREL(height) ; wxCoord hhdest = YLOG2DEVREL(dstHeight) ;
wxMemoryDC* memdc = dynamic_cast<wxMemoryDC*>(source) ; wxMemoryDC* memdc = dynamic_cast<wxMemoryDC*>(source) ;
if ( memdc && logical_func == wxCOPY ) if ( memdc && logical_func == wxCOPY )

View File

@@ -130,16 +130,21 @@ static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; }
// return true if we could draw the bitmap in one way or the other, false // return true if we could draw the bitmap in one way or the other, false
// otherwise // otherwise
static bool AlphaBlt(HDC hdcDst, static bool AlphaBlt(HDC hdcDst,
int x, int y, int w, int h, int x, int y, int dstWidth, int dstHeight,
int srcX, int srcY, HDC hdcSrc, int srcX, int srcY,
const wxBitmap& bmpSrc); int srcWidth, int srcHeight,
HDC hdcSrc,
const wxBitmap& bmp);
#ifdef wxHAVE_RAW_BITMAP #ifdef wxHAVE_RAW_BITMAP
// our (limited) AlphaBlend() replacement for Windows versions not providing it // our (limited) AlphaBlend() replacement for Windows versions not providing it
static void static void
wxAlphaBlend(HDC hdcDst, int x, int y, int w, int h, wxAlphaBlend(HDC hdcDst, int xDst, int yDst,
int srcX, int srcY, const wxBitmap& bmp); int dstWidth, int dstHeight,
int srcX, int srcY,
int srcWidth, int srcHeight,
const wxBitmap& bmpSrc);
#endif // wxHAVE_RAW_BITMAP #endif // wxHAVE_RAW_BITMAP
@@ -1183,7 +1188,7 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask
MemoryHDC hdcMem; MemoryHDC hdcMem;
SelectInHDC select(hdcMem, GetHbitmapOf(bmp)); 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; return;
} }
@@ -2046,12 +2051,23 @@ wxCoord wxDCBase::LogicalToDeviceYRel(wxCoord y) const
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// bit blit // bit blit
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
bool wxDC::DoBlit(wxCoord dstX, wxCoord dstY,
bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord dstWidth, wxCoord dstHeight,
wxCoord width, wxCoord height, wxDC *source,
wxDC *source, wxCoord xsrc, wxCoord ysrc, wxCoord srcX, wxCoord srcY,
int rop, bool useMask, 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") ); wxCHECK_MSG( source, false, _T("wxDC::Blit(): NULL wxDC pointer") );
@@ -2063,8 +2079,8 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
if ( bmpSrc.Ok() && (bmpSrc.HasAlpha() || if ( bmpSrc.Ok() && (bmpSrc.HasAlpha() ||
(m_selectedBitmap.Ok() && m_selectedBitmap.HasAlpha())) ) (m_selectedBitmap.Ok() && m_selectedBitmap.HasAlpha())) )
{ {
if ( AlphaBlt(GetHdc(), xdest, ydest, width, height, if ( AlphaBlt(GetHdc(), xdest, ydest, dstWidth, dstHeight,
xsrc, ysrc, GetHdcOf(*source), bmpSrc) ) xsrc, ysrc, srcWidth, srcHeight, GetHdcOf(*source), bmpSrc) )
return true; return true;
} }
@@ -2138,16 +2154,19 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
if (wxSystemOptions::GetOptionInt(wxT("no-maskblt")) == 0) if (wxSystemOptions::GetOptionInt(wxT("no-maskblt")) == 0)
#endif #endif
{ {
success = ::MaskBlt if ( dstWidth == srcWidth && dstHeight == srcHeight )
( {
success = ::MaskBlt
(
GetHdc(), GetHdc(),
xdest, ydest, width, height, xdest, ydest, dstWidth, dstHeight,
GetHdcOf(*source), GetHdcOf(*source),
xsrc, ysrc, xsrc, ysrc,
(HBITMAP)mask->GetMaskBitmap(), (HBITMAP)mask->GetMaskBitmap(),
xsrcMask, ysrcMask, xsrcMask, ysrcMask,
MAKEROP4(dwRop, DSTCOPY) MAKEROP4(dwRop, DSTCOPY)
) != 0; ) != 0;
}
} }
if ( !success ) if ( !success )
@@ -2167,55 +2186,59 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
dc_buffer = (HDC) dcCacheEntry2->m_dc; dc_buffer = (HDC) dcCacheEntry2->m_dc;
wxDCCacheEntry* bitmapCacheEntry = FindBitmapInCache(GetHDC(), wxDCCacheEntry* bitmapCacheEntry = FindBitmapInCache(GetHDC(),
width, height); dstWidth, dstHeight);
buffer_bmap = (HBITMAP) bitmapCacheEntry->m_bitmap; buffer_bmap = (HBITMAP) bitmapCacheEntry->m_bitmap;
#else // !wxUSE_DC_CACHEING #else // !wxUSE_DC_CACHEING
// create a temp buffer bitmap and DCs to access it and the mask // create a temp buffer bitmap and DCs to access it and the mask
dc_mask = ::CreateCompatibleDC(GetHdcOf(*source)); dc_mask = ::CreateCompatibleDC(GetHdcOf(*source));
dc_buffer = ::CreateCompatibleDC(GetHdc()); dc_buffer = ::CreateCompatibleDC(GetHdc());
buffer_bmap = ::CreateCompatibleBitmap(GetHdc(), width, height); buffer_bmap = ::CreateCompatibleBitmap(GetHdc(), dstWidth, dstHeight);
#endif // wxUSE_DC_CACHEING/!wxUSE_DC_CACHEING #endif // wxUSE_DC_CACHEING/!wxUSE_DC_CACHEING
HGDIOBJ hOldMaskBitmap = ::SelectObject(dc_mask, (HBITMAP) mask->GetMaskBitmap()); HGDIOBJ hOldMaskBitmap = ::SelectObject(dc_mask, (HBITMAP) mask->GetMaskBitmap());
HGDIOBJ hOldBufferBitmap = ::SelectObject(dc_buffer, buffer_bmap); HGDIOBJ hOldBufferBitmap = ::SelectObject(dc_buffer, buffer_bmap);
// copy dest to buffer // 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) ) GetHdc(), xdest, ydest, SRCCOPY) )
{ {
wxLogLastError(wxT("BitBlt")); wxLogLastError(wxT("BitBlt"));
} }
#ifndef __WXWINCE__
StretchBltModeChanger changeMode(dc_buffer, COLORONCOLOR);
#endif
// copy src to buffer using selected raster op // copy src to buffer using selected raster op
if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height, if ( !::StretchBlt(dc_buffer, 0, 0, (int)dstWidth, (int)dstHeight,
GetHdcOf(*source), xsrc, ysrc, dwRop) ) GetHdcOf(*source), xsrc, ysrc, srcWidth, srcHeight, dwRop) )
{ {
wxLogLastError(wxT("BitBlt")); wxLogLastError(wxT("StretchBlt"));
} }
// set masked area in buffer to BLACK (pixel value 0) // set masked area in buffer to BLACK (pixel value 0)
COLORREF prevBkCol = ::SetBkColor(GetHdc(), RGB(255, 255, 255)); COLORREF prevBkCol = ::SetBkColor(GetHdc(), RGB(255, 255, 255));
COLORREF prevCol = ::SetTextColor(GetHdc(), RGB(0, 0, 0)); COLORREF prevCol = ::SetTextColor(GetHdc(), RGB(0, 0, 0));
if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height, if ( !::StretchBlt(dc_buffer, 0, 0, (int)dstWidth, (int)dstHeight,
dc_mask, xsrcMask, ysrcMask, SRCAND) ) dc_mask, xsrcMask, ysrcMask, srcWidth, srcHeight, SRCAND) )
{ {
wxLogLastError(wxT("BitBlt")); wxLogLastError(wxT("StretchBlt"));
} }
// set unmasked area in dest to BLACK // set unmasked area in dest to BLACK
::SetBkColor(GetHdc(), RGB(0, 0, 0)); ::SetBkColor(GetHdc(), RGB(0, 0, 0));
::SetTextColor(GetHdc(), RGB(255, 255, 255)); ::SetTextColor(GetHdc(), RGB(255, 255, 255));
if ( !::BitBlt(GetHdc(), xdest, ydest, (int)width, (int)height, if ( !::StretchBlt(GetHdc(), xdest, ydest, (int)dstWidth, (int)dstHeight,
dc_mask, xsrcMask, ysrcMask, SRCAND) ) dc_mask, xsrcMask, ysrcMask, srcWidth, srcHeight, SRCAND) )
{ {
wxLogLastError(wxT("BitBlt")); wxLogLastError(wxT("StretchBlt"));
} }
::SetBkColor(GetHdc(), prevBkCol); // restore colours to original values ::SetBkColor(GetHdc(), prevBkCol); // restore colours to original values
::SetTextColor(GetHdc(), prevCol); ::SetTextColor(GetHdc(), prevCol);
// OR buffer to dest // OR buffer to dest
success = ::BitBlt(GetHdc(), xdest, ydest, success = ::BitBlt(GetHdc(), xdest, ydest,
(int)width, (int)height, (int)dstWidth, (int)dstHeight,
dc_buffer, 0, 0, SRCPAINT) != 0; dc_buffer, 0, 0, SRCPAINT) != 0;
if ( !success ) if ( !success )
{ {
@@ -2260,14 +2283,14 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
if ( hDIB > 0 ) if ( hDIB > 0 )
{ {
// reflect ysrc // reflect ysrc
ysrc = hDIB - (ysrc + height); ysrc = hDIB - (ysrc + dstHeight);
} }
if ( ::StretchDIBits(GetHdc(), if ( ::StretchDIBits(GetHdc(),
xdest, ydest, xdest, ydest,
width, height, dstWidth, dstHeight,
xsrc, ysrc, xsrc, ysrc,
width, height, srcWidth, srcHeight,
ds.dsBm.bmBits, ds.dsBm.bmBits,
(LPBITMAPINFO)&ds.dsBmih, (LPBITMAPINFO)&ds.dsBmih,
DIB_RGB_COLORS, DIB_RGB_COLORS,
@@ -2298,9 +2321,9 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
if ( !::StretchBlt if ( !::StretchBlt
( (
GetHdc(), GetHdc(),
xdest, ydest, width, height, xdest, ydest, dstWidth, dstHeight,
GetHdcOf(*source), GetHdcOf(*source),
xsrc, ysrc, width, height, xsrc, ysrc, srcWidth, srcHeight,
dwRop dwRop
) ) ) )
{ {
@@ -2318,7 +2341,7 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
( (
GetHdc(), GetHdc(),
xdest, ydest, xdest, ydest,
(int)width, (int)height, (int)dstWidth, (int)dstHeight,
GetHdcOf(*source), GetHdcOf(*source),
xsrc, ysrc, xsrc, ysrc,
dwRop dwRop
@@ -2540,8 +2563,10 @@ IMPLEMENT_DYNAMIC_CLASS(wxDCModule, wxModule)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
static bool AlphaBlt(HDC hdcDst, static bool AlphaBlt(HDC hdcDst,
int x, int y, int width, int height, int x, int y, int dstWidth, int dstHeight,
int srcX, int srcY, HDC hdcSrc, int srcX, int srcY,
int srcWidth, int srcHeight,
HDC hdcSrc,
const wxBitmap& bmp) const wxBitmap& bmp)
{ {
wxASSERT_MSG( bmp.Ok() && bmp.HasAlpha(), _T("AlphaBlt(): invalid bitmap") ); wxASSERT_MSG( bmp.Ok() && bmp.HasAlpha(), _T("AlphaBlt(): invalid bitmap") );
@@ -2564,8 +2589,8 @@ static bool AlphaBlt(HDC hdcDst,
bf.SourceConstantAlpha = 0xff; bf.SourceConstantAlpha = 0xff;
bf.AlphaFormat = AC_SRC_ALPHA; bf.AlphaFormat = AC_SRC_ALPHA;
if ( pfnAlphaBlend(hdcDst, x, y, width, height, if ( pfnAlphaBlend(hdcDst, x, y, dstWidth, dstHeight,
hdcSrc, srcX, srcY, width, height, hdcSrc, srcX, srcY, srcWidth, srcHeight,
bf) ) bf) )
{ {
// skip wxAlphaBlend() call below // skip wxAlphaBlend() call below
@@ -2581,7 +2606,7 @@ static bool AlphaBlt(HDC hdcDst,
// AlphaBlend() unavailable of failed: use our own (probably much slower) // AlphaBlend() unavailable of failed: use our own (probably much slower)
// implementation // implementation
#ifdef wxHAVE_RAW_BITMAP #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; return true;
#else // !wxHAVE_RAW_BITMAP #else // !wxHAVE_RAW_BITMAP
@@ -2598,15 +2623,17 @@ static bool AlphaBlt(HDC hdcDst,
static void static void
wxAlphaBlend(HDC hdcDst, int xDst, int yDst, wxAlphaBlend(HDC hdcDst, int xDst, int yDst,
int w, int h, int dstWidth, int dstHeight,
int srcX, int srcY, const wxBitmap& bmpSrc) int srcX, int srcY,
int srcWidth, int srcHeight,
const wxBitmap& bmpSrc)
{ {
// get the destination DC pixels // 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; MemoryHDC hdcMem;
SelectInHDC select(hdcMem, GetHbitmapOf(bmpDst)); 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")); wxLogLastError(_T("BitBlt"));
} }
@@ -2621,15 +2648,17 @@ wxAlphaBlend(HDC hdcDst, int xDst, int yDst,
wxAlphaPixelData::Iterator pDst(dataDst), wxAlphaPixelData::Iterator pDst(dataDst),
pSrc(dataSrc); 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, wxAlphaPixelData::Iterator pDstRowStart = pDst;
pSrcRowStart = pSrc;
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 // note that source bitmap uses premultiplied alpha (as required by
// the real AlphaBlend) // the real AlphaBlend)
const unsigned beta = 255 - pSrc.Alpha(); const unsigned beta = 255 - pSrc.Alpha();
@@ -2639,17 +2668,14 @@ wxAlphaBlend(HDC hdcDst, int xDst, int yDst,
pDst.Green() = pSrc.Green() + (beta * pDst.Green() + 127) / 255; pDst.Green() = pSrc.Green() + (beta * pDst.Green() + 127) / 255;
++pDst; ++pDst;
++pSrc;
} }
pDst = pDstRowStart; pDst = pDstRowStart;
pSrc = pSrcRowStart;
pDst.OffsetY(dataDst, 1); pDst.OffsetY(dataDst, 1);
pSrc.OffsetY(dataSrc, 1);
} }
// and finally blit them back to the destination DC // 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")); wxLogLastError(_T("BitBlt"));
} }