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:
parent
fa3b08caf1
commit
e3b81044ee
@ -65,6 +65,7 @@ All:
|
||||
|
||||
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().
|
||||
|
@ -108,7 +108,7 @@ See \helpref{wxMemoryDC}{wxmemorydc} for typical usage.
|
||||
|
||||
\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}
|
||||
|
||||
@ -1198,3 +1198,84 @@ Message is a message to show while printing.
|
||||
|
||||
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}
|
||||
|
||||
|
@ -314,6 +314,25 @@ public:
|
||||
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);
|
||||
@ -723,10 +742,25 @@ protected:
|
||||
|
||||
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;
|
||||
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; }
|
||||
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;
|
||||
|
@ -145,6 +145,14 @@ protected:
|
||||
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;
|
||||
|
||||
|
@ -255,6 +255,14 @@ protected:
|
||||
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
|
||||
|
||||
|
@ -214,6 +214,14 @@ protected:
|
||||
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);
|
||||
|
@ -70,6 +70,7 @@ enum ScreenToShow
|
||||
Show_Brushes,
|
||||
Show_Polygons,
|
||||
Show_Mask,
|
||||
Show_Mask_Stretch,
|
||||
Show_Ops,
|
||||
Show_Regions,
|
||||
Show_Circles,
|
||||
@ -178,11 +179,17 @@ public:
|
||||
#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);
|
||||
@ -227,6 +234,7 @@ enum
|
||||
File_ShowBrushes,
|
||||
File_ShowPolygons,
|
||||
File_ShowMask,
|
||||
File_ShowMaskStretch,
|
||||
File_ShowOps,
|
||||
File_ShowRegions,
|
||||
File_ShowCircles,
|
||||
@ -310,6 +318,7 @@ bool MyApp::LoadImages()
|
||||
wxPathList pathList;
|
||||
pathList.Add(_T("."));
|
||||
pathList.Add(_T(".."));
|
||||
pathList.Add(_T("../.."));
|
||||
|
||||
wxString path = pathList.FindValidPath(_T("pat4.bmp"));
|
||||
if ( !path )
|
||||
@ -835,7 +844,7 @@ static const struct
|
||||
{ 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);
|
||||
@ -857,9 +866,17 @@ void MyCanvas::DrawImages(wxDC& dc)
|
||||
|
||||
dc.DrawText(rasterOperations[n].name, x, y - 20);
|
||||
memDC.SelectObject(*gs_bmpWithColMask);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MyCanvas::DrawWithLogicalOps(wxDC& dc)
|
||||
{
|
||||
@ -1280,7 +1297,11 @@ void MyCanvas::OnPaint(wxPaintEvent &WXUNUSED(event))
|
||||
break;
|
||||
|
||||
case Show_Mask:
|
||||
DrawImages(dc);
|
||||
DrawImages(dc, Draw_Normal);
|
||||
break;
|
||||
|
||||
case Show_Mask_Stretch:
|
||||
DrawImages(dc, Draw_Stretch);
|
||||
break;
|
||||
|
||||
case Show_Ops:
|
||||
@ -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_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"));
|
||||
|
@ -78,6 +78,27 @@ void wxDCBase::DoDrawCheckMark(wxCoord x1, wxCoord y1,
|
||||
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
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -1156,4 +1177,4 @@ void wxDCBase::CalculateEllipticPoints( wxList* points,
|
||||
} // not iUseAngles
|
||||
} // CalculateEllipticPoints
|
||||
|
||||
#endif
|
||||
#endif // __WXWINCE__
|
||||
|
@ -718,11 +718,22 @@ bool wxGCDC::CanDrawBitmap() const
|
||||
|
||||
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;
|
||||
@ -740,8 +751,8 @@ bool wxGCDC::DoBlit(
|
||||
|
||||
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;
|
||||
@ -758,8 +769,7 @@ bool wxGCDC::DoBlit(
|
||||
if ( blit.Ok() )
|
||||
{
|
||||
m_graphicContext->DrawBitmap( blit, xdest, ydest,
|
||||
wxMin(width, blit.GetWidth()),
|
||||
wxMin(height, blit.GetHeight()));
|
||||
dstWidth, dstHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1175,12 +1175,26 @@ bool wxDC::CanDrawBitmap(void) const
|
||||
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 ;
|
||||
@ -1198,12 +1212,12 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
|
||||
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 ;
|
||||
|
||||
|
@ -2021,8 +2021,22 @@ bool wxDC::DoBlit(
|
||||
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 ;
|
||||
@ -2035,13 +2049,13 @@ bool wxDC::DoBlit(
|
||||
|
||||
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 )
|
||||
|
124
src/msw/dc.cpp
124
src/msw/dc.cpp
@ -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
|
||||
// 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
|
||||
|
||||
@ -1183,7 +1188,7 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask
|
||||
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;
|
||||
}
|
||||
|
||||
@ -2046,10 +2051,21 @@ wxCoord wxDCBase::LogicalToDeviceYRel(wxCoord y) const
|
||||
// ---------------------------------------------------------------------------
|
||||
// bit blit
|
||||
// ---------------------------------------------------------------------------
|
||||
bool wxDC::DoBlit(wxCoord dstX, wxCoord dstY,
|
||||
wxCoord dstWidth, wxCoord dstHeight,
|
||||
wxDC *source,
|
||||
wxCoord srcX, wxCoord srcY,
|
||||
int rop, bool useMask,
|
||||
wxCoord srcMaskX, wxCoord srcMaskY)
|
||||
{
|
||||
return DoStretchBlit(dstX, dstY, dstWidth, dstHeight, source, srcX, srcY, dstWidth, dstHeight, rop, useMask, srcMaskX, srcMaskY);
|
||||
}
|
||||
|
||||
bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
|
||||
wxCoord width, wxCoord height,
|
||||
wxDC *source, wxCoord xsrc, wxCoord ysrc,
|
||||
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)
|
||||
{
|
||||
@ -2063,8 +2079,8 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
|
||||
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;
|
||||
}
|
||||
|
||||
@ -2137,11 +2153,13 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
|
||||
#if wxUSE_SYSTEM_OPTIONS
|
||||
if (wxSystemOptions::GetOptionInt(wxT("no-maskblt")) == 0)
|
||||
#endif
|
||||
{
|
||||
if ( dstWidth == srcWidth && dstHeight == srcHeight )
|
||||
{
|
||||
success = ::MaskBlt
|
||||
(
|
||||
GetHdc(),
|
||||
xdest, ydest, width, height,
|
||||
xdest, ydest, dstWidth, dstHeight,
|
||||
GetHdcOf(*source),
|
||||
xsrc, ysrc,
|
||||
(HBITMAP)mask->GetMaskBitmap(),
|
||||
@ -2149,6 +2167,7 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
|
||||
MAKEROP4(dwRop, DSTCOPY)
|
||||
) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !success )
|
||||
#endif // Win32
|
||||
@ -2167,55 +2186,59 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
|
||||
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 )
|
||||
{
|
||||
@ -2260,14 +2283,14 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
|
||||
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,
|
||||
@ -2298,9 +2321,9 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
|
||||
if ( !::StretchBlt
|
||||
(
|
||||
GetHdc(),
|
||||
xdest, ydest, width, height,
|
||||
xdest, ydest, dstWidth, dstHeight,
|
||||
GetHdcOf(*source),
|
||||
xsrc, ysrc, width, height,
|
||||
xsrc, ysrc, srcWidth, srcHeight,
|
||||
dwRop
|
||||
) )
|
||||
{
|
||||
@ -2318,7 +2341,7 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
|
||||
(
|
||||
GetHdc(),
|
||||
xdest, ydest,
|
||||
(int)width, (int)height,
|
||||
(int)dstWidth, (int)dstHeight,
|
||||
GetHdcOf(*source),
|
||||
xsrc, ysrc,
|
||||
dwRop
|
||||
@ -2540,8 +2563,10 @@ IMPLEMENT_DYNAMIC_CLASS(wxDCModule, wxModule)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
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") );
|
||||
@ -2564,8 +2589,8 @@ static bool AlphaBlt(HDC hdcDst,
|
||||
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
|
||||
@ -2581,7 +2606,7 @@ static bool AlphaBlt(HDC hdcDst,
|
||||
// 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
|
||||
@ -2598,15 +2623,17 @@ static bool AlphaBlt(HDC hdcDst,
|
||||
|
||||
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"));
|
||||
}
|
||||
@ -2621,15 +2648,17 @@ wxAlphaBlend(HDC hdcDst, int xDst, int yDst,
|
||||
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();
|
||||
@ -2639,17 +2668,14 @@ wxAlphaBlend(HDC hdcDst, int xDst, int yDst,
|
||||
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"));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user