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;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
RECT rect;
|
||||
@@ -813,23 +827,24 @@ void wxMSWDCImpl::DoCrossHair(wxCoord x, wxCoord y)
|
||||
// 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
|
||||
// for:
|
||||
// - Solid lines with pen width > 0 because it doesn't support drawing
|
||||
// non-scaled 1-pixel wide lines when pen width is 0. Shape of the lines
|
||||
// ends doesn't matter because non-square line ends are drawn outside
|
||||
// the view and visible line ends are always square.
|
||||
// - Any shape of the lines ends 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
|
||||
// of the DC != GM_ADVANCED).
|
||||
if ( ::GetGraphicsMode(GetHdc()) != GM_ADVANCED && // ensure DC is not rotated
|
||||
// of the DC != GM_ADVANCED) and not scaled.
|
||||
if ( IsNonTransformedDC(GetHdc()) &&
|
||||
m_pen.IsNonTransparent() && // this calls IsOk() too
|
||||
m_pen.GetStyle() == wxPENSTYLE_SOLID &&
|
||||
m_pen.GetWidth() > 0
|
||||
m_pen.GetStyle() == wxPENSTYLE_SOLID
|
||||
)
|
||||
{
|
||||
// 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());
|
||||
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),
|
||||
color, m_pen.GetWidth());
|
||||
color, w);
|
||||
}
|
||||
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
|
||||
// the line is horizontal/vertical in the logical coordinates and use
|
||||
// optimized function only for DC which coordinate system is for sure
|
||||
// not rotated (graphics mode of the DC != GM_ADVANCED).
|
||||
// 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.
|
||||
// not rotated (graphics mode of the DC != GM_ADVANCED) and not scaled.
|
||||
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.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),
|
||||
wxColourToRGB(m_pen.GetColour()), m_pen.GetWidth());
|
||||
wxColourToRGB(m_pen.GetColour()),
|
||||
m_pen.GetWidth() > 0 ? m_pen.GetWidth() : 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Reference in New Issue
Block a user