]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/dc.cpp
SetBrushOrgExt broke WIN16 compilation
[wxWidgets.git] / src / msw / dc.cpp
index e952121916fff6c25d372cede4e95421e18cea8b..737f7235e6c6648f061ead80fff7120767af5e3b 100644 (file)
@@ -48,9 +48,6 @@
 #include "wx/msw/private.h" // needs to be before #include <commdlg.h>
 
 #if wxUSE_COMMON_DIALOGS
-#if wxUSE_NORLANDER_HEADERS
-    #include <windows.h>
-#endif
     #include <commdlg.h>
 #endif
 
@@ -178,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()
@@ -321,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 )
@@ -338,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)
@@ -363,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);
@@ -374,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) ;;
@@ -412,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)
@@ -429,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
@@ -479,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);
     }
 }
 
@@ -545,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);
@@ -570,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'
 
@@ -586,15 +697,58 @@ void wxDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord h
     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 )
+    {
+        x2++;
+        y2++;
+    }
+
     (void)RoundRect(GetHdc(), XLOG2DEV(x), YLOG2DEV(y), XLOG2DEV(x2),
         YLOG2DEV(y2), (int) (2*XLOG2DEV(radius)), (int)( 2*YLOG2DEV(radius)));
 
     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);
 
@@ -602,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);
 
@@ -642,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)
@@ -959,7 +1155,23 @@ 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() )
+        {
+#ifdef __WIN32__
+               ::SetBrushOrgEx(GetHdc(),
+                            m_deviceOriginX % stipple->GetWidth(),
+                            m_deviceOriginY % stipple->GetHeight(),
+                            NULL);  // don't need previous brush origin
+#else
+               ::SetBrushOrg(GetHdc(),
+                            m_deviceOriginX % stipple->GetWidth(),
+                            m_deviceOriginY % stipple->GetHeight());
+#endif
+        }
+
+        if ( m_brush.GetResourceHandle() )
         {
             HBRUSH b = 0;
             b = (HBRUSH) ::SelectObject(GetHdc(), (HBRUSH)m_brush.GetResourceHandle());