1. some fixes for the problems reported by BoundsChecker
2. filled rectangles without outline are one pixel taller/wider git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5771 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -857,7 +857,7 @@ wxBitmap wxImage::ConvertToBitmap() const
|
|||||||
if( HasMask() )
|
if( HasMask() )
|
||||||
{
|
{
|
||||||
hbitmap = ::CreateBitmap( (WORD)width, (WORD)bmpHeight, 1, 1, NULL );
|
hbitmap = ::CreateBitmap( (WORD)width, (WORD)bmpHeight, 1, 1, NULL );
|
||||||
::SelectObject( memdc, hbitmap);
|
HGDIOBJ hbmpOld = ::SelectObject( memdc, hbitmap);
|
||||||
if( numDIB == 1 ) height = bmpHeight;
|
if( numDIB == 1 ) height = bmpHeight;
|
||||||
else height = sizeLimit/bytePerLine;
|
else height = sizeLimit/bytePerLine;
|
||||||
lpDIBh->bmiHeader.biHeight = (DWORD)(-height);
|
lpDIBh->bmiHeader.biHeight = (DWORD)(-height);
|
||||||
@@ -917,10 +917,11 @@ wxBitmap wxImage::ConvertToBitmap() const
|
|||||||
wxMask *mask = new wxMask( bitmap, colour );
|
wxMask *mask = new wxMask( bitmap, colour );
|
||||||
bitmap.SetMask( mask );
|
bitmap.SetMask( mask );
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
::SelectObject( memdc, hbmpOld );
|
||||||
}
|
}
|
||||||
|
|
||||||
// free allocated resources
|
// free allocated resources
|
||||||
::SelectObject( memdc, 0 );
|
|
||||||
::DeleteDC( memdc );
|
::DeleteDC( memdc );
|
||||||
::ReleaseDC(NULL, hdc);
|
::ReleaseDC(NULL, hdc);
|
||||||
free(lpDIBh);
|
free(lpDIBh);
|
||||||
|
@@ -656,20 +656,29 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
|
|||||||
wxLogLastError("CreateCompatibleDC");
|
wxLogLastError("CreateCompatibleDC");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !::SelectObject(srcDC, GetHbitmapOf(bitmap)) )
|
bool ok = TRUE;
|
||||||
|
|
||||||
|
HGDIOBJ hbmpSrcOld = ::SelectObject(srcDC, GetHbitmapOf(bitmap));
|
||||||
|
if ( !hbmpSrcOld )
|
||||||
{
|
{
|
||||||
wxLogLastError("SelectObject");
|
wxLogLastError("SelectObject");
|
||||||
|
|
||||||
|
ok = FALSE;
|
||||||
}
|
}
|
||||||
if ( !::SelectObject(destDC, (HBITMAP)m_maskBitmap) )
|
|
||||||
|
HGDIOBJ hbmpDstOld = ::SelectObject(destDC, (HBITMAP)m_maskBitmap);
|
||||||
|
if ( !hbmpDstOld )
|
||||||
{
|
{
|
||||||
wxLogLastError("SelectObject");
|
wxLogLastError("SelectObject");
|
||||||
|
|
||||||
|
ok = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is not very efficient, but I can't think of a better way of doing
|
// this is not very efficient, but I can't think of a better way of doing
|
||||||
// it
|
// it
|
||||||
for ( int w = 0; w < width; w++ )
|
for ( int w = 0; ok && (w < width); w++ )
|
||||||
{
|
{
|
||||||
for ( int h = 0; h < height; h++ )
|
for ( int h = 0; ok && (h < height); h++ )
|
||||||
{
|
{
|
||||||
COLORREF col = GetPixel(srcDC, w, h);
|
COLORREF col = GetPixel(srcDC, w, h);
|
||||||
if ( col == CLR_INVALID )
|
if ( col == CLR_INVALID )
|
||||||
@@ -677,12 +686,9 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
|
|||||||
wxLogLastError("GetPixel");
|
wxLogLastError("GetPixel");
|
||||||
|
|
||||||
// doesn't make sense to continue
|
// doesn't make sense to continue
|
||||||
::SelectObject(srcDC, 0);
|
ok = FALSE;
|
||||||
::DeleteDC(srcDC);
|
|
||||||
::SelectObject(destDC, 0);
|
|
||||||
::DeleteDC(destDC);
|
|
||||||
|
|
||||||
return FALSE;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( col == maskColour )
|
if ( col == maskColour )
|
||||||
@@ -696,12 +702,12 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::SelectObject(srcDC, 0);
|
::SelectObject(srcDC, hbmpSrcOld);
|
||||||
::DeleteDC(srcDC);
|
::DeleteDC(srcDC);
|
||||||
::SelectObject(destDC, 0);
|
::SelectObject(destDC, hbmpDstOld);
|
||||||
::DeleteDC(destDC);
|
::DeleteDC(destDC);
|
||||||
|
|
||||||
return TRUE;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
128
src/msw/dc.cpp
128
src/msw/dc.cpp
@@ -289,23 +289,34 @@ void wxDC::Clear()
|
|||||||
|
|
||||||
void wxDC::DoFloodFill(wxCoord x, wxCoord y, const wxColour& col, int style)
|
void wxDC::DoFloodFill(wxCoord x, wxCoord y, const wxColour& col, int style)
|
||||||
{
|
{
|
||||||
(void)ExtFloodFill(GetHdc(), XLOG2DEV(x), YLOG2DEV(y),
|
if ( !::ExtFloodFill(GetHdc(), XLOG2DEV(x), YLOG2DEV(y),
|
||||||
col.GetPixel(),
|
col.GetPixel(),
|
||||||
style == wxFLOOD_SURFACE ? FLOODFILLSURFACE
|
style == wxFLOOD_SURFACE ? FLOODFILLSURFACE
|
||||||
: FLOODFILLBORDER);
|
: FLOODFILLBORDER) )
|
||||||
|
{
|
||||||
|
// quoting from the MSDN docs:
|
||||||
|
//
|
||||||
|
// Following are some of the reasons this function might fail:
|
||||||
|
//
|
||||||
|
// * The filling could not be completed.
|
||||||
|
// * The specified point has the boundary color specified by the
|
||||||
|
// crColor parameter (if FLOODFILLBORDER was requested).
|
||||||
|
// * The specified point does not have the color specified by
|
||||||
|
// crColor (if FLOODFILLSURFACE was requested)
|
||||||
|
// * The point is outside the clipping region that is, it is not
|
||||||
|
// visible on the device.
|
||||||
|
//
|
||||||
|
wxLogLastError("ExtFloodFill");
|
||||||
|
}
|
||||||
|
|
||||||
CalcBoundingBox(x, y);
|
CalcBoundingBox(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxDC::DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const
|
bool wxDC::DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const
|
||||||
{
|
{
|
||||||
// added by steve 29.12.94 (copied from DrawPoint)
|
|
||||||
// returns TRUE for pixels in the color of the current pen
|
|
||||||
// and FALSE for all other pixels colors
|
|
||||||
// if col is non-NULL return the color of the pixel
|
|
||||||
|
|
||||||
// get the color of the pixel
|
// get the color of the pixel
|
||||||
COLORREF pixelcolor = ::GetPixel(GetHdc(), XLOG2DEV(x), YLOG2DEV(y));
|
COLORREF pixelcolor = ::GetPixel(GetHdc(), XLOG2DEV(x), YLOG2DEV(y));
|
||||||
|
|
||||||
// get the color of the pen
|
// get the color of the pen
|
||||||
COLORREF pencolor = 0x00ffffff;
|
COLORREF pencolor = 0x00ffffff;
|
||||||
if (m_pen.Ok())
|
if (m_pen.Ok())
|
||||||
@@ -314,12 +325,16 @@ bool wxDC::DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// return the color of the pixel
|
// return the color of the pixel
|
||||||
if(col)
|
if( col )
|
||||||
col->Set(GetRValue(pixelcolor),GetGValue(pixelcolor),GetBValue(pixelcolor));
|
{
|
||||||
|
col->Set(GetRValue(pixelcolor),
|
||||||
|
GetGValue(pixelcolor),
|
||||||
|
GetBValue(pixelcolor));
|
||||||
|
}
|
||||||
|
|
||||||
// check, if color of the pixels is the same as the color
|
// check, if color of the pixels is the same as the color of the current
|
||||||
// of the current pen
|
// pen and return TRUE if it is, FALSE otherwise
|
||||||
return(pixelcolor==pencolor);
|
return pixelcolor == pencolor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxDC::DoCrossHair(wxCoord x, wxCoord y)
|
void wxDC::DoCrossHair(wxCoord x, wxCoord y)
|
||||||
@@ -497,74 +512,55 @@ void wxDC::DoDrawLines(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset
|
|||||||
|
|
||||||
void wxDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
|
void wxDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
|
||||||
{
|
{
|
||||||
COLORREF old_textground = ::GetTextColor(GetHdc());
|
COLORREF colFgOld = 0,
|
||||||
COLORREF old_background = ::GetBkColor(GetHdc());
|
colBgOld = 0;
|
||||||
if (m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE)
|
|
||||||
|
if ( m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE )
|
||||||
{
|
{
|
||||||
|
colFgOld = ::GetTextColor(GetHdc());
|
||||||
|
colBgOld = ::GetBkColor(GetHdc());
|
||||||
|
|
||||||
if (m_textForegroundColour.Ok())
|
if ( m_textForegroundColour.Ok() )
|
||||||
{ //just the oposite from what is expected see help on pattern brush
|
{
|
||||||
// 1 in mask becomes bk color
|
// just the oposite from what is expected see help on pattern brush
|
||||||
::SetBkColor(GetHdc(), m_textForegroundColour.GetPixel() );
|
// 1 in mask becomes bk color
|
||||||
}
|
::SetBkColor(GetHdc(), m_textForegroundColour.GetPixel());
|
||||||
if (m_textBackgroundColour.Ok())
|
}
|
||||||
{ //just the oposite from what is expected
|
|
||||||
// 0 in mask becomes text color
|
|
||||||
::SetTextColor(GetHdc(), m_textBackgroundColour.GetPixel() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_backgroundMode == wxTRANSPARENT)
|
if ( m_textBackgroundColour.Ok() )
|
||||||
SetBkMode(GetHdc(), TRANSPARENT);
|
{
|
||||||
else
|
// 0 in mask becomes text color
|
||||||
SetBkMode(GetHdc(), OPAQUE);
|
::SetTextColor(GetHdc(), m_textBackgroundColour.GetPixel());
|
||||||
|
}
|
||||||
|
|
||||||
|
// VZ: IMHO this does strictly nothing here
|
||||||
|
SetBkMode(GetHdc(), m_backgroundMode == wxTRANSPARENT ? TRANSPARENT
|
||||||
|
: OPAQUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCoord x2 = x + width;
|
wxCoord x2 = x + width;
|
||||||
wxCoord y2 = y + height;
|
wxCoord y2 = y + height;
|
||||||
|
|
||||||
/* MATTHEW: [6] new normalization */
|
// Windows draws the filled rectangles without outline (i.e. drawn with a
|
||||||
#if WX_STANDARD_GRAPHICS
|
// transparent pen) one pixel smaller in both directions and we want them
|
||||||
bool do_brush, do_pen;
|
// to have the same size regardless of which pen is used - adjust
|
||||||
|
if ( m_pen.GetStyle() == wxTRANSPARENT )
|
||||||
do_brush = m_brush.Ok() && m_brush.GetStyle() != wxTRANSPARENT;
|
{
|
||||||
do_pen = m_pen.Ok() && m_pen.GetStyle() != wxTRANSPARENT;
|
x2++;
|
||||||
|
y2++;
|
||||||
if (do_brush) {
|
|
||||||
HPEN orig_pen = NULL;
|
|
||||||
|
|
||||||
if (do_pen || !m_pen.Ok())
|
|
||||||
orig_pen = (HPEN) ::SelectObject(GetHdc(), (HPEN) ::GetStockObject(NULL_PEN));
|
|
||||||
|
|
||||||
(void)Rectangle(GetHdc(), XLOG2DEV(x), YLOG2DEV(y),
|
|
||||||
XLOG2DEV(x2) + 1, YLOG2DEV(y2) + 1);
|
|
||||||
|
|
||||||
if (do_pen || !m_pen.Ok())
|
|
||||||
::SelectObject(GetHdc() , orig_pen);
|
|
||||||
}
|
}
|
||||||
if (do_pen) {
|
|
||||||
HBRUSH orig_brush = NULL;
|
|
||||||
|
|
||||||
if (do_brush || !m_brush.Ok())
|
|
||||||
orig_brush = (HBRUSH) ::SelectObject(GetHdc(), (HBRUSH) ::GetStockObject(NULL_BRUSH));
|
|
||||||
|
|
||||||
(void)Rectangle(GetHdc(), XLOG2DEV(x), YLOG2DEV(y),
|
|
||||||
XLOG2DEV(x2), YLOG2DEV(y2));
|
|
||||||
|
|
||||||
if (do_brush || !m_brush.Ok())
|
|
||||||
::SelectObject(GetHdc(), orig_brush);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
(void)Rectangle(GetHdc(), XLOG2DEV(x), YLOG2DEV(y), XLOG2DEV(x2), YLOG2DEV(y2));
|
(void)Rectangle(GetHdc(), XLOG2DEV(x), YLOG2DEV(y), XLOG2DEV(x2), YLOG2DEV(y2));
|
||||||
#endif
|
|
||||||
|
|
||||||
CalcBoundingBox(x, y);
|
CalcBoundingBox(x, y);
|
||||||
CalcBoundingBox(x2, y2);
|
CalcBoundingBox(x2, y2);
|
||||||
|
|
||||||
if (m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE)
|
if ( m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE )
|
||||||
{
|
{
|
||||||
::SetBkMode(GetHdc(), TRANSPARENT);
|
// restore the colours we changed
|
||||||
::SetTextColor(GetHdc(), old_textground);
|
::SetBkMode(GetHdc(), TRANSPARENT);
|
||||||
::SetBkColor(GetHdc(), old_background);
|
::SetTextColor(GetHdc(), colFgOld);
|
||||||
|
::SetBkColor(GetHdc(), colBgOld);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user