X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9f7948af90ec2e3b907944e7d979f0863910c5c8..044fe836c169b99ebeed802d31bb8c794429b888:/src/msw/dc.cpp?ds=sidebyside diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp index 869f90c4a2..c9a0c81386 100644 --- a/src/msw/dc.cpp +++ b/src/msw/dc.cpp @@ -41,6 +41,7 @@ #endif #include "wx/msw/private.h" // needs to be before #include +#include "wx/msw/missing.h" // needs to be before #include #include "wx/sysopt.h" #include "wx/dcprint.h" @@ -112,13 +113,17 @@ static const int MM_METRIC = 10; coordinates used. */ -// logical to device -#define XLOG2DEV(x) (x) -#define YLOG2DEV(y) (y) - -// device to logical -#define XDEV2LOG(x) (x) -#define YDEV2LOG(y) (y) +#ifdef __WXWINCE__ + #define XLOG2DEV(x) ((x-m_logicalOriginX)*m_signX+m_deviceOriginX) + #define YLOG2DEV(y) ((y-m_logicalOriginY)*m_signY+m_deviceOriginY) + #define XDEV2LOG(x) ((x-m_deviceOriginX)*m_signX+m_logicalOriginX) + #define YDEV2LOG(y) ((y-m_deviceOriginY)*m_signY+m_logicalOriginY) +#else + #define XLOG2DEV(x) (x) + #define YLOG2DEV(y) (y) + #define XDEV2LOG(x) (x) + #define YDEV2LOG(y) (y) +#endif // --------------------------------------------------------------------------- // private functions @@ -238,12 +243,12 @@ wxColourChanger::wxColourChanger(wxDC& dc) : m_dc(dc) : OPAQUE); // flag which telsl us to undo changes in the dtor - m_changed = TRUE; + m_changed = true; } else { // nothing done, nothing to undo - m_changed = FALSE; + m_changed = false; } } @@ -277,7 +282,7 @@ wxDC::wxDC() m_oldPalette = 0; #endif // wxUSE_PALETTE - m_bOwnsDC = FALSE; + m_bOwnsDC = false; m_hDC = 0; } @@ -378,6 +383,24 @@ void wxDC::UpdateClipBox() m_clipY2 = (wxCoord) YDEV2LOG(rect.bottom); } +void +wxDC::DoGetClippingBox(wxCoord *x, wxCoord *y, wxCoord *w, wxCoord *h) const +{ + // check if we should try to retrieve the clipping region possibly not set + // by our SetClippingRegion() but preset by Windows:this can only happen + // when we're associated with an existing HDC usign SetHDC(), see there + if ( m_clipping && !m_clipX1 && !m_clipX2 ) + { + wxDC *self = wxConstCast(this, wxDC); + self->UpdateClipBox(); + + if ( !m_clipX1 && !m_clipX2 ) + self->m_clipping = false; + } + + return wxDCBase::DoGetClippingBox(x, y, w, h); +} + // common part of DoSetClippingRegion() and DoSetClippingRegionAsRegion() void wxDC::SetClippingHrgn(WXHRGN hrgn) { @@ -388,7 +411,7 @@ void wxDC::SetClippingHrgn(WXHRGN hrgn) // note that we combine the new clipping region with the existing one: this // is compatible with what the other ports do and is the documented // behaviour now (starting with 2.3.3) -#if defined(__WIN16__) || defined(__WXWINCE__) +#if defined(__WXWINCE__) RECT rectClip; if ( !::GetClipBox(GetHdc(), &rectClip) ) return; @@ -404,16 +427,16 @@ void wxDC::SetClippingHrgn(WXHRGN hrgn) ::DeleteObject(hrgnClipOld); ::DeleteObject(hrgnDest); -#else // Win32 +#else // !WinCE if ( ::ExtSelectClipRgn(GetHdc(), (HRGN)hrgn, RGN_AND) == ERROR ) { wxLogLastError(_T("ExtSelectClipRgn")); return; } -#endif // Win16/32 +#endif // WinCE/!WinCE - m_clipping = TRUE; + m_clipping = true; UpdateClipBox(); } @@ -460,7 +483,7 @@ void wxDC::DestroyClippingRegion() ::DeleteObject(rgn); } - m_clipping = FALSE; + wxDCBase::DestroyClippingRegion(); } // --------------------------------------------------------------------------- @@ -469,14 +492,14 @@ void wxDC::DestroyClippingRegion() bool wxDC::CanDrawBitmap() const { - return TRUE; + return true; } bool wxDC::CanGetTextExtent() const { #ifdef __WXMICROWIN__ // TODO Extend MicroWindows' GetDeviceCaps function - return TRUE; + return true; #else // What sort of display is it? int technology = ::GetDeviceCaps(GetHdc(), TECHNOLOGY); @@ -543,10 +566,10 @@ void wxDC::Clear() bool wxDC::DoFloodFill(wxCoord x, wxCoord y, const wxColour& col, int style) { #ifdef __WXWINCE__ - return FALSE; + return false; #else - WXMICROWIN_CHECK_HDC_RET(FALSE) + WXMICROWIN_CHECK_HDC_RET(false) bool success = (0 != ::ExtFloodFill(GetHdc(), XLOG2DEV(x), YLOG2DEV(y), col.GetPixel(), @@ -577,16 +600,16 @@ bool wxDC::DoFloodFill(wxCoord x, wxCoord y, const wxColour& col, int style) bool wxDC::DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const { - WXMICROWIN_CHECK_HDC_RET(FALSE) + WXMICROWIN_CHECK_HDC_RET(false) - wxCHECK_MSG( col, FALSE, _T("NULL colour parameter in wxDC::GetPixel") ); + wxCHECK_MSG( col, false, _T("NULL colour parameter in wxDC::GetPixel") ); // get the color of the pixel COLORREF pixelcolor = ::GetPixel(GetHdc(), XLOG2DEV(x), YLOG2DEV(y)); wxRGBToColour(*col, pixelcolor); - return TRUE; + return true; } void wxDC::DoCrossHair(wxCoord x, wxCoord y) @@ -698,8 +721,8 @@ void wxDC::DoDrawCheckMark(wxCoord x1, wxCoord y1, #else DrawFrameControl(GetHdc(), &rect, DFC_MENU, DFCS_MENUCHECK); #endif -#else // Win16 - // In WIN16, draw a cross +#else // Symantec-MicroWin + // 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); @@ -713,7 +736,7 @@ void wxDC::DoDrawCheckMark(wxCoord x1, wxCoord y1, ::SelectObject(GetHdc(), hPenOld); ::SelectObject(GetHdc(), hBrushOld); ::DeleteObject(blackPen); -#endif // Win32/16 +#endif // Win32/Symantec-MicroWin CalcBoundingBox(x1, y1); CalcBoundingBox(x2, y2); @@ -779,18 +802,21 @@ void wxDC::DoDrawPolygon(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffs void wxDC::DoDrawPolyPolygon(int n, - int start[], + int count[], wxPoint points[], wxCoord xoffset, wxCoord yoffset, int fillStyle) { +#ifdef __WXWINCE__ + wxDCBase::DoDrawPolyPolygon(n, count, points, xoffset, yoffset, fillStyle); +#else WXMICROWIN_CHECK_HDC wxColourChanger cc(*this); // needed for wxSTIPPLE_MASK_OPAQUE handling int i, cnt; for (i = cnt = 0; i < n; i++) - cnt += start[i]; + cnt += count[i]; // Do things less efficiently if we have offsets if (xoffset != 0 || yoffset != 0) @@ -803,9 +829,13 @@ wxDC::DoDrawPolyPolygon(int n, CalcBoundingBox(cpoints[i].x, cpoints[i].y); } +#ifndef __WXWINCE__ int prev = SetPolyFillMode(GetHdc(),fillStyle==wxODDEVEN_RULE?ALTERNATE:WINDING); - (void)PolyPolygon(GetHdc(), cpoints, start, n); +#endif + (void)PolyPolygon(GetHdc(), cpoints, count, n); +#ifndef __WXWINCE__ SetPolyFillMode(GetHdc(),prev); +#endif delete[] cpoints; } else @@ -813,10 +843,16 @@ wxDC::DoDrawPolyPolygon(int n, for (i = 0; i < cnt; i++) CalcBoundingBox(points[i].x, points[i].y); +#ifndef __WXWINCE__ int prev = SetPolyFillMode(GetHdc(),fillStyle==wxODDEVEN_RULE?ALTERNATE:WINDING); - (void)PolyPolygon(GetHdc(), (POINT*) points, start, n); +#endif + (void)PolyPolygon(GetHdc(), (POINT*) points, count, n); +#ifndef __WXWINCE__ SetPolyFillMode(GetHdc(),prev); +#endif } +#endif + // __WXWINCE__ } void wxDC::DoDrawLines(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset) @@ -1037,7 +1073,7 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask { // don't give assert here because this would break existing // programs - just silently ignore useMask parameter - useMask = FALSE; + useMask = false; } } if ( useMask ) @@ -1048,7 +1084,7 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask // On some systems, MaskBlt succeeds yet is much much slower // than the wxWindows fall-back implementation. So we need // to be able to switch this on and off at runtime. - bool ok = FALSE; + bool ok = false; #if wxUSE_SYSTEM_OPTIONS if (wxSystemOptions::GetOptionInt(wxT("no-maskblt")) == 0) #endif @@ -1281,7 +1317,7 @@ void wxDC::DoSelectPalette(bool realize) { HPALETTE oldPal = ::SelectPalette(GetHdc(), GetHpaletteOf(m_palette), - FALSE); + false); if (!m_oldPalette) m_oldPalette = (WXHPALETTE) oldPal; @@ -1295,7 +1331,7 @@ void wxDC::SetPalette(const wxPalette& palette) if ( palette.Ok() ) { m_palette = palette; - DoSelectPalette(TRUE); + DoSelectPalette(true); } } @@ -1354,7 +1390,7 @@ void wxDC::SetFont(const wxFont& font) wxLogLastError(_T("SelectObject(old font)")); } - m_oldFont = NULL; + m_oldFont = 0; } m_font = wxNullFont; @@ -1392,7 +1428,7 @@ void wxDC::SetPen(const wxPen& pen) wxLogLastError(_T("SelectObject(old pen)")); } - m_oldPen = NULL; + m_oldPen = 0; } m_pen = wxNullPen; @@ -1447,7 +1483,7 @@ void wxDC::SetBrush(const wxBrush& brush) wxLogLastError(_T("SelectObject(old brush)")); } - m_oldBrush = NULL; + m_oldBrush = 0; } m_brush = wxNullBrush; @@ -1521,8 +1557,8 @@ void wxDC::SetRop(WXHDC dc) bool wxDC::StartDoc(const wxString& WXUNUSED(message)) { - // We might be previewing, so return TRUE to let it continue. - return TRUE; + // We might be previewing, so return true to let it continue. + return true; } void wxDC::EndDoc() @@ -1611,6 +1647,49 @@ void wxDC::DoGetTextExtent(const wxString& string, wxCoord *x, wxCoord *y, } } + +// Each element of the array will be the width of the string up to and +// including the coresoponding character in text. + +bool wxDC::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const +{ + static int maxLenText = -1; + static int maxWidth = -1; + int fit = 0; + SIZE sz = {0,0}; + int stlen = text.Length(); + + if (maxLenText == -1) + { + // Win9x and WinNT+ have different limits + int version = wxGetOsVersion(); + maxLenText = version == wxWINDOWS_NT ? 65535 : 8192; + maxWidth = version == wxWINDOWS_NT ? INT_MAX : 32767; + } + + widths.Empty(); + widths.Add(0, stlen); // fill the array with zeros + + if (!::GetTextExtentExPoint(GetHdc(), + text.c_str(), // string to check + wxMin(stlen, maxLenText), + maxWidth, + &fit, // [out] count of chars + // that will fit + &widths[0], // array to fill + &sz)) + { + // API failed + wxLogLastError(wxT("GetTextExtentExPoint")); + return false; + } + + return true; +} + + + + void wxDC::SetMapMode(int mode) { WXMICROWIN_CHECK_HDC @@ -1719,13 +1798,13 @@ void wxDC::SetSystemScale(double x, double y) { WXMICROWIN_CHECK_HDC -#ifndef __WXWINCE__ if ( x == m_scaleX && y == m_scaleY ) return; m_scaleX = x; m_scaleY = y; +#ifndef __WXWINCE__ SetMapMode(m_mappingMode); #endif } @@ -1734,13 +1813,13 @@ void wxDC::SetLogicalOrigin(wxCoord x, wxCoord y) { WXMICROWIN_CHECK_HDC -#ifndef __WXWINCE__ if ( x == m_logicalOriginX && y == m_logicalOriginY ) return; m_logicalOriginX = x; m_logicalOriginY = y; +#ifndef __WXWINCE__ ::SetWindowOrgEx(GetHdc(), (int)m_logicalOriginX, (int)m_logicalOriginY, NULL); #endif } @@ -1749,13 +1828,13 @@ void wxDC::SetDeviceOrigin(wxCoord x, wxCoord y) { WXMICROWIN_CHECK_HDC -#ifndef __WXWINCE__ if ( x == m_deviceOriginX && y == m_deviceOriginY ) return; m_deviceOriginX = x; m_deviceOriginY = y; +#ifndef __WXWINCE__ ::SetViewportOrgEx(GetHdc(), (int)m_deviceOriginX, (int)m_deviceOriginY, NULL); #endif } @@ -1818,16 +1897,16 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, int rop, bool useMask, wxCoord xsrcMask, wxCoord ysrcMask) { - wxCHECK_MSG( source, FALSE, _T("wxDC::Blit(): NULL wxDC pointer") ); + wxCHECK_MSG( source, false, _T("wxDC::Blit(): NULL wxDC pointer") ); - WXMICROWIN_CHECK_HDC_RET(FALSE) + WXMICROWIN_CHECK_HDC_RET(false) const wxBitmap& bmpSrc = source->m_selectedBitmap; if ( bmpSrc.Ok() && bmpSrc.HasAlpha() ) { if ( AlphaBlt(GetHdc(), xdest, ydest, width, height, GetHdcOf(*source), bmpSrc) ) - return TRUE; + return true; } wxMask *mask = NULL; @@ -1839,7 +1918,7 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, { // don't give assert here because this would break existing // programs - just silently ignore useMask parameter - useMask = FALSE; + useMask = false; } } @@ -1880,10 +1959,10 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, case wxNOR: dwRop = NOTSRCCOPY; break; default: wxFAIL_MSG( wxT("unsupported logical function") ); - return FALSE; + return false; } - bool success = FALSE; + bool success = false; if (useMask) { @@ -2036,11 +2115,15 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, SRCCOPY ) == (int)GDI_ERROR ) { - wxLogLastError(wxT("StretchDIBits")); + // On Win9x this API fails most (all?) of the time, so + // logging it becomes quite distracting. Since it falls + // back to the code below this is not really serious, so + // don't log it. + //wxLogLastError(wxT("StretchDIBits")); } else { - success = TRUE; + success = true; } } } @@ -2066,7 +2149,7 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, } else { - success = TRUE; + success = true; } } @@ -2086,7 +2169,7 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, } else { - success = TRUE; + success = true; } } } @@ -2280,7 +2363,7 @@ void wxDC::ClearCache() class wxDCModule : public wxModule { public: - virtual bool OnInit() { return TRUE; } + virtual bool OnInit() { return true; } virtual void OnExit() { wxDC::ClearCache(); } private: @@ -2312,11 +2395,11 @@ static bool AlphaBlt(HDC hdcDst, // bitmaps can be drawn only from GUI thread so there is no need to // protect this static variable from multiple threads - static bool s_triedToLoad = FALSE; + static bool s_triedToLoad = false; static AlphaBlend_t pfnAlphaBlend = NULL; if ( !s_triedToLoad ) { - s_triedToLoad = TRUE; + s_triedToLoad = true; // don't give errors about the DLL being unavailable, we're // prepared to handle this @@ -2349,7 +2432,7 @@ static bool AlphaBlt(HDC hdcDst, bf) ) { // skip wxAlphaBlend() call below - return TRUE; + return true; } wxLogLastError(_T("AlphaBlend")); @@ -2361,11 +2444,11 @@ static bool AlphaBlt(HDC hdcDst, #ifdef wxHAVE_RAW_BITMAP wxAlphaBlend(hdcDst, x, y, width, height, bmp); - return TRUE; + return true; #else // !wxHAVE_RAW_BITMAP // no wxAlphaBlend() neither, fall back to using simple BitBlt() (we lose // alpha but at least something will be shown like this) - return FALSE; + return false; #endif // wxHAVE_RAW_BITMAP }