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-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 #include <sch_draw_panel.h>
26 #include <plotter.h>
27 #include <trigo.h>
28 #include <base_units.h>
29 #include <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 
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 
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 )
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( RENDER_SETTINGS* aSettings, const wxPoint& aOffset, void* aData,
162  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, BLUE ) );
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 ) );
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  return false;
254 }
255 
256 
258 {
259  return wxString::Format( _( "Rectangle, width %s height %s" ),
260  MessageTextFromValue( aUnits, std::abs( m_Pos.x - m_End.x ) ),
261  MessageTextFromValue( aUnits, std::abs( m_Pos.y - m_End.y ) ) );
262 }
263 
264 
266 {
267  return add_rectangle_xpm;
268 }
269 
270 
271 void LIB_RECTANGLE::BeginEdit( const wxPoint aPosition )
272 {
273  m_Pos = m_End = aPosition;
274 }
275 
276 
277 void LIB_RECTANGLE::CalcEdit( const wxPoint& aPosition )
278 {
279  m_End = aPosition;
280 }
EDA_UNITS
Definition: common.h:200
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aAddUnitLabel, EDA_DATA_TYPE aType)
Definition: base_units.cpp:122
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
Common plot library 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
Function HitTest tests if aPosition is contained within or on the bounding box of an item.
PNG memory record (file in memory).
Definition: bitmap_def.h:29
RENDER_SETTINGS Contains all the knowledge about how graphical objects are drawn on any output surfac...
Implementation of conversion functions that require both schematic and board internal units.
virtual void SetColor(COLOR4D color)=0
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
Function GetLayerColor Returns the color used to draw a layer.
TRANSFORM DefaultTransform
void SetOrigin(const wxPoint &pos)
Definition: eda_rect.h:131
void MoveTo(const wxPoint &aPosition) override
Move a draw object to aPosition.
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
void BeginEdit(const wxPoint aStartPoint) override
Begin drawing a component library draw item at aPosition.
The base class for create windows for drawing purpose.
void RevertYAxis()
Function RevertYAxis Mirror the rectangle from the X axis (negate Y pos and size)
Definition: eda_rect.h:209
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 components.
Definition: lib_item.h:62
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 m_Fill
The body fill type.
Definition: lib_item.h:94
const BITMAP_OPAQUE add_rectangle_xpm[1]
FILL_TYPE GetFillMode() const
Definition: lib_item.h:302
void GRRect(EDA_RECT *aClipBox, wxDC *aDC, int x1, int y1, int x2, int y2, COLOR4D aColor)
Definition: gr_basic.cpp:842
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
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:117
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
void SetEnd(int x, int y)
Definition: eda_rect.h:192
void print(RENDER_SETTINGS *aSettings, const wxPoint &aOffset, void *aData, const TRANSFORM &aTransform) override
Print the item to aDC.
#define MINIMUM_SELECTION_DISTANCE
Definition: lib_item.h:48
bool m_isFillable
Definition: lib_item.h:95
int GetPenWidth() const override
Define a library symbol object.
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
Base plotter engine class.
Definition: plotter.h:120
Definition: color4d.h:57
LIB_RECTANGLE(LIB_PART *aParent)
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:153
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:201
void Plot(PLOTTER *aPlotter, const wxPoint &aOffset, bool aFill, const TRANSFORM &aTransform) override
Plot the draw item using the plot object.
#define _(s)
Definition: 3d_actions.cpp:33
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
void Offset(const wxPoint &aOffset) override
Set the drawing object by aOffset from the current position.
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: eda_item.h:147
std::vector< MSG_PANEL_ITEM > MSG_PANEL_ITEMS
Definition: msgpanel.h:103
int GetDefaultPenWidth() const
void CalcEdit(const wxPoint &aPosition) override
Calculates the attributes of an item at aPosition when it is being edited.
EDA_MSG_ITEM is used EDA_MSG_PANEL as the item type for displaying messages.
Definition: msgpanel.h:54
Message panel definition file.
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.
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
Definition: eda_rect.cpp:363
KICAD_T Type() const
Function Type()
Definition: eda_item.h:181
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.
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:100