KiCad PCB EDA Suite
lib_rectangle.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 (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2004-2021 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 #include <sch_draw_panel.h>
26 #include <plotter.h>
27 #include <trigo.h>
28 #include <base_units.h>
29 #include <widgets/msgpanel.h>
30 #include <bitmaps.h>
31 #include <eda_draw_frame.h>
32 #include <general.h>
33 #include <lib_rectangle.h>
35 #include <transform.h>
36 
37 
39 {
40  m_Width = 0;
42  m_isFillable = true;
43 }
44 
45 
47 {
48  return new LIB_RECTANGLE( *this );
49 }
50 
51 
52 int LIB_RECTANGLE::compare( const LIB_ITEM& aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags ) const
53 {
54  wxASSERT( aOther.Type() == LIB_RECTANGLE_T );
55 
56  int retv = LIB_ITEM::compare( aOther );
57 
58  if( retv )
59  return retv;
60 
61  const LIB_RECTANGLE* tmp = ( LIB_RECTANGLE* ) &aOther;
62 
63  if( m_Pos.x != tmp->m_Pos.x )
64  return m_Pos.x - tmp->m_Pos.x;
65 
66  if( m_Pos.y != tmp->m_Pos.y )
67  return m_Pos.y - tmp->m_Pos.y;
68 
69  if( m_End.x != tmp->m_End.x )
70  return m_End.x - tmp->m_End.x;
71 
72  if( m_End.y != tmp->m_End.y )
73  return m_End.y - tmp->m_End.y;
74 
75  return 0;
76 }
77 
78 
79 void LIB_RECTANGLE::Offset( const wxPoint& aOffset )
80 {
81  m_Pos += aOffset;
82  m_End += aOffset;
83 }
84 
85 
86 void LIB_RECTANGLE::MoveTo( const wxPoint& aPosition )
87 {
88  wxPoint size = m_End - m_Pos;
89  m_Pos = aPosition;
90  m_End = aPosition + size;
91 }
92 
93 
94 void LIB_RECTANGLE::MirrorHorizontal( const wxPoint& aCenter )
95 {
96  m_Pos.x -= aCenter.x;
97  m_Pos.x *= -1;
98  m_Pos.x += aCenter.x;
99  m_End.x -= aCenter.x;
100  m_End.x *= -1;
101  m_End.x += aCenter.x;
102 }
103 
104 
105 void LIB_RECTANGLE::MirrorVertical( const wxPoint& aCenter )
106 {
107  m_Pos.y -= aCenter.y;
108  m_Pos.y *= -1;
109  m_Pos.y += aCenter.y;
110  m_End.y -= aCenter.y;
111  m_End.y *= -1;
112  m_End.y += aCenter.y;
113 }
114 
115 
116 void LIB_RECTANGLE::Rotate( const wxPoint& aCenter, bool aRotateCCW )
117 {
118  int rot_angle = aRotateCCW ? -900 : 900;
119  RotatePoint( &m_Pos, aCenter, rot_angle );
120  RotatePoint( &m_End, aCenter, rot_angle );
121 }
122 
123 
124 void LIB_RECTANGLE::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
125  const TRANSFORM& aTransform ) const
126 {
127  wxASSERT( aPlotter != NULL );
128 
129  wxPoint pos = aTransform.TransformCoordinate( m_Pos ) + aOffset;
130  wxPoint end = aTransform.TransformCoordinate( m_End ) + aOffset;
131 
133  {
134  aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE_BACKGROUND ) );
135  aPlotter->Rect( pos, end, FILL_TYPE::FILLED_WITH_BG_BODYCOLOR, 0 );
136  }
137 
138  bool already_filled = m_fill == FILL_TYPE::FILLED_WITH_BG_BODYCOLOR;
139  int pen_size = GetPenWidth();
140 
141  if( !already_filled || pen_size > 0 )
142  {
143  pen_size = std::max( pen_size, aPlotter->RenderSettings()->GetMinPenWidth() );
144 
145  aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) );
146  aPlotter->Rect( pos, end, already_filled ? FILL_TYPE::NO_FILL : m_fill, pen_size );
147  }
148 }
149 
150 
152 {
153  // Historically 0 meant "default width" and negative numbers meant "don't stroke".
154  if( m_Width < 0 && GetFillMode() != FILL_TYPE::NO_FILL )
155  return 0;
156  else
157  return std::max( m_Width, 1 );
158 }
159 
160 
161 void LIB_RECTANGLE::print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset,
162  void* aData, const TRANSFORM& aTransform )
163 {
164  bool forceNoFill = static_cast<bool>( aData );
165  int penWidth = GetPenWidth();
166 
167  if( forceNoFill && m_fill != FILL_TYPE::NO_FILL && penWidth == 0 )
168  return;
169 
170  wxDC* DC = aSettings->GetPrintDC();
171  COLOR4D color = aSettings->GetLayerColor( LAYER_DEVICE );
172  wxPoint pt1 = aTransform.TransformCoordinate( m_Pos ) + aOffset;
173  wxPoint pt2 = aTransform.TransformCoordinate( m_End ) + aOffset;
174 
175  if( forceNoFill || m_fill == FILL_TYPE::NO_FILL )
176  {
177  penWidth = std::max( penWidth, aSettings->GetDefaultPenWidth() );
178  GRRect( nullptr, DC, pt1.x, pt1.y, pt2.x, pt2.y, penWidth, color );
179  }
180  else
181  {
184 
185  GRFilledRect( nullptr, DC, pt1.x, pt1.y, pt2.x, pt2.y, penWidth, color, color );
186  }
187 }
188 
189 
191 {
192  LIB_ITEM::GetMsgPanelInfo( aFrame, aList );
193 
194  wxString msg = MessageTextFromValue( aFrame->GetUserUnits(), m_Width );
195 
196  aList.push_back( MSG_PANEL_ITEM( _( "Line Width" ), msg ) );
197 }
198 
199 
201 {
202  EDA_RECT rect;
203 
204  rect.SetOrigin( m_Pos );
205  rect.SetEnd( m_End );
206  rect.Inflate( ( GetPenWidth() / 2 ) + 1 );
207 
208  rect.RevertYAxis();
209 
210  return rect;
211 }
212 
213 
214 bool LIB_RECTANGLE::HitTest( const wxPoint& aPosition, int aAccuracy ) const
215 {
216  int mindist = std::max( aAccuracy + GetPenWidth() / 2,
217  Mils2iu( MINIMUM_SELECTION_DISTANCE ) );
218  wxPoint actualStart = DefaultTransform.TransformCoordinate( m_Pos );
219  wxPoint actualEnd = DefaultTransform.TransformCoordinate( m_End );
220 
221  // locate lower segment
222  wxPoint start, end;
223 
224  start = actualStart;
225  end.x = actualEnd.x;
226  end.y = actualStart.y;
227 
228  if( TestSegmentHit( aPosition, start, end, mindist ) )
229  return true;
230 
231  // locate right segment
232  start.x = actualEnd.x;
233  end.y = actualEnd.y;
234 
235  if( TestSegmentHit( aPosition, start, end, mindist ) )
236  return true;
237 
238  // locate upper segment
239  start.y = actualEnd.y;
240  end.x = actualStart.x;
241 
242  if( TestSegmentHit( aPosition, start, end, mindist ) )
243  return true;
244 
245  // locate left segment
246  start = actualStart;
247  end.x = actualStart.x;
248  end.y = actualEnd.y;
249 
250  if( TestSegmentHit( aPosition, start, end, mindist ) )
251  return true;
252 
253  if( m_fill == FILL_TYPE::NO_FILL )
254  return false;
255 
256  return GetBoundingBox().Contains( aPosition );
257 }
258 
259 
260 bool LIB_RECTANGLE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
261 {
262  if( m_flags & (STRUCT_DELETED | SKIP_STRUCT ) )
263  return false;
264 
265  EDA_RECT sel = aRect;
266 
267  if ( aAccuracy )
268  sel.Inflate( aAccuracy );
269 
270  if( aContained )
271  return sel.Contains( GetBoundingBox() );
272 
273  return sel.Intersects( GetBoundingBox() );
274 }
275 
276 
278 {
279  return wxString::Format( _( "Rectangle, width %s height %s" ),
280  MessageTextFromValue( aUnits, std::abs( m_Pos.x - m_End.x ) ),
281  MessageTextFromValue( aUnits, std::abs( m_Pos.y - m_End.y ) ) );
282 }
283 
284 
286 {
287  return BITMAPS::add_rectangle;
288 }
289 
290 
291 void LIB_RECTANGLE::BeginEdit( const wxPoint& aPosition )
292 {
293  m_Pos = m_End = aPosition;
294 }
295 
296 
297 void LIB_RECTANGLE::CalcEdit( const wxPoint& aPosition )
298 {
299  m_End = aPosition;
300 }
void print(const RENDER_SETTINGS *aSettings, const wxPoint &aOffset, void *aData, const TRANSFORM &aTransform) override
Print the item to aDC.
void BeginEdit(const wxPoint &aStartPoint) override
Begin drawing a symbol library draw item at aPosition.
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aAddUnitLabel, EDA_DATA_TYPE aType)
Convert a value to a string using double notation.
Definition: base_units.cpp:103
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Plot settings, and plotting engines (PostScript, Gerber, HPGL and DXF)
void MirrorHorizontal(const wxPoint &aCenter) override
Mirror the draw object along the horizontal (X) axis about aCenter point.
bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const override
Test if aPosition is contained within or on the bounding box of an item.
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
Implementation of conversion functions that require both schematic and board internal units.
virtual void Rect(const wxPoint &p1, const wxPoint &p2, FILL_TYPE fill, int width=USE_DEFAULT_LINE_WIDTH)=0
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Display basic info (type, part and convert) about the current item in message panel.
void GRFilledRect(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, COLOR4D Color, COLOR4D BgColor)
Definition: gr_basic.cpp:882
int color
Definition: DXF_plotter.cpp:60
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
void SetOrigin(const wxPoint &pos)
Definition: eda_rect.h:121
void MoveTo(const wxPoint &aPosition) override
Move a draw object to aPosition.
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:481
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:228
The base class for create windows for drawing purpose.
Define a library symbol object.
Definition: lib_symbol.h:96
void RevertYAxis()
Mirror the rectangle from the X axis (negate Y pos and size).
Definition: eda_rect.h:198
FILL_TYPE m_fill
The body fill type.
Definition: lib_item.h:326
bool Contains(const wxPoint &aPoint) const
Definition: eda_rect.cpp:57
void Rotate(const wxPoint &aCenter, bool aRotateCCW=true) override
Rotate the object about aCenter point.
wxPoint TransformCoordinate(const wxPoint &aPoint) const
Calculate a new coordinate according to the mirror/rotation transform.
Definition: transform.cpp:42
The base class for drawable items used by schematic library symbols.
Definition: lib_item.h:61
bool TestSegmentHit(const wxPoint &aRefPoint, wxPoint aStart, wxPoint aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
Definition: trigo.cpp:129
FILL_TYPE GetFillMode() const
Definition: lib_item.h:265
void GRRect(EDA_RECT *aClipBox, wxDC *aDC, int x1, int y1, int x2, int y2, COLOR4D aColor)
Definition: gr_basic.cpp:842
LIB_RECTANGLE(LIB_SYMBOL *aParent)
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Return the text to display to be used in the selection clarification context menu when multiple items...
for transforming drawing coordinates for a wxDC device context.
Definition: transform.h:45
#define NULL
COMPARE_FLAGS
The list of flags used by the compare function.
Definition: lib_item.h:81
void SetEnd(int x, int y)
Definition: eda_rect.h:182
#define MINIMUM_SELECTION_DISTANCE
Definition: lib_item.h:47
bool m_isFillable
Definition: lib_item.h:327
int GetPenWidth() const override
#define STRUCT_DELETED
flag indication structures to be erased
#define _(s)
wxDC * GetPrintDC() const
void MirrorVertical(const wxPoint &aCenter) override
Mirror the draw object along the MirrorVertical (Y) axis about aCenter point.
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Display basic info (type, part and convert) about the current item in message panel.
Definition: lib_item.cpp:50
virtual void SetColor(const COLOR4D &color)=0
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
EDA_UNITS
Definition: eda_units.h:38
Base plotter engine class.
Definition: plotter.h:121
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:156
TRANSFORM DefaultTransform
Definition: eeschema.cpp:56
#define SKIP_STRUCT
flag indicating that the structure should be ignored
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:32
Handle the component boundary box.
Definition: eda_rect.h:42
void Offset(const wxPoint &aOffset) override
Set the drawing object by aOffset from the current position.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:100
std::vector< MSG_PANEL_ITEM > MSG_PANEL_ITEMS
Definition: msgpanel.h:97
bool Intersects(const EDA_RECT &aRect) const
Test for a common area between rectangles.
Definition: eda_rect.cpp:150
int GetDefaultPenWidth() const
void CalcEdit(const wxPoint &aPosition) override
Calculate the attributes of an item at aPosition when it is being edited.
EDA_MSG_PANEL items for displaying messages.
Definition: msgpanel.h:53
Message panel definition file.
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
virtual int compare(const LIB_ITEM &aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags=LIB_ITEM::COMPARE_FLAGS::NORMAL) const
Provide the draw object specific comparison called by the == and < operators.
Definition: lib_item.cpp:74
const EDA_RECT GetBoundingBox() const override
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
void Plot(PLOTTER *aPlotter, const wxPoint &aOffset, bool aFill, const TRANSFORM &aTransform) const override
Plot the draw item using the plot object.
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Inflate the rectangle horizontally by dx and vertically by dy.
Definition: eda_rect.cpp:364
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113
int compare(const LIB_ITEM &aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags=LIB_ITEM::COMPARE_FLAGS::NORMAL) const override
Provide the draw object specific comparison called by the == and < operators.
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:103