Implement 0-width pen consistently in wxGraphicsContext
Emulate a 1-pixel pen width as closely as possible. This reverts:334cf1cc91(Take HiDPI scale into account for wxGCDC 0-width pen, 2021-04-03)0d80050057(Make wxGCDC behavior with 0-width wxPen consistent with MSW wxDC, 2021-03-02) See #19077, #19115
This commit is contained in:
@@ -441,17 +441,23 @@ public:
|
||||
|
||||
virtual bool ShouldOffset() const wxOVERRIDE
|
||||
{
|
||||
if ( !m_enableOffset )
|
||||
if (!m_enableOffset || m_pen.IsNull())
|
||||
return false;
|
||||
|
||||
int penwidth = 0 ;
|
||||
if ( !m_pen.IsNull() )
|
||||
{
|
||||
penwidth = (int)((wxCairoPenData*)m_pen.GetRefData())->GetWidth();
|
||||
if ( penwidth == 0 )
|
||||
penwidth = 1;
|
||||
}
|
||||
return ( penwidth % 2 ) == 1;
|
||||
const double width = static_cast<wxCairoPenData*>(m_pen.GetRefData())->GetWidth();
|
||||
|
||||
// always offset for 1-pixel width
|
||||
if (width <= 0)
|
||||
return true;
|
||||
|
||||
// no offset if overall scale is not odd integer
|
||||
double x = GetContentScaleFactor(), y = x;
|
||||
cairo_user_to_device_distance(m_context, &x, &y);
|
||||
if (!wxIsSameDouble(fmod(wxMin(fabs(x), fabs(y)), 2.0), 1.0))
|
||||
return false;
|
||||
|
||||
// offset if pen width is odd integer
|
||||
return wxIsSameDouble(fmod(width, 2.0), 1.0);
|
||||
}
|
||||
|
||||
virtual void Clip( const wxRegion ®ion ) wxOVERRIDE;
|
||||
@@ -844,8 +850,6 @@ wxCairoPenData::wxCairoPenData( wxGraphicsRenderer* renderer, const wxGraphicsPe
|
||||
{
|
||||
Init();
|
||||
m_width = info.GetWidth();
|
||||
if (m_width <= 0.0)
|
||||
m_width = 0.1;
|
||||
|
||||
switch ( info.GetCap() )
|
||||
{
|
||||
@@ -1017,7 +1021,14 @@ void wxCairoPenData::Apply( wxGraphicsContext* context )
|
||||
wxCairoPenBrushBaseData::Apply(context);
|
||||
|
||||
cairo_t * ctext = (cairo_t*) context->GetNativeContext();
|
||||
cairo_set_line_width(ctext,m_width);
|
||||
double width = m_width;
|
||||
if (width <= 0)
|
||||
{
|
||||
double x = context->GetContentScaleFactor(), y = x;
|
||||
cairo_user_to_device_distance(ctext, &x, &y);
|
||||
width = 1 / wxMin(fabs(x), fabs(y));
|
||||
}
|
||||
cairo_set_line_width(ctext, width);
|
||||
cairo_set_line_cap(ctext,m_cap);
|
||||
cairo_set_line_join(ctext,m_join);
|
||||
cairo_set_dash(ctext, m_lengths, m_count, 0);
|
||||
@@ -1912,21 +1923,26 @@ wxCairoBitmapData::~wxCairoBitmapData()
|
||||
class wxCairoOffsetHelper
|
||||
{
|
||||
public :
|
||||
wxCairoOffsetHelper( cairo_t* ctx , bool offset )
|
||||
wxCairoOffsetHelper(cairo_t* ctx, double scaleFactor, bool offset)
|
||||
{
|
||||
m_ctx = ctx;
|
||||
m_offset = offset;
|
||||
if ( m_offset )
|
||||
cairo_translate( m_ctx, 0.5, 0.5 );
|
||||
m_offset = 0;
|
||||
if (offset)
|
||||
{
|
||||
double x = scaleFactor, y = x;
|
||||
cairo_user_to_device_distance(ctx, &x, &y);
|
||||
m_offset = 0.5 / wxMin(fabs(x), fabs(y));
|
||||
cairo_translate(m_ctx, m_offset, m_offset);
|
||||
}
|
||||
}
|
||||
~wxCairoOffsetHelper( )
|
||||
{
|
||||
if ( m_offset )
|
||||
cairo_translate( m_ctx, -0.5, -0.5 );
|
||||
if (m_offset > 0)
|
||||
cairo_translate(m_ctx, -m_offset, -m_offset);
|
||||
}
|
||||
public :
|
||||
private:
|
||||
cairo_t* m_ctx;
|
||||
bool m_offset;
|
||||
double m_offset;
|
||||
} ;
|
||||
|
||||
#if wxUSE_PRINTING_ARCHITECTURE
|
||||
@@ -1976,7 +1992,7 @@ wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, const wxWindowDC&
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
|
||||
m_enableOffset = dc.GetContentScaleFactor() <= 1;
|
||||
EnableOffset();
|
||||
|
||||
#ifdef __WXMSW__
|
||||
HDC hdc = (HDC)dc.GetHDC();
|
||||
@@ -2029,7 +2045,7 @@ wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, const wxMemoryDC&
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
|
||||
m_enableOffset = dc.GetContentScaleFactor() <= 1;
|
||||
SetContentScaleFactor(dc.GetContentScaleFactor());
|
||||
|
||||
#ifdef __WXMSW__
|
||||
wxBitmap bmp = dc.GetSelectedBitmap();
|
||||
@@ -2352,7 +2368,7 @@ wxCairoContext::wxCairoContext(wxGraphicsRenderer* renderer, HWND hWnd)
|
||||
{
|
||||
// See remarks for wxWindowBase::GetContentScaleFactor
|
||||
double scaleY = ::GetDeviceCaps((HDC)m_mswWindowHDC, LOGPIXELSY) / 96.0f;
|
||||
m_enableOffset = scaleY <= 1.0;
|
||||
SetContentScaleFactor(scaleY);
|
||||
|
||||
m_mswStateSavedDC = 0;
|
||||
m_mswSurface = cairo_win32_surface_create((HDC)m_mswWindowHDC);
|
||||
@@ -2393,7 +2409,7 @@ wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, wxWindow *window)
|
||||
, m_mswWindowHDC(GetHwndOf(window))
|
||||
#endif
|
||||
{
|
||||
m_enableOffset = window->GetContentScaleFactor() <= 1;
|
||||
EnableOffset();
|
||||
#ifdef __WXGTK__
|
||||
// something along these lines (copied from dcclient)
|
||||
|
||||
@@ -2605,7 +2621,7 @@ void wxCairoContext::StrokePath( const wxGraphicsPath& path )
|
||||
{
|
||||
if ( !m_pen.IsNull() )
|
||||
{
|
||||
wxCairoOffsetHelper helper( m_context, ShouldOffset() ) ;
|
||||
wxCairoOffsetHelper helper(m_context, GetContentScaleFactor(), ShouldOffset());
|
||||
cairo_path_t* cp = (cairo_path_t*) path.GetNativePath() ;
|
||||
cairo_append_path(m_context,cp);
|
||||
((wxCairoPenData*)m_pen.GetRefData())->Apply(this);
|
||||
@@ -2618,7 +2634,7 @@ void wxCairoContext::FillPath( const wxGraphicsPath& path , wxPolygonFillMode fi
|
||||
{
|
||||
if ( !m_brush.IsNull() )
|
||||
{
|
||||
wxCairoOffsetHelper helper( m_context, ShouldOffset() ) ;
|
||||
wxCairoOffsetHelper helper(m_context, GetContentScaleFactor(), ShouldOffset());
|
||||
cairo_path_t* cp = (cairo_path_t*) path.GetNativePath() ;
|
||||
cairo_append_path(m_context,cp);
|
||||
((wxCairoBrushData*)m_brush.GetRefData())->Apply(this);
|
||||
@@ -2647,7 +2663,7 @@ void wxCairoContext::DrawRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble
|
||||
}
|
||||
if ( !m_pen.IsNull() )
|
||||
{
|
||||
wxCairoOffsetHelper helper( m_context, ShouldOffset() ) ;
|
||||
wxCairoOffsetHelper helper(m_context, GetContentScaleFactor(), ShouldOffset());
|
||||
((wxCairoPenData*)m_pen.GetRefData())->Apply(this);
|
||||
cairo_rectangle(m_context, x, y, w, h);
|
||||
cairo_stroke(m_context);
|
||||
|
||||
Reference in New Issue
Block a user