Draw horizontal/vertical lines with optimized function only on non-scaled DCs
It turned out that drawing horizontal/vertical lines with optimized function based on ExtTextOut() Win API works as expected only for non-scaled DC. Therefore we can use this optimized way of drawing only for non-rotated and non-scaled DCs. On not-scaled DCs we can use optimized function to draw also 0-pixel width lines (as a 1-pixel wide lines for compatibility with Win API). Closes #18612.
This commit is contained in:
@@ -801,6 +801,20 @@ bool wxMSWDCImpl::DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check whether DC is not rotated and not scaled
|
||||||
|
static bool IsNonTransformedDC(HDC hdc)
|
||||||
|
{
|
||||||
|
// Ensure DC is not rotated
|
||||||
|
if ( ::GetGraphicsMode(hdc) == GM_ADVANCED )
|
||||||
|
return false;
|
||||||
|
// and not scaled
|
||||||
|
SIZE devExt;
|
||||||
|
::GetViewportExtEx(hdc, &devExt);
|
||||||
|
SIZE logExt;
|
||||||
|
::GetWindowExtEx(hdc, &logExt);
|
||||||
|
return devExt.cx == logExt.cx && devExt.cy == logExt.cy;
|
||||||
|
}
|
||||||
|
|
||||||
void wxMSWDCImpl::DoCrossHair(wxCoord x, wxCoord y)
|
void wxMSWDCImpl::DoCrossHair(wxCoord x, wxCoord y)
|
||||||
{
|
{
|
||||||
RECT rect;
|
RECT rect;
|
||||||
@@ -813,23 +827,24 @@ void wxMSWDCImpl::DoCrossHair(wxCoord x, wxCoord y)
|
|||||||
// We have optimized function to draw physical vertical or horizontal lines
|
// We have optimized function to draw physical vertical or horizontal lines
|
||||||
// with solid color and square ends so it can be used to draw a cross hair
|
// with solid color and square ends so it can be used to draw a cross hair
|
||||||
// for:
|
// for:
|
||||||
// - Solid lines with pen width > 0 because it doesn't support drawing
|
// - Any shape of the lines ends because non-square line ends are drawn
|
||||||
// non-scaled 1-pixel wide lines when pen width is 0. Shape of the lines
|
// outside the view and visible line ends are always square.
|
||||||
// ends doesn't matter because non-square line ends are drawn outside
|
|
||||||
// the view and visible line ends are always square.
|
|
||||||
// - DC which coordinate system is not rotated (graphics mode
|
// - DC which coordinate system is not rotated (graphics mode
|
||||||
// of the DC != GM_ADVANCED).
|
// of the DC != GM_ADVANCED) and not scaled.
|
||||||
if ( ::GetGraphicsMode(GetHdc()) != GM_ADVANCED && // ensure DC is not rotated
|
if ( IsNonTransformedDC(GetHdc()) &&
|
||||||
m_pen.IsNonTransparent() && // this calls IsOk() too
|
m_pen.IsNonTransparent() && // this calls IsOk() too
|
||||||
m_pen.GetStyle() == wxPENSTYLE_SOLID &&
|
m_pen.GetStyle() == wxPENSTYLE_SOLID
|
||||||
m_pen.GetWidth() > 0
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Since we are drawing on a non-scaled DC, a 0-pixel width line
|
||||||
|
// can be safely drawn as a 1-pixel wide one.
|
||||||
|
int w = m_pen.GetWidth() > 0 ? m_pen.GetWidth() : 1;
|
||||||
|
|
||||||
COLORREF color = wxColourToRGB(m_pen.GetColour());
|
COLORREF color = wxColourToRGB(m_pen.GetColour());
|
||||||
wxDrawHVLine(GetHdc(), XLOG2DEV(rect.left), YLOG2DEV(y), XLOG2DEV(rect.right), YLOG2DEV(y),
|
wxDrawHVLine(GetHdc(), XLOG2DEV(rect.left), YLOG2DEV(y), XLOG2DEV(rect.right), YLOG2DEV(y),
|
||||||
color, m_pen.GetWidth());
|
color, w);
|
||||||
wxDrawHVLine(GetHdc(), XLOG2DEV(x), YLOG2DEV(rect.top), XLOG2DEV(x), YLOG2DEV(rect.bottom),
|
wxDrawHVLine(GetHdc(), XLOG2DEV(x), YLOG2DEV(rect.top), XLOG2DEV(x), YLOG2DEV(rect.bottom),
|
||||||
color, m_pen.GetWidth());
|
color, w);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -849,20 +864,19 @@ void wxMSWDCImpl::DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
|
|||||||
// in the device coordinate system is complex so we only check whether
|
// in the device coordinate system is complex so we only check whether
|
||||||
// the line is horizontal/vertical in the logical coordinates and use
|
// the line is horizontal/vertical in the logical coordinates and use
|
||||||
// optimized function only for DC which coordinate system is for sure
|
// optimized function only for DC which coordinate system is for sure
|
||||||
// not rotated (graphics mode of the DC != GM_ADVANCED).
|
// not rotated (graphics mode of the DC != GM_ADVANCED) and not scaled.
|
||||||
// Moreover, optimized function can be used only for regular lines with pen
|
|
||||||
// width > 0 because it doesn't support drawing non-scaled 1-pixel wide
|
|
||||||
// lines when pen width is 0.
|
|
||||||
if ( (x1 == x2 || y1 == y2) &&
|
if ( (x1 == x2 || y1 == y2) &&
|
||||||
::GetGraphicsMode(GetHdc()) != GM_ADVANCED && // ensure DC is not rotated
|
IsNonTransformedDC(GetHdc()) &&
|
||||||
m_pen.IsNonTransparent() && // this calls IsOk() too
|
m_pen.IsNonTransparent() && // this calls IsOk() too
|
||||||
m_pen.GetStyle() == wxPENSTYLE_SOLID &&
|
m_pen.GetStyle() == wxPENSTYLE_SOLID &&
|
||||||
m_pen.GetWidth() > 0 &&
|
(m_pen.GetWidth() <= 1 || m_pen.GetCap() == wxCAP_BUTT)
|
||||||
(m_pen.GetWidth() == 1 || m_pen.GetCap() == wxCAP_BUTT)
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Since we are drawing on a non-scaled DC, a 0-pixel width line
|
||||||
|
// can be safely drawn as a 1-pixel wide one.
|
||||||
wxDrawHVLine(GetHdc(), XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2),
|
wxDrawHVLine(GetHdc(), XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2),
|
||||||
wxColourToRGB(m_pen.GetColour()), m_pen.GetWidth());
|
wxColourToRGB(m_pen.GetColour()),
|
||||||
|
m_pen.GetWidth() > 0 ? m_pen.GetWidth() : 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user