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.

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