You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

319 lines
7.5 KiB

  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. /**
  25. * @file sch_bitmap.cpp
  26. */
  27. #include <fctsys.h>
  28. #include <class_drawpanel.h>
  29. #include <trigo.h>
  30. #include <macros.h>
  31. #include <bitmaps.h>
  32. #include <sch_bitmap.h>
  33. #include <wx/mstream.h>
  34. /*
  35. * class SCH_BITMAP
  36. * This class handle a bitmap image that can be inserted in a schematic.
  37. */
  38. SCH_BITMAP::SCH_BITMAP( const wxPoint& pos ) :
  39. SCH_ITEM( NULL, SCH_BITMAP_T )
  40. {
  41. m_pos = pos;
  42. m_Layer = LAYER_NOTES; // used only to draw/plot a rectangle,
  43. // when a bitmap cannot be drawn or plotted
  44. m_image = new BITMAP_BASE();
  45. }
  46. SCH_BITMAP::SCH_BITMAP( const SCH_BITMAP& aSchBitmap ) :
  47. SCH_ITEM( aSchBitmap )
  48. {
  49. m_pos = aSchBitmap.m_pos;
  50. m_Layer = aSchBitmap.m_Layer;
  51. m_image = new BITMAP_BASE( *aSchBitmap.m_image );
  52. }
  53. SCH_ITEM& SCH_BITMAP::operator=( const SCH_ITEM& aItem )
  54. {
  55. wxCHECK_MSG( Type() == aItem.Type(), *this,
  56. wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) +
  57. GetClass() );
  58. if( &aItem != this )
  59. {
  60. SCH_ITEM::operator=( aItem );
  61. SCH_BITMAP* bitmap = (SCH_BITMAP*) &aItem;
  62. delete m_image;
  63. m_image = new BITMAP_BASE( *bitmap->m_image );
  64. m_pos = bitmap->m_pos;
  65. }
  66. return *this;
  67. }
  68. bool SCH_BITMAP::ReadImageFile( const wxString& aFullFilename )
  69. {
  70. return m_image->ReadImageFile( aFullFilename );
  71. }
  72. bool SCH_BITMAP::Save( FILE* aFile ) const
  73. {
  74. if( fprintf( aFile, "$Bitmap\n" ) == EOF )
  75. return false;
  76. if( fprintf( aFile, "Pos %-4d %-4d\n", m_pos.x, m_pos.y ) == EOF )
  77. return false;
  78. if( fprintf( aFile, "Scale %f\n", m_image->GetScale() ) == EOF )
  79. return false;
  80. if( fprintf( aFile, "Data\n" ) == EOF )
  81. return false;
  82. if( !m_image->SaveData( aFile ) )
  83. return false;
  84. if( fprintf( aFile, "\nEndData\n" ) == EOF )
  85. return false;
  86. if( fprintf( aFile, "$EndBitmap\n" ) == EOF )
  87. return false;
  88. return true;
  89. }
  90. EDA_ITEM* SCH_BITMAP::Clone() const
  91. {
  92. return new SCH_BITMAP( *this );
  93. }
  94. void SCH_BITMAP::SwapData( SCH_ITEM* aItem )
  95. {
  96. wxCHECK_RET( aItem->Type() == SCH_BITMAP_T,
  97. wxString::Format( wxT( "SCH_BITMAP object cannot swap data with %s object." ),
  98. GetChars( aItem->GetClass() ) ) );
  99. SCH_BITMAP* item = (SCH_BITMAP*) aItem;
  100. std::swap( m_pos, item->m_pos );
  101. std::swap( m_image, item->m_image );
  102. }
  103. bool SCH_BITMAP::Load( LINE_READER& aLine, wxString& aErrorMsg )
  104. {
  105. char* line = aLine.Line();
  106. if( strncasecmp( line, "$Bitmap", 7 ) != 0 )
  107. {
  108. aErrorMsg.Printf( wxT( "Eeschema file bitmap image load error at line %d, aborted" ),
  109. aLine.LineNumber() );
  110. aErrorMsg << wxT( "\n" ) << FROM_UTF8( (char*) aLine );
  111. return false;
  112. }
  113. for( ; ; )
  114. {
  115. if( !aLine.ReadLine() )
  116. return false;
  117. line = aLine.Line();
  118. if( strncasecmp( line, "Pos", 3 ) == 0 )
  119. {
  120. sscanf( line + 3, "%d %d", &m_pos.x, &m_pos.y );
  121. continue;
  122. }
  123. if( strncasecmp( line, "Scale", 5 ) == 0 )
  124. {
  125. double scale = 1.0;
  126. sscanf( line + 5, "%lf", &scale );
  127. m_image->SetScale( scale );
  128. continue;
  129. }
  130. if( strncasecmp( line, "Data", 4 ) == 0 )
  131. {
  132. m_image->LoadData( aLine, aErrorMsg );
  133. }
  134. if( strncasecmp( line, "$EndBitmap", 4 ) == 0 )
  135. break;
  136. }
  137. return true;
  138. }
  139. const EDA_RECT SCH_BITMAP::GetBoundingBox() const
  140. {
  141. EDA_RECT rect = m_image->GetBoundingBox();
  142. rect.Move( m_pos );
  143. return rect;
  144. }
  145. void SCH_BITMAP::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
  146. GR_DRAWMODE aDrawMode, COLOR4D aColor )
  147. {
  148. wxPoint pos = m_pos + aOffset;
  149. if( aColor == COLOR4D::UNSPECIFIED ) // Use normal drawing function
  150. {
  151. // https://bugs.launchpad.net/kicad/+bug/1529163
  152. // "Moving images in eeschema on OS X uses
  153. // wrong position and shows image flipped"
  154. //
  155. // Original fix was to only GRSetDrawMode if aColor >= 0, but this made
  156. // moving SCH_BITMAP work poorly on other platforms.
  157. #ifndef __WXMAC__
  158. GRSetDrawMode( aDC, aDrawMode );
  159. #endif
  160. m_image->DrawBitmap( aPanel, aDC, pos );
  161. }
  162. else // draws bounding box only (used to move items)
  163. {
  164. GRSetDrawMode( aDC, aDrawMode );
  165. // To draw the rect, pos is the upper left corner position
  166. wxSize size = m_image->GetSize();
  167. pos.x -= size.x / 2;
  168. pos.y -= size.y / 2;
  169. GRRect( aPanel->GetClipBox(), aDC, pos.x, pos.y,
  170. pos.x + size.x, pos.y + size.y, 0, aColor );
  171. }
  172. }
  173. /* Function GetSize
  174. * returns the actual size (in user units, not in pixels) of the image
  175. */
  176. wxSize SCH_BITMAP::GetSize() const
  177. {
  178. return m_image->GetSize();
  179. }
  180. /*
  181. * Mirror image relative to a horizontal X axis )
  182. */
  183. void SCH_BITMAP::MirrorX( int aXaxis_position )
  184. {
  185. MIRROR( m_pos.y, aXaxis_position );
  186. m_image->Mirror( true );
  187. }
  188. /*
  189. * Mirror image relative to a vertical Y axis
  190. */
  191. void SCH_BITMAP::MirrorY( int aYaxis_position )
  192. {
  193. MIRROR( m_pos.x, aYaxis_position );
  194. m_image->Mirror( false );
  195. }
  196. void SCH_BITMAP::Rotate( wxPoint aPosition )
  197. {
  198. RotatePoint( &m_pos, aPosition, 900 );
  199. m_image->Rotate( false );
  200. }
  201. bool SCH_BITMAP::IsSelectStateChanged( const wxRect& aRect )
  202. {
  203. bool previousState = IsSelected();
  204. if( aRect.Contains( m_pos ) )
  205. SetFlags( SELECTED );
  206. else
  207. ClearFlags( SELECTED );
  208. return previousState != IsSelected();
  209. }
  210. #if defined(DEBUG)
  211. void SCH_BITMAP::Show( int nestLevel, std::ostream& os ) const
  212. {
  213. // XML output:
  214. wxString s = GetClass();
  215. NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << m_pos << "/>\n";
  216. }
  217. #endif
  218. bool SCH_BITMAP::HitTest( const wxPoint& aPosition, int aAccuracy ) const
  219. {
  220. EDA_RECT rect = GetBoundingBox();
  221. rect.Inflate( aAccuracy );
  222. return rect.Contains( aPosition );
  223. }
  224. bool SCH_BITMAP::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
  225. {
  226. EDA_RECT rect = aRect;
  227. rect.Inflate( aAccuracy );
  228. if( aContained )
  229. return rect.Contains( GetBoundingBox() );
  230. return rect.Intersects( GetBoundingBox() );
  231. }
  232. void SCH_BITMAP::Plot( PLOTTER* aPlotter )
  233. {
  234. m_image->PlotImage( aPlotter, m_pos, GetLayerColor( GetLayer() ), GetPenSize() );
  235. }
  236. BITMAP_DEF SCH_BITMAP::GetMenuImage() const
  237. {
  238. return image_xpm;
  239. }