KiCad PCB EDA Suite
sch_bitmap.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) 2011 jean-pierre.charras
5  * Copyright (C) 2011 KiCad Developers, see change_log.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 
29 #include <fctsys.h>
30 #include <class_drawpanel.h>
31 #include <trigo.h>
32 #include <macros.h>
33 #include <bitmaps.h>
34 
35 #include <sch_bitmap.h>
36 
37 #include <wx/mstream.h>
38 
39 
40 /*
41  * class SCH_BITMAP
42  * This class handle a bitmap image that can be inserted in a schematic.
43  */
44 
46  SCH_ITEM( NULL, SCH_BITMAP_T )
47 {
48  m_pos = pos;
49  m_Layer = LAYER_NOTES; // used only to draw/plot a rectangle,
50  // when a bitmap cannot be drawn or plotted
51  m_image = new BITMAP_BASE();
52 }
53 
54 
55 SCH_BITMAP::SCH_BITMAP( const SCH_BITMAP& aSchBitmap ) :
56  SCH_ITEM( aSchBitmap )
57 {
58  m_pos = aSchBitmap.m_pos;
59  m_Layer = aSchBitmap.m_Layer;
60  m_image = new BITMAP_BASE( *aSchBitmap.m_image );
61 }
62 
63 
65 {
66  wxCHECK_MSG( Type() == aItem.Type(), *this,
67  wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) +
68  GetClass() );
69 
70  if( &aItem != this )
71  {
72  SCH_ITEM::operator=( aItem );
73 
74  SCH_BITMAP* bitmap = (SCH_BITMAP*) &aItem;
75 
76  delete m_image;
77  m_image = new BITMAP_BASE( *bitmap->m_image );
78  m_pos = bitmap->m_pos;
79  }
80 
81  return *this;
82 }
83 
84 
85 bool SCH_BITMAP::ReadImageFile( const wxString& aFullFilename )
86 {
87  return m_image->ReadImageFile( aFullFilename );
88 }
89 
90 
91 bool SCH_BITMAP::Save( FILE* aFile ) const
92 {
93  if( fprintf( aFile, "$Bitmap\n" ) == EOF )
94  return false;
95 
96  if( fprintf( aFile, "Pos %-4d %-4d\n", m_pos.x, m_pos.y ) == EOF )
97  return false;
98 
99  if( fprintf( aFile, "Scale %f\n", m_image->GetScale() ) == EOF )
100  return false;
101 
102  if( fprintf( aFile, "Data\n" ) == EOF )
103  return false;
104 
105  if( !m_image->SaveData( aFile ) )
106  return false;
107 
108  if( fprintf( aFile, "\nEndData\n" ) == EOF )
109  return false;
110 
111 
112  if( fprintf( aFile, "$EndBitmap\n" ) == EOF )
113  return false;
114 
115  return true;
116 }
117 
118 
120 {
121  return new SCH_BITMAP( *this );
122 }
123 
124 
126 {
127  wxCHECK_RET( aItem->Type() == SCH_BITMAP_T,
128  wxString::Format( wxT( "SCH_BITMAP object cannot swap data with %s object." ),
129  GetChars( aItem->GetClass() ) ) );
130 
131  SCH_BITMAP* item = (SCH_BITMAP*) aItem;
132  std::swap( m_pos, item->m_pos );
133  std::swap( m_image, item->m_image );
134 }
135 
136 
137 bool SCH_BITMAP::Load( LINE_READER& aLine, wxString& aErrorMsg )
138 {
139  char* line = aLine.Line();
140 
141  if( strncasecmp( line, "$Bitmap", 7 ) != 0 )
142  {
143  aErrorMsg.Printf( wxT( "Eeschema file bitmap image load error at line %d, aborted" ),
144  aLine.LineNumber() );
145  aErrorMsg << wxT( "\n" ) << FROM_UTF8( (char*) aLine );
146  return false;
147  }
148 
149  for( ; ; )
150  {
151  if( !aLine.ReadLine() )
152  return false;
153 
154  line = aLine.Line();
155 
156  if( strncasecmp( line, "Pos", 3 ) == 0 )
157  {
158  sscanf( line + 3, "%d %d", &m_pos.x, &m_pos.y );
159  continue;
160  }
161 
162  if( strncasecmp( line, "Scale", 5 ) == 0 )
163  {
164  double scale = 1.0;
165  sscanf( line + 5, "%lf", &scale );
166  m_image->SetScale( scale );
167  continue;
168  }
169 
170  if( strncasecmp( line, "Data", 4 ) == 0 )
171  {
172  m_image->LoadData( aLine, aErrorMsg );
173  }
174 
175  if( strncasecmp( line, "$EndBitmap", 4 ) == 0 )
176  break;
177  }
178 
179  return true;
180 }
181 
182 
184 {
185  EDA_RECT rect = m_image->GetBoundingBox();
186 
187  rect.Move( m_pos );
188 
189  return rect;
190 }
191 
192 
193 void SCH_BITMAP::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
194  GR_DRAWMODE aDrawMode, COLOR4D aColor )
195 {
196  wxPoint pos = m_pos + aOffset;
197 
198  if( aColor == COLOR4D::UNSPECIFIED ) // Use normal drawing function
199  {
200  // https://bugs.launchpad.net/kicad/+bug/1529163
201  // "Moving images in eeschema on OS X uses
202  // wrong position and shows image flipped"
203  //
204  // Original fix was to only GRSetDrawMode if aColor >= 0, but this made
205  // moving SCH_BITMAP work poorly on other platforms.
206 #ifndef __WXMAC__
207  GRSetDrawMode( aDC, aDrawMode );
208 #endif
209 
210  m_image->DrawBitmap( aPanel, aDC, pos );
211  }
212  else // draws bounding box only (used to move items)
213  {
214  GRSetDrawMode( aDC, aDrawMode );
215  // To draw the rect, pos is the upper left corner position
216  wxSize size = m_image->GetSize();
217  pos.x -= size.x / 2;
218  pos.y -= size.y / 2;
219  GRRect( aPanel->GetClipBox(), aDC, pos.x, pos.y,
220  pos.x + size.x, pos.y + size.y, 0, aColor );
221  }
222 }
223 
224 
225 /* Function GetSize
226  * returns the actual size (in user units, not in pixels) of the image
227  */
228 wxSize SCH_BITMAP::GetSize() const
229 {
230  return m_image->GetSize();
231 }
232 
233 
234 /*
235  * Mirror image relative to a horizontal X axis )
236  */
237 void SCH_BITMAP::MirrorX( int aXaxis_position )
238 {
239  MIRROR( m_pos.y, aXaxis_position );
240  m_image->Mirror( true );
241 }
242 
243 
244 /*
245  * Mirror image relative to a vertical Y axis
246  */
247 void SCH_BITMAP::MirrorY( int aYaxis_position )
248 {
249  MIRROR( m_pos.x, aYaxis_position );
250  m_image->Mirror( false );
251 }
252 
253 
254 void SCH_BITMAP::Rotate( wxPoint aPosition )
255 {
256  RotatePoint( &m_pos, aPosition, 900 );
257  m_image->Rotate( false );
258 }
259 
260 
261 bool SCH_BITMAP::IsSelectStateChanged( const wxRect& aRect )
262 {
263  bool previousState = IsSelected();
264 
265  if( aRect.Contains( m_pos ) )
266  SetFlags( SELECTED );
267  else
268  ClearFlags( SELECTED );
269 
270  return previousState != IsSelected();
271 }
272 
273 
274 #if defined(DEBUG)
275 void SCH_BITMAP::Show( int nestLevel, std::ostream& os ) const
276 {
277  // XML output:
278  wxString s = GetClass();
279 
280  NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << m_pos << "/>\n";
281 }
282 
283 
284 #endif
285 
286 
287 bool SCH_BITMAP::HitTest( const wxPoint& aPosition, int aAccuracy ) const
288 {
289  EDA_RECT rect = GetBoundingBox();
290 
291  rect.Inflate( aAccuracy );
292 
293  return rect.Contains( aPosition );
294 }
295 
296 
297 bool SCH_BITMAP::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
298 {
299  EDA_RECT rect = aRect;
300 
301  rect.Inflate( aAccuracy );
302 
303  if( aContained )
304  return rect.Contains( GetBoundingBox() );
305 
306  return rect.Intersects( GetBoundingBox() );
307 }
308 
309 
310 void SCH_BITMAP::Plot( PLOTTER* aPlotter )
311 {
312  m_image->PlotImage( aPlotter, m_pos, GetLayerColor( GetLayer() ), GetPenSize() );
313 }
314 
315 
317 {
318  return image_xpm;
319 }
KICAD_T Type() const
Function Type()
Definition: base_struct.h:212
SCH_LAYER_ID m_Layer
SCH_ITEM & operator=(const SCH_ITEM &aItem)
Definition: sch_bitmap.cpp:64
Class LINE_READER is an abstract class from which implementation specific LINE_READERs may be derived...
Definition: richio.h:81
void Move(const wxPoint &aMoveVector)
Function Move moves the rectangle by the aMoveVector.
void Draw(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aOffset, GR_DRAWMODE aDrawMode, COLOR4D aColor=COLOR4D::UNSPECIFIED) override
Function Draw Draw a schematic item.
Definition: sch_bitmap.cpp:193
virtual unsigned LineNumber() const
Function Line Number returns the line number of the last line read from this LINE_READER.
Definition: richio.h:159
PNG memory record (file in memory).
Definition: bitmap_types.h:38
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes...
Definition: macros.h:53
void GRSetDrawMode(wxDC *DC, GR_DRAWMODE draw_mode)
Definition: gr_basic.cpp:290
bool SaveData(FILE *aFile) const
writes the bitmap data to aFile The format is png, in Hexadecimal form: If the hexadecimal data is co...
bool Contains(const wxPoint &aPoint) const
Function Contains.
wxSize GetSize() const
Function GetSize.
void SetScale(double aScale)
bool IsSelected() const
Definition: base_struct.h:235
bool Save(FILE *aFile) const override
Function Save writes the data structures for this object out to a FILE in "*.sch" format...
Definition: sch_bitmap.cpp:91
wxPoint m_pos
Definition: sch_bitmap.h:40
SCH_LAYER_ID GetLayer() const
Function GetLayer returns the layer this item is on.
void PlotImage(PLOTTER *aPlotter, const wxPoint &aPos, COLOR4D aDefaultColor, int aDefaultPensize)
Function PlotImage Plot bitmap on plotter.
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
COLOR4D GetLayerColor(SCH_LAYER_ID aLayer)
Definition: eeschema.cpp:167
const EDA_RECT GetBoundingBox() const
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
Definition: sch_bitmap.cpp:316
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
Definition: sch_bitmap.cpp:183
void Mirror(bool aVertically)
Function Mirror Mirror image vertically (i.e.
void MirrorY(int aYaxis_position) override
Function MirrorY mirrors item relative to the Y axis about aYaxis_position.
Definition: sch_bitmap.cpp:247
This file contains miscellaneous commonly used macros and functions.
This class handle bitmap images in KiCad.
void Rotate(wxPoint aPosition) override
Function Rotate rotates the item around aPosition 90 degrees in the clockwise direction.
Definition: sch_bitmap.cpp:254
void MIRROR(T &aPoint, const T &aMirrorRef)
Definition: macros.h:111
#define SELECTED
Definition: base_struct.h:134
void GRRect(EDA_RECT *aClipBox, wxDC *aDC, int x1, int y1, int x2, int y2, COLOR4D aColor)
Definition: gr_basic.cpp:1077
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:267
GR_DRAWMODE
Drawmode. Compositing mode plus a flag or two.
Definition: gr_basic.h:41
char * Line() const
Function Line returns a pointer to the last line that was read in.
Definition: richio.h:139
wxSize GetSize() const
Function GetSize.
Definition: sch_bitmap.cpp:228
bool Load(LINE_READER &aLine, wxString &aErrorMsg) override
Function Load reads a schematic item from aLine in a .sch file.
Definition: sch_bitmap.cpp:137
void SwapData(SCH_ITEM *aItem) override
Function SwapData swap the internal data structures aItem with the schematic item.
Definition: sch_bitmap.cpp:125
EDA_RECT * GetClipBox()
EDA_ITEM & operator=(const EDA_ITEM &aItem)
Operator assignment is used to assign the members of aItem to another object.
double GetScale() const
Base plotter engine class.
Definition: plot_common.h:86
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
const int scale
virtual char * ReadLine()=0
Function ReadLine reads a line of text into the buffer and increments the line number counter...
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
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 MirrorX(int aXaxis_position) override
Function MirrorX mirrors item relative to the X axis about aXaxis_position.
Definition: sch_bitmap.cpp:237
Class EDA_RECT handles the component boundary box.
bool LoadData(LINE_READER &aLine, wxString &aErrorMsg)
Load an image data saved by SaveData (png, in Hexadecimal form)
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
Definition: sch_bitmap.cpp:119
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:165
bool HitTest(const wxPoint &aPosition, int aAccuracy) const override
Function HitTest tests if aPosition is contained within or on the bounding box of an item...
Definition: sch_bitmap.cpp:287
virtual wxString GetClass() const override
Function GetClass returns the class name.
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:268
SCH_BITMAP(const wxPoint &pos=wxPoint(0, 0))
Definition: sch_bitmap.cpp:45
bool ReadImageFile(const wxString &aFullFilename)
Function ReadImageFile Reads and stores in memory an image file.
bool ReadImageFile(const wxString &aFullFilename)
Function ReadImageFile Reads and stores an image file.
Definition: sch_bitmap.cpp:85
bool IsSelectStateChanged(const wxRect &aRect) override
Function IsSelectStateChanged checks if the selection state of an item inside aRect has changed...
Definition: sch_bitmap.cpp:261
void DrawBitmap(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aPos)
void Rotate(bool aRotateCCW)
Function Rotate Rotate image CW or CCW.
BITMAP_BASE * m_image
Definition: sch_bitmap.h:41
wxString GetClass() const override
Function GetClass returns the class name.
Definition: sch_bitmap.h:85
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...
void Plot(PLOTTER *aPlotter) override
Function Plot plots the schematic item to aPlotter.
Definition: sch_bitmap.cpp:310
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
wxImage * m_image
virtual int GetPenSize() const
Function GetPenSize virtual pure.
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39