X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/dfde8cd35734463150078a804475402d48e4c241..281b0186b81a35b3eff658635b083b04a3cfa23c:/src/msw/dc.cpp diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp index c6bd96b073..b9a942c87f 100644 --- a/src/msw/dc.cpp +++ b/src/msw/dc.cpp @@ -175,43 +175,39 @@ void wxDC::SelectOldObjects(WXHDC dc) // clipping // --------------------------------------------------------------------------- +#define DO_SET_CLIPPING_BOX() \ +{ \ + RECT rect; \ + \ + GetClipBox(GetHdc(), &rect); \ + \ + m_clipX1 = (wxCoord) XDEV2LOG(rect.left); \ + m_clipY1 = (wxCoord) YDEV2LOG(rect.top); \ + m_clipX2 = (wxCoord) XDEV2LOG(rect.right); \ + m_clipY2 = (wxCoord) YDEV2LOG(rect.bottom); \ +} + void wxDC::DoSetClippingRegion(wxCoord cx, wxCoord cy, wxCoord cw, wxCoord ch) { m_clipping = TRUE; - m_clipX1 = (int)cx; - m_clipY1 = (int)cy; - m_clipX2 = (int)(cx + cw); - m_clipY2 = (int)(cy + ch); - - DoClipping((WXHDC) m_hDC); + IntersectClipRect(GetHdc(), XLOG2DEV(cx), YLOG2DEV(cy), + XLOG2DEV(cx + cw), YLOG2DEV(cy + ch)); + DO_SET_CLIPPING_BOX() } void wxDC::DoSetClippingRegionAsRegion(const wxRegion& region) { wxCHECK_RET( region.GetHRGN(), wxT("invalid clipping region") ); - wxRect box = region.GetBox(); - m_clipping = TRUE; - m_clipX1 = box.x; - m_clipY1 = box.y; - m_clipX2 = box.x + box.width; - m_clipY2 = box.y + box.height; #ifdef __WIN16__ SelectClipRgn(GetHdc(), (HRGN) region.GetHRGN()); #else ExtSelectClipRgn(GetHdc(), (HRGN) region.GetHRGN(), RGN_AND); #endif -} -void wxDC::DoClipping(WXHDC dc) -{ - if (m_clipping && dc) - { - IntersectClipRect((HDC) dc, XLOG2DEV(m_clipX1), YLOG2DEV(m_clipY1), - XLOG2DEV(m_clipX2), YLOG2DEV(m_clipY2)); - } + DO_SET_CLIPPING_BOX() } void wxDC::DestroyClippingRegion() @@ -318,12 +314,15 @@ bool wxDC::DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const // get the color of the pixel COLORREF pixelcolor = ::GetPixel(GetHdc(), XLOG2DEV(x), YLOG2DEV(y)); + // JACS: what was this for? +#if 0 // get the color of the pen COLORREF pencolor = 0x00ffffff; if (m_pen.Ok()) { pencolor = m_pen.GetColour().GetPixel(); } +#endif // return the color of the pixel if( col ) @@ -335,7 +334,10 @@ bool wxDC::DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const // check, if color of the pixels is the same as the color of the current // pen and return TRUE if it is, FALSE otherwise - return pixelcolor == pencolor; + // JACS, 24/02/2000: can't understand the reason for this, so returning TRUE instead. + // return pixelcolor == pencolor; + + return TRUE; } void wxDC::DoCrossHair(wxCoord x, wxCoord y) @@ -360,10 +362,9 @@ void wxDC::DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2) (void)MoveToEx(GetHdc(), XLOG2DEV(x1), YLOG2DEV(y1), NULL); (void)LineTo(GetHdc(), XLOG2DEV(x2), YLOG2DEV(y2)); - /* MATTHEW: [6] New normalization */ -#if WX_STANDARD_GRAPHICS - (void)LineTo(GetHdc(), XLOG2DEV(x2) + 1, YLOG2DEV(y2)); -#endif + // Normalization: Windows doesn't draw the last point of the line. + // But apparently neither does GTK+, so we take it out again. +// (void)LineTo(GetHdc(), XLOG2DEV(x2) + 1, YLOG2DEV(y2)); CalcBoundingBox(x1, y1); CalcBoundingBox(x2, y2); @@ -371,6 +372,31 @@ void wxDC::DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2) void wxDC::DoDrawArc(wxCoord x1,wxCoord y1,wxCoord x2,wxCoord y2, wxCoord xc, wxCoord yc) { + COLORREF colFgOld = 0, + colBgOld = 0; + + if (m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE) + { + colFgOld = ::GetTextColor(GetHdc()); + colBgOld = ::GetBkColor(GetHdc()); + + if (m_textForegroundColour.Ok()) + { //just the oposite from what is expected see help on pattern brush + // 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) + SetBkMode(GetHdc(), TRANSPARENT); + else + SetBkMode(GetHdc(), OPAQUE); + } + double dx = xc-x1; double dy = yc-y1; double radius = (double)sqrt(dx*dx+dy*dy) ;; @@ -409,6 +435,49 @@ void wxDC::DoDrawArc(wxCoord x1,wxCoord y1,wxCoord x2,wxCoord y2, wxCoord xc, wx CalcBoundingBox((wxCoord)(xc-radius), (wxCoord)(yc-radius)); CalcBoundingBox((wxCoord)(xc+radius), (wxCoord)(yc+radius)); + + if ( m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE ) + { + // restore the colours we changed + ::SetBkMode(GetHdc(), TRANSPARENT); + ::SetTextColor(GetHdc(), colFgOld); + ::SetBkColor(GetHdc(), colBgOld); + } +} + +void wxDC::DoDrawCheckMark(wxCoord x1, wxCoord y1, + wxCoord width, wxCoord height) +{ + wxCoord x2 = x1 + width, + y2 = y1 + height; + +#if defined(__WIN32__) && !defined(__SC__) + RECT rect; + rect.left = x1; + rect.top = y1; + rect.right = x2; + rect.bottom = y2; + + DrawFrameControl(GetHdc(), &rect, DFC_MENU, DFCS_MENUCHECK); +#else // Win16 + // In WIN16, draw a cross + HPEN blackPen = ::CreatePen(PS_SOLID, 1, RGB(0, 0, 0)); + HPEN whiteBrush = (HPEN)::GetStockObject(WHITE_BRUSH); + HPEN hPenOld = (HPEN)::SelectObject(GetHdc(), blackPen); + HPEN hBrushOld = (HPEN)::SelectObject(GetHdc(), whiteBrush); + ::SetROP2(GetHdc(), R2_COPYPEN); + Rectangle(GetHdc(), x1, y1, x2, y2); + MoveTo(GetHdc(), x1, y1); + LineTo(GetHdc(), x2, y2); + MoveTo(GetHdc(), x2, y1); + LineTo(GetHdc(), x1, y2); + ::SelectObject(GetHdc(), hPenOld); + ::SelectObject(GetHdc(), hBrushOld); + ::DeleteObject(blackPen); +#endif // Win32/16 + + CalcBoundingBox(x1, y1); + CalcBoundingBox(x2, y2); } void wxDC::DoDrawPoint(wxCoord x, wxCoord y) @@ -426,10 +495,13 @@ void wxDC::DoDrawPoint(wxCoord x, wxCoord y) void wxDC::DoDrawPolygon(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset,int fillStyle) { - COLORREF old_textground = ::GetTextColor(GetHdc()); - COLORREF old_background = ::GetBkColor(GetHdc()); + COLORREF colFgOld = 0, + colBgOld = 0; + if (m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE) { + colFgOld = ::GetTextColor(GetHdc()); + colBgOld = ::GetBkColor(GetHdc()); if (m_textForegroundColour.Ok()) { //just the oposite from what is expected see help on pattern brush @@ -476,11 +548,12 @@ void wxDC::DoDrawPolygon(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffs SetPolyFillMode(GetHdc(),prev); } - if (m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE) + if ( m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE ) { - ::SetBkMode(GetHdc(), TRANSPARENT); - ::SetTextColor(GetHdc(), old_textground); - ::SetBkColor(GetHdc(), old_background); + // restore the colours we changed + ::SetBkMode(GetHdc(), TRANSPARENT); + ::SetTextColor(GetHdc(), colFgOld); + ::SetBkColor(GetHdc(), colBgOld); } } @@ -542,16 +615,31 @@ void wxDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height) wxCoord x2 = x + width; wxCoord y2 = y + height; - // Windows draws the filled rectangles without outline (i.e. drawn with a - // transparent pen) one pixel smaller in both directions and we want them - // to have the same size regardless of which pen is used - adjust - if ( m_pen.GetStyle() == wxTRANSPARENT ) + if ((m_logicalFunction == wxCOPY) && (m_pen.GetStyle() == wxTRANSPARENT)) { - x2++; - y2++; + RECT rect; + rect.left = XLOG2DEV(x); + rect.top = YLOG2DEV(y); + rect.right = XLOG2DEV(x2); + rect.bottom = YLOG2DEV(y2); + (void)FillRect(GetHdc(), &rect, (HBRUSH)m_brush.GetResourceHandle() ); + } + else + { + // Windows draws the filled rectangles without outline (i.e. drawn with a + // transparent pen) one pixel smaller in both directions and we want them + // to have the same size regardless of which pen is used - adjust + + // I wonder if this shouldn´t be done after the LOG2DEV() conversions. RR. + if ( m_pen.GetStyle() == wxTRANSPARENT ) + { + x2++; + y2++; + } + + (void)Rectangle(GetHdc(), XLOG2DEV(x), YLOG2DEV(y), XLOG2DEV(x2), YLOG2DEV(y2)); } - (void)Rectangle(GetHdc(), XLOG2DEV(x), YLOG2DEV(y), XLOG2DEV(x2), YLOG2DEV(y2)); CalcBoundingBox(x, y); CalcBoundingBox(x2, y2); @@ -567,6 +655,32 @@ void wxDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height) void wxDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius) { + COLORREF colFgOld = 0, + colBgOld = 0; + + if ( m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE ) + { + colFgOld = ::GetTextColor(GetHdc()); + colBgOld = ::GetBkColor(GetHdc()); + + if ( m_textForegroundColour.Ok() ) + { + // just the oposite from what is expected see help on pattern brush + // 1 in mask becomes bk color + ::SetBkColor(GetHdc(), m_textForegroundColour.GetPixel()); + } + + if ( m_textBackgroundColour.Ok() ) + { + // 0 in mask becomes text color + ::SetTextColor(GetHdc(), m_textBackgroundColour.GetPixel()); + } + + // VZ: IMHO this does strictly nothing here + SetBkMode(GetHdc(), m_backgroundMode == wxTRANSPARENT ? TRANSPARENT + : OPAQUE); + } + // Now, a negative radius value is interpreted to mean // 'the proportion of the smallest X or Y dimension' @@ -597,10 +711,44 @@ void wxDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord h CalcBoundingBox(x, y); CalcBoundingBox(x2, y2); + + if ( m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE ) + { + // restore the colours we changed + ::SetBkMode(GetHdc(), TRANSPARENT); + ::SetTextColor(GetHdc(), colFgOld); + ::SetBkColor(GetHdc(), colBgOld); + } } void wxDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height) { + COLORREF colFgOld = 0, + colBgOld = 0; + + if ( m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE ) + { + colFgOld = ::GetTextColor(GetHdc()); + colBgOld = ::GetBkColor(GetHdc()); + + if ( m_textForegroundColour.Ok() ) + { + // just the oposite from what is expected see help on pattern brush + // 1 in mask becomes bk color + ::SetBkColor(GetHdc(), m_textForegroundColour.GetPixel()); + } + + if ( m_textBackgroundColour.Ok() ) + { + // 0 in mask becomes text color + ::SetTextColor(GetHdc(), m_textBackgroundColour.GetPixel()); + } + + // VZ: IMHO this does strictly nothing here + SetBkMode(GetHdc(), m_backgroundMode == wxTRANSPARENT ? TRANSPARENT + : OPAQUE); + } + wxCoord x2 = (x+width); wxCoord y2 = (y+height); @@ -608,11 +756,45 @@ void wxDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height) CalcBoundingBox(x, y); CalcBoundingBox(x2, y2); + + if ( m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE ) + { + // restore the colours we changed + ::SetBkMode(GetHdc(), TRANSPARENT); + ::SetTextColor(GetHdc(), colFgOld); + ::SetBkColor(GetHdc(), colBgOld); + } } // Chris Breeze 20/5/98: first implementation of DrawEllipticArc on Windows void wxDC::DoDrawEllipticArc(wxCoord x,wxCoord y,wxCoord w,wxCoord h,double sa,double ea) { + COLORREF colFgOld = 0, + colBgOld = 0; + + if ( m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE ) + { + colFgOld = ::GetTextColor(GetHdc()); + colBgOld = ::GetBkColor(GetHdc()); + + if ( m_textForegroundColour.Ok() ) + { + // just the oposite from what is expected see help on pattern brush + // 1 in mask becomes bk color + ::SetBkColor(GetHdc(), m_textForegroundColour.GetPixel()); + } + + if ( m_textBackgroundColour.Ok() ) + { + // 0 in mask becomes text color + ::SetTextColor(GetHdc(), m_textBackgroundColour.GetPixel()); + } + + // VZ: IMHO this does strictly nothing here + SetBkMode(GetHdc(), m_backgroundMode == wxTRANSPARENT ? TRANSPARENT + : OPAQUE); + } + wxCoord x2 = (x+w); wxCoord y2 = (y+h); @@ -648,6 +830,14 @@ void wxDC::DoDrawEllipticArc(wxCoord x,wxCoord y,wxCoord w,wxCoord h,double sa,d CalcBoundingBox(x, y); CalcBoundingBox(x2, y2); + + if ( m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE ) + { + // restore the colours we changed + ::SetBkMode(GetHdc(), TRANSPARENT); + ::SetTextColor(GetHdc(), colFgOld); + ::SetBkColor(GetHdc(), colBgOld); + } } void wxDC::DoDrawIcon(const wxIcon& icon, wxCoord x, wxCoord y) @@ -965,7 +1155,17 @@ void wxDC::SetBrush(const wxBrush& brush) if (m_brush.Ok()) { - if (m_brush.GetResourceHandle()) + // to make sure the brush is alligned with the logical coordinates + wxBitmap *stipple = m_brush.GetStipple(); + if ( stipple && stipple->Ok() ) + { + ::SetBrushOrgEx(GetHdc(), + m_deviceOriginX % stipple->GetWidth(), + m_deviceOriginY % stipple->GetHeight(), + NULL); // don't need previous brush origin + } + + if ( m_brush.GetResourceHandle() ) { HBRUSH b = 0; b = (HBRUSH) ::SelectObject(GetHdc(), (HBRUSH)m_brush.GetResourceHandle());