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 <fctsys.h>
26 #include <gr_basic.h>
27 #include <macros.h>
28 #include <sch_draw_panel.h>
29 #include <plotter.h>
30 #include <trigo.h>
31 #include <base_units.h>
32 #include <msgpanel.h>
33 #include <bitmaps.h>
34 #include <eda_draw_frame.h>
35 #include <general.h>
36 #include <lib_rectangle.h>
38 #include <transform.h>
39 
40 
42  LIB_ITEM( LIB_RECTANGLE_T, aParent )
43 {
44  m_Width = 0;
45  m_Fill = NO_FILL;
46  m_isFillable = true;
47 }
48 
49 
51 {
52  return new LIB_RECTANGLE( *this );
53 }
54 
55 
56 int LIB_RECTANGLE::compare( const LIB_ITEM& aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags ) const
57 {
58  wxASSERT( aOther.Type() == LIB_RECTANGLE_T );
59 
60  int retv = LIB_ITEM::compare( aOther );
61 
62  if( retv )
63  return retv;
64 
65  const LIB_RECTANGLE* tmp = ( LIB_RECTANGLE* ) &aOther;
66 
67  if( m_Pos.x != tmp->m_Pos.x )
68  return m_Pos.x - tmp->m_Pos.x;
69 
70  if( m_Pos.y != tmp->m_Pos.y )
71  return m_Pos.y - tmp->m_Pos.y;
72 
73  if( m_End.x != tmp->m_End.x )
74  return m_End.x - tmp->m_End.x;
75 
76  if( m_End.y != tmp->m_End.y )
77  return m_End.y - tmp->m_End.y;
78 
79  return 0;
80 }
81 
82 
83 void LIB_RECTANGLE::Offset( const wxPoint& aOffset )
84 {
85  m_Pos += aOffset;
86  m_End += aOffset;
87 }
88 
89 
90 void LIB_RECTANGLE::MoveTo( const wxPoint& aPosition )
91 {
92  wxPoint size = m_End - m_Pos;
93  m_Pos = aPosition;
94  m_End = aPosition + size;
95 }
96 
97 
99 {
100  m_Pos.x -= aCenter.x;
101  m_Pos.x *= -1;
102  m_Pos.x += aCenter.x;
103  m_End.x -= aCenter.x;
104  m_End.x *= -1;
105  m_End.x += aCenter.x;
106 }
107 
108 
110 {
111  m_Pos.y -= aCenter.y;
112  m_Pos.y *= -1;
113  m_Pos.y += aCenter.y;
114  m_End.y -= aCenter.y;
115  m_End.y *= -1;
116  m_End.y += aCenter.y;
117 }
118 
119 
120 void LIB_RECTANGLE::Rotate( const wxPoint& aCenter, bool aRotateCCW )
121 {
122  int rot_angle = aRotateCCW ? -900 : 900;
123  RotatePoint( &m_Pos, aCenter, rot_angle );
124  RotatePoint( &m_End, aCenter, rot_angle );
125 }
126 
127 
128 void LIB_RECTANGLE::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
129  const TRANSFORM& aTransform )
130 {
131  wxASSERT( aPlotter != NULL );
132 
133  wxPoint pos = aTransform.TransformCoordinate( m_Pos ) + aOffset;
134  wxPoint end = aTransform.TransformCoordinate( m_End ) + aOffset;
135 
136  if( aFill && m_Fill == FILLED_WITH_BG_BODYCOLOR )
137  {
138  aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE_BACKGROUND ) );
139  aPlotter->Rect( pos, end, FILLED_WITH_BG_BODYCOLOR, 0 );
140  }
141 
142  bool already_filled = m_Fill == FILLED_WITH_BG_BODYCOLOR;
143  int pen_size = GetPenWidth();
144 
145  if( !already_filled || pen_size > 0 )
146  {
147  pen_size = std::max( pen_size, aPlotter->RenderSettings()->GetDefaultPenWidth() );
148 
149  aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) );
150  aPlotter->Rect( pos, end, already_filled ? NO_FILL : m_Fill, pen_size );
151  }
152 }
153 
154 
156 {
157  // Historically 0 meant "default width" and negative numbers meant "don't stroke".
158  if( m_Width < 0 && GetFillMode() != NO_FILL )
159  return 0;
160  else
161  return std::max( m_Width, 1 );
162 }
163 
164 
165 void LIB_RECTANGLE::print( RENDER_SETTINGS* aSettings, const wxPoint& aOffset, void* aData,
166  const TRANSFORM& aTransform )
167 {
168  bool forceNoFill = static_cast<bool>( aData );
169  int penWidth = GetPenWidth();
170 
171  if( forceNoFill && m_Fill != NO_FILL && penWidth == 0 )
172  return;
173 
174  wxDC* DC = aSettings->GetPrintDC();
175  COLOR4D color = aSettings->GetLayerColor( LAYER_DEVICE );
176  wxPoint pt1 = aTransform.TransformCoordinate( m_Pos ) + aOffset;
177  wxPoint pt2 = aTransform.TransformCoordinate( m_End ) + aOffset;
178 
179  if( forceNoFill || m_Fill == NO_FILL )
180  {
181  penWidth = std::max( penWidth, aSettings->GetDefaultPenWidth() );
182  GRRect( nullptr, DC, pt1.x, pt1.y, pt2.x, pt2.y, penWidth, color );
183  }
184  else
185  {
188 
189  GRFilledRect( nullptr, DC, pt1.x, pt1.y, pt2.x, pt2.y, penWidth, color, color );
190  }
191 }
192 
193 
195 {
196  LIB_ITEM::GetMsgPanelInfo( aFrame, aList );
197 
198  wxString msg = MessageTextFromValue( aFrame->GetUserUnits(), m_Width, true );
199 
200  aList.push_back( MSG_PANEL_ITEM( _( "Line Width" ), msg, BLUE ) );
201 }
202 
203 
205 {
206  EDA_RECT rect;
207 
208  rect.SetOrigin( m_Pos );
209  rect.SetEnd( m_End );
210  rect.Inflate( ( GetPenWidth() / 2 ) + 1 );
211 
212  rect.RevertYAxis();
213 
214  return rect;
215 }
216 
217 
218 bool LIB_RECTANGLE::HitTest( const wxPoint& aPosition, int aAccuracy ) const
219 {
220  int mindist = std::max( aAccuracy + GetPenWidth() / 2,
221  Mils2iu( MINIMUM_SELECTION_DISTANCE ) );
224 
225  // locate lower segment
226  wxPoint start, end;
227 
228  start = actualStart;
229  end.x = actualEnd.x;
230  end.y = actualStart.y;
231 
232  if( TestSegmentHit( aPosition, start, end, mindist ) )
233  return true;
234 
235  // locate right segment
236  start.x = actualEnd.x;
237  end.y = actualEnd.y;
238 
239  if( TestSegmentHit( aPosition, start, end, mindist ) )
240  return true;
241 
242  // locate upper segment
243  start.y = actualEnd.y;
244  end.x = actualStart.x;
245 
246  if( TestSegmentHit( aPosition, start, end, mindist ) )
247  return true;
248 
249  // locate left segment
250  start = actualStart;
251  end.x = actualStart.x;
252  end.y = actualEnd.y;
253 
254  if( TestSegmentHit( aPosition, start, end, mindist ) )
255  return true;
256 
257  return false;
258 }
259 
260 
262 {
263  return wxString::Format( _( "Rectangle from (%s, %s) to (%s, %s)" ),
264  MessageTextFromValue( aUnits, m_Pos.x ),
265  MessageTextFromValue( aUnits, m_Pos.y ),
266  MessageTextFromValue( aUnits, m_End.x ),
267  MessageTextFromValue( aUnits, m_End.y ) );
268 }
269 
270 
272 {
273  return add_rectangle_xpm;
274 }
275 
276 
277 void LIB_RECTANGLE::BeginEdit( const wxPoint aPosition )
278 {
279  m_Pos = m_End = aPosition;
280 }
281 
282 
283 void LIB_RECTANGLE::CalcEdit( const wxPoint& aPosition )
284 {
285  m_End = aPosition;
286 }
Definition: colors.h:57
EDA_UNITS
Definition: common.h:196
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
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
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:884
int color
Definition: DXF_plotter.cpp:61
FILL_T GetFillMode() const
Definition: lib_item.h:301
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:61
This file contains miscellaneous commonly used macros and functions.
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
const BITMAP_OPAQUE add_rectangle_xpm[1]
void GRRect(EDA_RECT *aClipBox, wxDC *aDC, int x1, int y1, int x2, int y2, COLOR4D aColor)
Definition: gr_basic.cpp:844
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:116
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:47
bool m_isFillable
Definition: lib_item.h:94
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:52
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aUseMils, EDA_DATA_TYPE aType)
Definition: base_units.cpp:124
Base plotter engine class.
Definition: plotter.h:104
LIB_RECTANGLE(LIB_PART *aParent)
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:137
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:205
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
FILL_T m_Fill
The body fill type.
Definition: lib_item.h:93
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: base_struct.h:163
virtual void Rect(const wxPoint &p1, const wxPoint &p2, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH)=0
std::vector< MSG_PANEL_ITEM > MSG_PANEL_ITEMS
Definition: msgpanel.h:102
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:53
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:76
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.
KICAD_T Type() const
Function Type()
Definition: base_struct.h:197
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:40