KiCad PCB EDA Suite
Loading...
Searching...
No Matches
item_drawing_utils.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KICAD, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
21
22#include <array>
23
25#include <geometry/seg.h>
26
27using namespace KIGFX;
28
29void KIGFX::DrawCross( GAL& aGal, const VECTOR2I& aPosition, int aSize )
30{
31 const int size = aSize / 2;
32 aGal.DrawLine( aPosition - VECTOR2I( size, 0 ), aPosition + VECTOR2I( size, 0 ) );
33 aGal.DrawLine( aPosition - VECTOR2I( 0, size ), aPosition + VECTOR2I( 0, size ) );
34}
35
36
37void KIGFX::DrawDashedLine( GAL& aGal, const SEG& aSeg, double aDashSize )
38{
39 const std::array<double, 2> strokes = { aDashSize, aDashSize / 2 };
40 const double dashCycleLen = strokes[0] + strokes[1];
41
42 // Endpoints may overflow int32 when an item is dragged past the coordinate limit, wrapping
43 // an int length negative and spinning the dash loop forever. Measure in double precision.
44 const VECTOR2D segVec( aSeg.B.x - aSeg.A.x, aSeg.B.y - aSeg.A.y );
45 const double segLen = segVec.EuclideanNorm();
46
47 // Draw solid when the cycle is degenerate, sub-pixel, or would emit too many dashes; the
48 // latter two arise for off-screen or overflowed geometry and would otherwise hang.
49 constexpr double maxDashes = 100000.0;
50
51 if( dashCycleLen <= 0.0 || dashCycleLen * aGal.GetWorldScale() <= 1.0
52 || segLen / dashCycleLen > maxDashes )
53 {
54 aGal.DrawLine( aSeg.A, aSeg.B );
55 return;
56 }
57
58 const BOX2I clip = BOX2I::ByCorners( aSeg.A, aSeg.B );
59
60 const double theta = atan2( aSeg.B.y - aSeg.A.y, aSeg.B.x - aSeg.A.x );
61
62 const VECTOR2D cycleVec{
63 dashCycleLen * cos( theta ),
64 dashCycleLen * sin( theta ),
65 };
66
67 const VECTOR2D dashVec{
68 strokes[0] * cos( theta ),
69 strokes[0] * sin( theta ),
70 };
71
72 const unsigned cycleCount = static_cast<unsigned>( segLen / dashCycleLen ) + 1;
73
74 for( unsigned cyclei = 0; cyclei < cycleCount; ++cyclei )
75 {
76 const VECTOR2D dashStart = aSeg.A + cycleVec * cyclei;
77 const VECTOR2D dashEnd = dashStart + dashVec;
78
79 // Drawing each segment can be done rounded to ints.
80 SEG dashSeg{ KiROUND( dashStart ), KiROUND( dashEnd ) };
81
82 if( ClipLine( &clip, dashSeg.A.x, dashSeg.A.y, dashSeg.B.x, dashSeg.B.y ) )
83 break;
84
85 aGal.DrawLine( dashSeg.A, dashSeg.B );
86 }
87}
BOX2< VECTOR2I > BOX2I
Definition box2.h:918
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:986
static constexpr BOX2< VECTOR2I > ByCorners(const VECTOR2I &aCorner1, const VECTOR2I &aCorner2)
Definition box2.h:66
Abstract interface for drawing on a 2D-surface.
virtual void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a line.
double GetWorldScale() const
Get the world scale.
Definition seg.h:38
VECTOR2I A
Definition seg.h:45
VECTOR2I B
Definition seg.h:46
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition vector2d.h:279
a few functions useful in geometry calculations.
bool ClipLine(const BOX2I *aClipBox, int &x1, int &y1, int &x2, int &y2)
Test if any part of a line falls within the bounds of a rectangle.
Utility functions for drawing compound items (i.e.
The Cairo implementation of the graphics abstraction layer.
Definition eda_group.h:29
void DrawCross(GAL &aGal, const VECTOR2I &aPosition, int aSize)
Draw a cross at a given position.
void DrawDashedLine(GAL &aGal, const SEG &aSeg, double aDashSize)
Draw a dashed line.
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683
VECTOR2< double > VECTOR2D
Definition vector2d.h:682