Improve wxQtDCImpl to better match Cairo rendering.
This commit is contained in:
parent
7037d2ae64
commit
95f9257d62
1 changed files with 101 additions and 37 deletions
138
src/qt/dc.cpp
138
src/qt/dc.cpp
|
|
@ -42,6 +42,49 @@ static void SetBrushColour( QPainter *qtPainter, QColor col )
|
||||||
qtPainter->setBrush( b );
|
qtPainter->setBrush( b );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class QtDCOffsetHelper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QtDCOffsetHelper(QPainter *qpainter)
|
||||||
|
{
|
||||||
|
m_shouldOffset = ShouldOffset(qpainter->pen());
|
||||||
|
if (!m_shouldOffset)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_qp = qpainter;
|
||||||
|
m_offset = 0.5;
|
||||||
|
|
||||||
|
m_qp->translate(m_offset, m_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
~QtDCOffsetHelper()
|
||||||
|
{
|
||||||
|
if (m_shouldOffset)
|
||||||
|
m_qp->translate(-m_offset, -m_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShouldOffset(const QPen &pen) const
|
||||||
|
{
|
||||||
|
if (pen.style() == Qt::NoPen)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
double width = pen.widthF();
|
||||||
|
|
||||||
|
// always offset for 1-pixel width
|
||||||
|
if (width <= 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// offset if pen width is odd integer
|
||||||
|
const int w = int(width);
|
||||||
|
return (w & 1) && wxIsSameDouble(width, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPainter *m_qp;
|
||||||
|
double m_offset;
|
||||||
|
bool m_shouldOffset;
|
||||||
|
};
|
||||||
|
|
||||||
wxIMPLEMENT_CLASS(wxQtDCImpl,wxDCImpl);
|
wxIMPLEMENT_CLASS(wxQtDCImpl,wxDCImpl);
|
||||||
|
|
||||||
wxQtDCImpl::wxQtDCImpl( wxDC *owner )
|
wxQtDCImpl::wxQtDCImpl( wxDC *owner )
|
||||||
|
|
@ -582,11 +625,15 @@ bool wxQtDCImpl::DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const
|
||||||
|
|
||||||
void wxQtDCImpl::DoDrawPoint(wxCoord x, wxCoord y)
|
void wxQtDCImpl::DoDrawPoint(wxCoord x, wxCoord y)
|
||||||
{
|
{
|
||||||
|
QtDCOffsetHelper helper( m_qtPainter );
|
||||||
|
|
||||||
m_qtPainter->drawPoint(x, y);
|
m_qtPainter->drawPoint(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxQtDCImpl::DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
|
void wxQtDCImpl::DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
|
||||||
{
|
{
|
||||||
|
QtDCOffsetHelper helper( m_qtPainter );
|
||||||
|
|
||||||
m_qtPainter->drawLine(x1, y1, x2, y2);
|
m_qtPainter->drawLine(x1, y1, x2, y2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -600,55 +647,72 @@ void wxQtDCImpl::DoDrawArc(wxCoord x1, wxCoord y1,
|
||||||
QLineF l2( xc, yc, x2, y2 );
|
QLineF l2( xc, yc, x2, y2 );
|
||||||
QPointF center( xc, yc );
|
QPointF center( xc, yc );
|
||||||
|
|
||||||
qreal penWidth = m_qtPainter->pen().width();
|
qreal lenRadius = l1.length();
|
||||||
qreal lenRadius = l1.length() - penWidth / 2;
|
|
||||||
QPointF centerToCorner( lenRadius, lenRadius );
|
QPointF centerToCorner( lenRadius, lenRadius );
|
||||||
|
|
||||||
QRect rectangle = QRectF( center - centerToCorner, center + centerToCorner ).toRect();
|
QRect rectangle = QRectF( center - centerToCorner, center + centerToCorner ).toRect();
|
||||||
|
|
||||||
// Calculate the angles
|
// Calculate the angles
|
||||||
int startAngle = (int)( l1.angle() * 16 );
|
int startAngle = (int)(l1.angle() * 16);
|
||||||
int endAngle = (int)( l2.angle() * 16 );
|
int endAngle = (int)(l2.angle() * 16);
|
||||||
|
|
||||||
|
while(endAngle < startAngle)
|
||||||
|
endAngle += 360 * 16;
|
||||||
|
|
||||||
int spanAngle = endAngle - startAngle;
|
int spanAngle = endAngle - startAngle;
|
||||||
if ( spanAngle < 0 )
|
|
||||||
{
|
QtDCOffsetHelper helper( m_qtPainter );
|
||||||
spanAngle = -spanAngle;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( spanAngle == 0 )
|
if ( spanAngle == 0 )
|
||||||
m_qtPainter->drawEllipse( rectangle );
|
m_qtPainter->drawEllipse( rectangle );
|
||||||
else
|
else if (m_qtPainter->brush().style() != Qt::NoBrush)
|
||||||
m_qtPainter->drawPie( rectangle, startAngle, spanAngle );
|
m_qtPainter->drawPie( rectangle, startAngle, spanAngle );
|
||||||
|
else
|
||||||
|
m_qtPainter->drawArc( rectangle, startAngle, spanAngle );
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxQtDCImpl::DoDrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h,
|
void wxQtDCImpl::DoDrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h,
|
||||||
double sa, double ea)
|
double sa, double ea)
|
||||||
{
|
{
|
||||||
int penWidth = m_qtPainter->pen().width();
|
int startAngle = (int)( sa * 16 );
|
||||||
x += penWidth / 2;
|
int endAngle = (int)( ea * 16 );
|
||||||
y += penWidth / 2;
|
|
||||||
w -= penWidth;
|
|
||||||
h -= penWidth;
|
|
||||||
|
|
||||||
double spanAngle = sa - ea;
|
while(endAngle < startAngle)
|
||||||
if (spanAngle < -180)
|
endAngle += 360 * 16;
|
||||||
spanAngle += 360;
|
|
||||||
if (spanAngle > 180)
|
|
||||||
spanAngle -= 360;
|
|
||||||
|
|
||||||
if ( spanAngle == 0 )
|
int spanAngle = endAngle - startAngle;
|
||||||
m_qtPainter->drawEllipse( x, y, w, h );
|
|
||||||
|
QRect rectangle(x, y, w, h);
|
||||||
|
|
||||||
|
QtDCOffsetHelper helper( m_qtPainter );
|
||||||
|
|
||||||
|
if (spanAngle == 0)
|
||||||
|
{
|
||||||
|
m_qtPainter->drawEllipse( rectangle );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
m_qtPainter->drawPie( x, y, w, h, (int)( sa * 16 ), (int)( ( ea - sa ) * 16 ) );
|
{
|
||||||
|
if (m_qtPainter->brush().style() != Qt::NoBrush)
|
||||||
|
{
|
||||||
|
QPen savedPen = m_qtPainter->pen();
|
||||||
|
m_qtPainter->setPen( QPen( Qt::NoPen ) );
|
||||||
|
m_qtPainter->drawPie( rectangle, startAngle, spanAngle );
|
||||||
|
m_qtPainter->setPen( savedPen );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_qtPainter->drawArc( rectangle, startAngle, spanAngle );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxQtDCImpl::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
|
void wxQtDCImpl::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
|
||||||
{
|
{
|
||||||
int penWidth = m_qtPainter->pen().width();
|
if (m_qtPainter->pen().style() != Qt::NoPen)
|
||||||
x += penWidth / 2;
|
{
|
||||||
y += penWidth / 2;
|
width -= 1;
|
||||||
width -= penWidth;
|
height -= 1;
|
||||||
height -= penWidth;
|
}
|
||||||
|
|
||||||
|
QtDCOffsetHelper helper( m_qtPainter );
|
||||||
|
|
||||||
m_qtPainter->drawRect( x, y, width, height );
|
m_qtPainter->drawRect( x, y, width, height );
|
||||||
}
|
}
|
||||||
|
|
@ -657,11 +721,13 @@ void wxQtDCImpl::DoDrawRoundedRectangle(wxCoord x, wxCoord y,
|
||||||
wxCoord width, wxCoord height,
|
wxCoord width, wxCoord height,
|
||||||
double radius)
|
double radius)
|
||||||
{
|
{
|
||||||
int penWidth = m_qtPainter->pen().width();
|
if (m_qtPainter->pen().style() != Qt::NoPen)
|
||||||
x += penWidth / 2;
|
{
|
||||||
y += penWidth / 2;
|
width -= 1;
|
||||||
width -= penWidth;
|
height -= 1;
|
||||||
height -= penWidth;
|
}
|
||||||
|
|
||||||
|
QtDCOffsetHelper helper( m_qtPainter );
|
||||||
|
|
||||||
m_qtPainter->drawRoundedRect( x, y, width, height, radius, radius );
|
m_qtPainter->drawRoundedRect( x, y, width, height, radius, radius );
|
||||||
}
|
}
|
||||||
|
|
@ -669,11 +735,7 @@ void wxQtDCImpl::DoDrawRoundedRectangle(wxCoord x, wxCoord y,
|
||||||
void wxQtDCImpl::DoDrawEllipse(wxCoord x, wxCoord y,
|
void wxQtDCImpl::DoDrawEllipse(wxCoord x, wxCoord y,
|
||||||
wxCoord width, wxCoord height)
|
wxCoord width, wxCoord height)
|
||||||
{
|
{
|
||||||
const int penWidth = m_qtPainter->pen().width();
|
QtDCOffsetHelper helper( m_qtPainter );
|
||||||
x += penWidth / 2;
|
|
||||||
y += penWidth / 2;
|
|
||||||
width -= penWidth;
|
|
||||||
height -= penWidth;
|
|
||||||
|
|
||||||
m_qtPainter->drawEllipse( x, y, width, height );
|
m_qtPainter->drawEllipse( x, y, width, height );
|
||||||
}
|
}
|
||||||
|
|
@ -689,6 +751,8 @@ void wxQtDCImpl::DoCrossHair(wxCoord x, wxCoord y)
|
||||||
inv.map( w, h, &right, &bottom );
|
inv.map( w, h, &right, &bottom );
|
||||||
inv.map( 0, 0, &left, &top );
|
inv.map( 0, 0, &left, &top );
|
||||||
|
|
||||||
|
QtDCOffsetHelper helper( m_qtPainter );
|
||||||
|
|
||||||
m_qtPainter->drawLine( left, y, right, y );
|
m_qtPainter->drawLine( left, y, right, y );
|
||||||
m_qtPainter->drawLine( x, top, x, bottom );
|
m_qtPainter->drawLine( x, top, x, bottom );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue