1 /*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2018-2020 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25 /**
26 * @file marker_base.cpp
27 * @brief Implementation of MARKER_BASE class.
28 * Markers are used to show something (usually a drc/erc problem).
29 * Markers in Pcbnew and Eeschema are derived from this base class.
30 */
31
32
33 #include "base_screen.h"
34 #include "marker_base.h"
35 #include <core/arraydim.h>
36 #include <geometry/shape_line_chain.h>
37 #include <render_settings.h>
38 #include "dialogs/dialog_display_html_text_base.h"
39
40
41 /* The graphic shape of markers is a polygon.
42 * MarkerShapeCorners contains the coordinates of corners of the polygonal default shape
43 * they are arbitrary units to make coding shape easy.
44 * internal units coordinates are these values scaled by .m_ScalingFactor
45 */
46 static const VECTOR2I MarkerShapeCorners[] =
47 {
48 VECTOR2I( 0, 0 ),
49 VECTOR2I( 8, 1 ),
50 VECTOR2I( 4, 3 ),
51 VECTOR2I( 13, 8 ),
52 VECTOR2I( 9, 9 ),
53 VECTOR2I( 8, 13 ),
54 VECTOR2I( 3, 4 ),
55 VECTOR2I( 1, 8 ),
56 VECTOR2I( 0, 0 )
57 };
58 const unsigned CORNERS_COUNT = arrayDim( MarkerShapeCorners );
59
60
MARKER_BASE(int aScalingFactor,std::shared_ptr<RC_ITEM> aItem,TYPEMARKER aType)61 MARKER_BASE::MARKER_BASE( int aScalingFactor, std::shared_ptr<RC_ITEM> aItem, TYPEMARKER aType ) :
62 m_markerType( aType ),
63 m_excluded( false ),
64 m_rcItem( aItem ),
65 m_scalingFactor( aScalingFactor )
66 {
67 const VECTOR2I* point_shape = MarkerShapeCorners;
68 wxPoint start( point_shape->x, point_shape->y );
69 wxPoint end = start;
70
71 for( unsigned ii = 1; ii < CORNERS_COUNT; ii++ )
72 {
73 ++point_shape;
74 start.x = std::min( start.x, point_shape->x);
75 start.y = std::min( start.y, point_shape->y);
76 end.x = std::max( end.x, point_shape->x);
77 end.y = std::max( end.y, point_shape->y);
78 }
79
80 m_shapeBoundingBox.SetOrigin( start);
81 m_shapeBoundingBox.SetEnd( end);
82 }
83
84
~MARKER_BASE()85 MARKER_BASE::~MARKER_BASE()
86 {
87 }
88
89
HitTestMarker(const wxPoint & aHitPosition,int aAccuracy) const90 bool MARKER_BASE::HitTestMarker( const wxPoint& aHitPosition, int aAccuracy ) const
91 {
92 EDA_RECT bbox = GetBoundingBoxMarker();
93 bbox.Inflate( aAccuracy );
94
95 // Fast hit test using boundary box. A finer test will be made if requested
96 bool hit = bbox.Contains( aHitPosition );
97
98 if( hit ) // Fine test
99 {
100 SHAPE_LINE_CHAIN polygon;
101 ShapeToPolygon( polygon );
102 VECTOR2I rel_pos( aHitPosition - m_Pos );
103 hit = polygon.PointInside( rel_pos, aAccuracy );
104 }
105
106 return hit;
107 }
108
109
ShapeToPolygon(SHAPE_LINE_CHAIN & aPolygon,int aScale) const110 void MARKER_BASE::ShapeToPolygon( SHAPE_LINE_CHAIN& aPolygon, int aScale ) const
111 {
112 if( aScale < 0 )
113 aScale = MarkerScale();
114
115 for( const VECTOR2I& corner : MarkerShapeCorners )
116 aPolygon.Append( corner * aScale );
117
118 // Be sure aPolygon is seen as a closed polyline:
119 aPolygon.SetClosed( true );
120 }
121
122
GetBoundingBoxMarker() const123 EDA_RECT MARKER_BASE::GetBoundingBoxMarker() const
124 {
125 wxSize size_iu = m_shapeBoundingBox.GetSize();
126 wxPoint position_iu = m_shapeBoundingBox.GetPosition();
127 size_iu.x *= m_scalingFactor;
128 size_iu.y *= m_scalingFactor;
129 position_iu.x *= m_scalingFactor;
130 position_iu.y *= m_scalingFactor;
131 position_iu += m_Pos;
132
133 return EDA_RECT( position_iu, size_iu );
134 }
135
136
PrintMarker(const RENDER_SETTINGS * aSettings,const wxPoint & aOffset)137 void MARKER_BASE::PrintMarker( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset )
138 {
139 wxDC* DC = aSettings->GetPrintDC();
140
141 // Build the marker shape polygon in internal units:
142 std::vector<wxPoint> shape;
143 shape.reserve( CORNERS_COUNT );
144
145 for( const VECTOR2I& corner : MarkerShapeCorners )
146 shape.emplace_back( corner * MarkerScale() + m_Pos + aOffset );
147
148 GRClosedPoly( nullptr, DC, CORNERS_COUNT, &shape[0], true, 0, getColor(), getColor() );
149 }
150