Fix drawing on wxDC when using right-to-left layout in wxMSW.
Avoid integer overflow when setting wxDC scale. This affected (i.e. broke) drawing in RTL but probably not only that. Closes #16254. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_3_0_BRANCH@77022 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -602,6 +602,7 @@ wxMSW:
|
|||||||
- Fix parallel build of MSVC 11/12 solutions (Artur Wieczorek).
|
- Fix parallel build of MSVC 11/12 solutions (Artur Wieczorek).
|
||||||
- Fix background of wxRadioBox buttons and wxSlider (Artur Wieczorek).
|
- Fix background of wxRadioBox buttons and wxSlider (Artur Wieczorek).
|
||||||
- Fix appearance of wxToggleButtons with non default colours (Artur Wieczorek).
|
- Fix appearance of wxToggleButtons with non default colours (Artur Wieczorek).
|
||||||
|
- Fix drawing on wxDC when using right-to-left layout (Artur Wieczorek).
|
||||||
|
|
||||||
|
|
||||||
3.0.1: (released 2014-06-15)
|
3.0.1: (released 2014-06-15)
|
||||||
|
@@ -1932,6 +1932,50 @@ void ApplyEffectiveScale(double scale, int sign, int *device, int *logical)
|
|||||||
*logical = sign*wxRound(VIEWPORT_EXTENT/scale);
|
*logical = sign*wxRound(VIEWPORT_EXTENT/scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Binary GCD algorithm
|
||||||
|
// See: http://en.wikipedia.org/wiki/Binary_GCD_algorithm#Iterative_version_in_C
|
||||||
|
unsigned int CalcGCD(unsigned int u, unsigned int v)
|
||||||
|
{
|
||||||
|
// GCD(0,v) == v; GCD(u,0) == u, GCD(0,0) == 0
|
||||||
|
if (u == 0)
|
||||||
|
return v;
|
||||||
|
if (v == 0)
|
||||||
|
return u;
|
||||||
|
|
||||||
|
int shift;
|
||||||
|
|
||||||
|
// Let shift := lg K, where K is the greatest power of 2
|
||||||
|
// dividing both u and v.
|
||||||
|
for (shift = 0; ((u | v) & 1) == 0; ++shift)
|
||||||
|
{
|
||||||
|
u >>= 1;
|
||||||
|
v >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((u & 1) == 0)
|
||||||
|
u >>= 1;
|
||||||
|
|
||||||
|
// From here on, u is always odd.
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// remove all factors of 2 in v -- they are not common
|
||||||
|
// note: v is not zero, so while will terminate
|
||||||
|
while ((v & 1) == 0)
|
||||||
|
v >>= 1;
|
||||||
|
|
||||||
|
// Now u and v are both odd. Swap if necessary so u <= v,
|
||||||
|
// then set v = v - u (which is even)
|
||||||
|
if (u > v)
|
||||||
|
{
|
||||||
|
wxSwap(u, v);
|
||||||
|
}
|
||||||
|
v -= u; // Here v >= u
|
||||||
|
} while (v != 0);
|
||||||
|
|
||||||
|
// restore common factors of 2
|
||||||
|
return u << shift;
|
||||||
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
void wxMSWDCImpl::RealizeScaleAndOrigin()
|
void wxMSWDCImpl::RealizeScaleAndOrigin()
|
||||||
@@ -1952,6 +1996,16 @@ void wxMSWDCImpl::RealizeScaleAndOrigin()
|
|||||||
ApplyEffectiveScale(m_scaleX, m_signX, &devExtX, &logExtX);
|
ApplyEffectiveScale(m_scaleX, m_signX, &devExtX, &logExtX);
|
||||||
ApplyEffectiveScale(m_scaleY, m_signY, &devExtY, &logExtY);
|
ApplyEffectiveScale(m_scaleY, m_signY, &devExtY, &logExtY);
|
||||||
|
|
||||||
|
// Becaue only devExtX/logExtX ratio and devExtY/logExtY ratio are counted
|
||||||
|
// we can reduce the fractions to avoid large absolute numbers
|
||||||
|
// and possible arithmetic overflows.
|
||||||
|
unsigned int gcd = CalcGCD(abs(devExtX), abs(logExtX));
|
||||||
|
devExtX /= gcd;
|
||||||
|
logExtX /= gcd;
|
||||||
|
gcd = CalcGCD(abs(devExtY), abs(logExtY));
|
||||||
|
devExtY /= gcd;
|
||||||
|
logExtY /= gcd;
|
||||||
|
|
||||||
::SetViewportExtEx(GetHdc(), devExtX, devExtY, NULL);
|
::SetViewportExtEx(GetHdc(), devExtX, devExtY, NULL);
|
||||||
::SetWindowExtEx(GetHdc(), logExtX, logExtY, NULL);
|
::SetWindowExtEx(GetHdc(), logExtX, logExtY, NULL);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user