QSkinny 0.8.0
C++/Qt UI toolkit
Loading...
Searching...
No Matches
QskStippledLineRenderer.cpp
1/******************************************************************************
2 * QSkinny - Copyright (C) The authors
3 * SPDX-License-Identifier: BSD-3-Clause
4 *****************************************************************************/
5
6#include "QskStippledLineRenderer.h"
7
8QSK_QT_PRIVATE_BEGIN
9#include <private/qstroker_p.h>
10QSK_QT_PRIVATE_END
11
12namespace
13{
14 /*
15 Thanks to the hooks of the stroker classes we can make use
16 of QDashStroker without having to deal with the overhead of
17 QPainterPaths. But it might be worth to check if this could
18 be done in a shader. TODO ...
19 */
20 class DashStroker : public QDashStroker
21 {
22 public:
23 DashStroker( QskStippledLineRenderer* renderer )
24 : QDashStroker( nullptr )
25 , m_renderer( renderer )
26 {
27 setDashOffset( renderer->metrics().offset() );
28 setDashPattern( renderer->metrics().pattern() );
29
30 m_elements.reserve( 2 );
31 }
32
33 void renderDashes( qreal x1, qreal y1, qreal x2, qreal y2 )
34 {
35 if ( ( x1 == x2 ) && ( y1 == y2 ) )
36 return;
37
38 setMoveToHook( moveTo );
39 setLineToHook( lineTo );
40
41 begin( this );
42
43 m_elements.add( { QPainterPath::MoveToElement, x1, y1 } );
44 m_elements.add( { QPainterPath::LineToElement, x2, y2 } );
45
46 processCurrentSubpath();
47
48 end();
49 }
50
51 qsizetype dashCount( qreal x1, qreal y1, qreal x2, qreal y2 )
52 {
53 if ( ( x1 == x2 ) && ( y1 == y2 ) )
54 return 0;
55
56 /*
57 There should be a faster way to calculate the
58 number of points. TODO ...
59 */
60 setMoveToHook( countMoveTo );
61 setLineToHook( countLineTo );
62
63 m_count = 0;
64
65 begin( this );
66
67 m_elements.add( { QPainterPath::MoveToElement, x1, y1 } );
68 m_elements.add( { QPainterPath::LineToElement, x2, y2 } );
69
70 processCurrentSubpath();
71
72 end();
73
74 return m_count;
75 }
76
77 private:
78 static void moveTo( qfixed x, qfixed y, void* data )
79 {
80 auto stroker = reinterpret_cast< DashStroker* >( data );
81
82 stroker->m_x = x;
83 stroker->m_y = y;
84 }
85
86 static void lineTo( qfixed x, qfixed y, void* data )
87 {
88 auto stroker = reinterpret_cast< DashStroker* >( data );
89 stroker->m_renderer->renderDash( stroker->m_x, stroker->m_y, x, y );
90 }
91
92 static void countMoveTo( qfixed, qfixed, void* )
93 {
94 }
95
96 static void countLineTo( qfixed, qfixed, void* data )
97 {
98 auto stroker = reinterpret_cast< DashStroker* >( data );
99 stroker->m_count++;
100 }
101
102 QskStippledLineRenderer* m_renderer;
103
104 qsizetype m_count = 0;
105 qreal m_x, m_y;
106 };
107}
108
109QskStippledLineRenderer::QskStippledLineRenderer( const QskStippleMetrics& metrics )
110 : m_metrics( metrics )
111{
112}
113
114QskStippledLineRenderer::~QskStippledLineRenderer()
115{
116}
117
118qsizetype QskStippledLineRenderer::dashCount(
119 const QPointF& p1, const QPointF& p2 ) const
120{
121 return dashCount( p1.x(), p1.y(), p2.x(), p2.y() );
122}
123
124qsizetype QskStippledLineRenderer::dashCount( const QLineF& line ) const
125{
126 return dashCount( line.x1(), line.y1(), line.x2(), line.y2() );
127}
128
129qsizetype QskStippledLineRenderer::dashCount(
130 qreal x1, qreal y1, qreal x2, qreal y2 ) const
131{
132 auto that = const_cast< QskStippledLineRenderer* >( this );
133 return DashStroker( that ).dashCount( x1, y1, x2, y2 );
134}
135
136void QskStippledLineRenderer::renderLine( const QPointF& p1, const QPointF& p2 )
137{
138 renderLine( p1.x(), p1.y(), p2.x(), p2.y() );
139}
140
141void QskStippledLineRenderer::renderLine( const QLineF& line )
142{
143 renderLine( line.x1(), line.y1(), line.x2(), line.y2() );
144}
145
146void QskStippledLineRenderer::renderLine( qreal x1, qreal y1, qreal x2, qreal y2 )
147{
148 DashStroker( this ).renderDashes( x1, y1, x2, y2 );
149}
150
151void QskStippledLineRenderer::renderDash( qreal, qreal, qreal, qreal )
152{
153 // nop
154}