scaling of pens moved to QskStrokeNode

This commit is contained in:
Uwe Rathmann 2022-09-30 15:09:52 +02:00
parent cd19b047ab
commit ee7dbb300a
3 changed files with 34 additions and 29 deletions

View File

@ -26,19 +26,20 @@ static inline bool isVisible( const QPen& pen )
return ( pen.style() != Qt::NoPen ) && isVisible( pen.color() ); return ( pen.style() != Qt::NoPen ) && isVisible( pen.color() );
} }
static inline QPen cosmeticPen( const QPen& pen, const QSizeF& size1, const QSizeF& size2 ) static inline qreal effectivePenWidth(
const QPen& pen, const QRectF& r1, const QRectF& r2 )
{ {
if ( pen.isCosmetic() || pen.widthF() <= 0.0 || size2.isEmpty() ) qreal width = pen.widthF();
return pen;
const auto f = qMin( size1.width() / size2.width(), if ( !pen.isCosmetic() )
size1.height() / size2.height() ); {
const qreal sx = r1.width() / r2.width();
const qreal sy = r1.height() / r2.height();
auto newPen = pen; width *= std::min( sx, sy );
newPen.setWidthF( pen.widthF() * f ); }
newPen.setCosmetic( true );
return newPen; return width;
} }
ShapeItem::ShapeItem( QQuickItem* parent ) ShapeItem::ShapeItem( QQuickItem* parent )
@ -125,8 +126,6 @@ void ShapeItem::updateNode( QSGNode* parentNode )
return; return;
} }
const auto pen = ::cosmeticPen( m_pen, rect.size(), pathRect.size() );
if ( ::isVisible( m_fillColor[0] ) || ::isVisible( m_fillColor[1] ) ) if ( ::isVisible( m_fillColor[0] ) || ::isVisible( m_fillColor[1] ) )
{ {
if ( fillNode == nullptr ) if ( fillNode == nullptr )
@ -138,9 +137,9 @@ void ShapeItem::updateNode( QSGNode* parentNode )
} }
auto fillRect = rect; auto fillRect = rect;
if ( pen.style() != Qt::NoPen ) if ( m_pen.style() != Qt::NoPen )
{ {
const auto pw2 = 0.5 * pen.widthF(); const auto pw2 = 0.5 * ::effectivePenWidth( m_pen, rect, pathRect );
fillRect.adjust( pw2, pw2, -pw2, -pw2 ); fillRect.adjust( pw2, pw2, -pw2, -pw2 );
} }
@ -166,11 +165,12 @@ void ShapeItem::updateNode( QSGNode* parentNode )
delete fillNode; delete fillNode;
} }
if ( ::isVisible( pen ) ) if ( ::isVisible( m_pen ) )
{ {
if ( pen.widthF() > 1.0 ) #if 0
if ( m_pen.widthF() > 1.0 )
{ {
if ( !( pen.isSolid() && pen.color().alpha() == 255 ) ) if ( !( m_pen.isSolid() && m_pen.color().alpha() == 255 ) )
{ {
/* /*
We might end up with overlapping parts We might end up with overlapping parts
@ -182,6 +182,7 @@ void ShapeItem::updateNode( QSGNode* parentNode )
*/ */
} }
} }
#endif
if ( borderNode == nullptr ) if ( borderNode == nullptr )
{ {
@ -192,7 +193,7 @@ void ShapeItem::updateNode( QSGNode* parentNode )
} }
const auto transform = ::transformForRects( pathRect, rect ); const auto transform = ::transformForRects( pathRect, rect );
borderNode->updateNode( m_path, transform, pen ); borderNode->updateNode( m_path, transform, m_pen );
} }
else else
{ {

View File

@ -26,7 +26,7 @@ namespace
Pen( const QColor& color ) Pen( const QColor& color )
: QPen( color ) : QPen( color )
{ {
setCosmetic( true ); //setCosmetic( true );
setWidth( isCosmetic() ? 8 : 2 ); setWidth( isCosmetic() ? 8 : 2 );
setJoinStyle( Qt::MiterJoin ); setJoinStyle( Qt::MiterJoin );

View File

@ -58,32 +58,36 @@ void QskStrokeNode::updateNode(
*/ */
const auto scaledPath = transform.map( path ); const auto scaledPath = transform.map( path );
auto effectivePen = pen;
if ( !effectivePen.isCosmetic() )
{
const auto scaleFactor = qMin( transform.m11(), transform.m22() );
if ( scaleFactor != 1.0 )
{
effectivePen.setWidth( effectivePen.widthF() * scaleFactor );
effectivePen.setCosmetic( false );
}
}
QTriangulatingStroker stroker; QTriangulatingStroker stroker;
#if 0
// can we do something useful with this factor ???
stroker.setInvScale( 1.0 );
#endif
if ( pen.style() == Qt::SolidLine ) if ( pen.style() == Qt::SolidLine )
{ {
// clipRect, renderHint are ignored in QTriangulatingStroker::process // clipRect, renderHint are ignored in QTriangulatingStroker::process
stroker.process( qtVectorPathForPath( scaledPath ), pen, {}, {} ); stroker.process( qtVectorPathForPath( scaledPath ), effectivePen, {}, {} );
} }
else else
{ {
constexpr QRectF clipRect; // empty rect: no clipping constexpr QRectF clipRect; // empty rect: no clipping
QDashedStrokeProcessor dashStroker; QDashedStrokeProcessor dashStroker;
#if 0 dashStroker.process( qtVectorPathForPath( scaledPath ), effectivePen, clipRect, {} );
// can we do something useful with this factor ???
dashStroker.setInvScale( 1.0 );
#endif
dashStroker.process( qtVectorPathForPath( scaledPath ), pen, clipRect, {} );
const QVectorPath dashedVectorPath( dashStroker.points(), const QVectorPath dashedVectorPath( dashStroker.points(),
dashStroker.elementCount(), dashStroker.elementTypes(), 0 ); dashStroker.elementCount(), dashStroker.elementTypes(), 0 );
stroker.process( dashedVectorPath, pen, {}, {} ); stroker.process( dashedVectorPath, effectivePen, {}, {} );
} }
d->geometry.allocate( stroker.vertexCount() ); d->geometry.allocate( stroker.vertexCount() );