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:
Vadim Zeitlin
2000-02-01 01:22:00 +00:00
parent 70862fa81b
commit 0bafad0cf4
3 changed files with 83 additions and 80 deletions

View File

@@ -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);

View File

@@ -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;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -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);
} }
} }