+ 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 == wxOS_WINDOWS_NT ? 65535 : 8192;
+ maxWidth = version == wxOS_WINDOWS_NT ? INT_MAX : 32767;
+ }
+
+ widths.Empty();
+ widths.Add(0, stlen); // fill the array with zeros
+ if (stlen == 0)
+ return true;
+
+ 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;
+}
+
+namespace
+{
+
+void ApplyEffectiveScale(double scale, int sign, int *device, int *logical)
+{
+ // To reduce rounding errors as much as possible, we try to use the largest
+ // possible extent (2^27-1) for the device space but we must also avoid
+ // overflowing the int range i.e. ensure that logical extents are less than
+ // 2^31 in magnitude. So the minimal scale we can use is 1/16 as for
+ // anything smaller VIEWPORT_EXTENT/scale would overflow the int range.
+ static const double MIN_LOGICAL_SCALE = 1./16;
+
+ double physExtent = VIEWPORT_EXTENT;
+ if ( scale < MIN_LOGICAL_SCALE )
+ {
+ physExtent *= scale/MIN_LOGICAL_SCALE;
+ scale = MIN_LOGICAL_SCALE;
+ }
+
+ *device = wxRound(physExtent);
+ *logical = sign*wxRound(VIEWPORT_EXTENT/scale);
+}
+
+} // anonymous namespace
+
+void wxMSWDCImpl::RealizeScaleAndOrigin()
+{
+ // although it may seem wasteful to always use MM_ANISOTROPIC here instead
+ // of using MM_TEXT if there is no scaling, benchmarking doesn't detect any
+ // noticeable difference between these mapping modes
+#ifndef __WXWINCE__
+ ::SetMapMode(GetHdc(), MM_ANISOTROPIC);
+
+ // wxWidgets API assumes that the coordinate space is "infinite" (i.e. only
+ // limited by 2^32 range of the integer coordinates) but in MSW API we must
+ // actually specify the extents that we use so compute them here.
+
+ int devExtX, devExtY, // Viewport, i.e. device space, extents.
+ logExtX, logExtY; // Window, i.e. logical coordinate space, extents.
+
+ ApplyEffectiveScale(m_scaleX, m_signX, &devExtX, &logExtX);
+ ApplyEffectiveScale(m_scaleY, m_signY, &devExtY, &logExtY);
+
+ ::SetViewportExtEx(GetHdc(), devExtX, devExtY, NULL);
+ ::SetWindowExtEx(GetHdc(), logExtX, logExtY, NULL);
+
+ ::SetViewportOrgEx(GetHdc(), m_deviceOriginX, m_deviceOriginY, NULL);
+ ::SetWindowOrgEx(GetHdc(), m_logicalOriginX, m_logicalOriginY, NULL);