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.

294 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-2023 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. * @file sch_bitmap.cpp
  26. */
  27. #include <sch_draw_panel.h>
  28. #include <plotters/plotter.h>
  29. #include <settings/color_settings.h>
  30. #include <bitmaps.h>
  31. #include <base_units.h>
  32. #include <common.h>
  33. #include <eda_draw_frame.h>
  34. #include <core/mirror.h>
  35. #include <sch_bitmap.h>
  36. #include <trigo.h>
  37. #include <wx/mstream.h>
  38. SCH_BITMAP::SCH_BITMAP( const VECTOR2I& pos ) :
  39. SCH_ITEM( nullptr, 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_bitmapBase = new BITMAP_BASE();
  45. m_bitmapBase->SetPixelSizeIu( (double) schIUScale.MilsToIU( 1000 ) / m_bitmapBase->GetPPI() );
  46. }
  47. SCH_BITMAP::SCH_BITMAP( const SCH_BITMAP& aSchBitmap ) :
  48. SCH_ITEM( aSchBitmap )
  49. {
  50. m_pos = aSchBitmap.m_pos;
  51. m_layer = aSchBitmap.m_layer;
  52. m_bitmapBase = new BITMAP_BASE( *aSchBitmap.m_bitmapBase );
  53. }
  54. SCH_BITMAP& SCH_BITMAP::operator=( const SCH_ITEM& aItem )
  55. {
  56. wxCHECK_MSG( Type() == aItem.Type(), *this,
  57. wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) +
  58. GetClass() );
  59. if( &aItem != this )
  60. {
  61. SCH_ITEM::operator=( aItem );
  62. SCH_BITMAP* bitmap = (SCH_BITMAP*) &aItem;
  63. delete m_bitmapBase;
  64. m_bitmapBase = new BITMAP_BASE( *bitmap->m_bitmapBase );
  65. m_pos = bitmap->m_pos;
  66. }
  67. return *this;
  68. }
  69. bool SCH_BITMAP::ReadImageFile( const wxString& aFullFilename )
  70. {
  71. if( m_bitmapBase->ReadImageFile( aFullFilename ) )
  72. {
  73. m_bitmapBase->SetPixelSizeIu( (double) schIUScale.MilsToIU( 1000 ) / m_bitmapBase->GetPPI() );
  74. return true;
  75. }
  76. return false;
  77. }
  78. bool SCH_BITMAP::ReadImageFile( wxMemoryBuffer& aBuffer )
  79. {
  80. if( m_bitmapBase->ReadImageFile( aBuffer ) )
  81. {
  82. m_bitmapBase->SetPixelSizeIu( (double) schIUScale.MilsToIU( 1000 ) / m_bitmapBase->GetPPI() );
  83. return true;
  84. }
  85. return false;
  86. }
  87. EDA_ITEM* SCH_BITMAP::Clone() const
  88. {
  89. return new SCH_BITMAP( *this );
  90. }
  91. void SCH_BITMAP::SwapData( SCH_ITEM* aItem )
  92. {
  93. SCH_ITEM::SwapFlags( aItem );
  94. wxCHECK_RET( aItem->Type() == SCH_BITMAP_T,
  95. wxString::Format( wxT( "SCH_BITMAP object cannot swap data with %s object." ),
  96. aItem->GetClass() ) );
  97. SCH_BITMAP* item = (SCH_BITMAP*) aItem;
  98. std::swap( m_pos, item->m_pos );
  99. std::swap( m_bitmapBase, item->m_bitmapBase );
  100. }
  101. const BOX2I SCH_BITMAP::GetBoundingBox() const
  102. {
  103. BOX2I bbox = m_bitmapBase->GetBoundingBox();
  104. bbox.Move( m_pos );
  105. return bbox;
  106. }
  107. void SCH_BITMAP::Print( const SCH_RENDER_SETTINGS* aSettings, int aUnit, int aBodyStyle,
  108. const VECTOR2I& aOffset, bool aForceNoFill, bool aDimmed )
  109. {
  110. VECTOR2I pos = m_pos + aOffset;
  111. m_bitmapBase->DrawBitmap( aSettings->GetPrintDC(), pos, aSettings->GetBackgroundColor() );
  112. }
  113. VECTOR2I SCH_BITMAP::GetSize() const
  114. {
  115. return m_bitmapBase->GetSize();
  116. }
  117. void SCH_BITMAP::MirrorVertically( int aCenter )
  118. {
  119. MIRROR( m_pos.y, aCenter );
  120. m_bitmapBase->Mirror( true );
  121. }
  122. void SCH_BITMAP::MirrorHorizontally( int aCenter )
  123. {
  124. MIRROR( m_pos.x, aCenter );
  125. m_bitmapBase->Mirror( false );
  126. }
  127. void SCH_BITMAP::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
  128. {
  129. RotatePoint( m_pos, aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
  130. m_bitmapBase->Rotate( aRotateCCW );
  131. }
  132. #if defined(DEBUG)
  133. void SCH_BITMAP::Show( int nestLevel, std::ostream& os ) const
  134. {
  135. // XML output:
  136. wxString s = GetClass();
  137. NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << m_pos << "/>\n";
  138. }
  139. #endif
  140. bool SCH_BITMAP::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
  141. {
  142. BOX2I rect = GetBoundingBox();
  143. rect.Inflate( aAccuracy );
  144. return rect.Contains( aPosition );
  145. }
  146. bool SCH_BITMAP::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
  147. {
  148. BOX2I rect = aRect;
  149. rect.Inflate( aAccuracy );
  150. if( aContained )
  151. return rect.Contains( GetBoundingBox() );
  152. return rect.Intersects( GetBoundingBox() );
  153. }
  154. void SCH_BITMAP::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts,
  155. int aUnit, int aBodyStyle, const VECTOR2I& aOffset, bool aDimmed )
  156. {
  157. if( aBackground )
  158. {
  159. m_bitmapBase->PlotImage( aPlotter, m_pos,
  160. aPlotter->RenderSettings()->GetLayerColor( GetLayer() ),
  161. aPlotter->RenderSettings()->GetDefaultPenWidth() );
  162. }
  163. }
  164. BITMAPS SCH_BITMAP::GetMenuImage() const
  165. {
  166. return BITMAPS::image;
  167. }
  168. void SCH_BITMAP::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
  169. {
  170. aList.emplace_back( _( "Bitmap" ), wxEmptyString );
  171. aList.emplace_back( _( "PPI" ), wxString::Format( wxT( "%d "), GetImage()->GetPPI() ) );
  172. aList.emplace_back( _( "Scale" ), wxString::Format( wxT( "%f "), GetImageScale() ) );
  173. aList.emplace_back( _( "Width" ), aFrame->MessageTextFromValue( GetSize().x ) );
  174. aList.emplace_back( _( "Height" ), aFrame->MessageTextFromValue( GetSize().y ) );
  175. }
  176. void SCH_BITMAP::ViewGetLayers( int aLayers[], int& aCount ) const
  177. {
  178. aCount = 2;
  179. aLayers[0] = LAYER_DRAW_BITMAPS;
  180. aLayers[1] = LAYER_SELECTION_SHADOWS;
  181. }
  182. static struct SCH_BITMAP_DESC
  183. {
  184. SCH_BITMAP_DESC()
  185. {
  186. PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
  187. REGISTER_TYPE( SCH_BITMAP );
  188. propMgr.InheritsAfter( TYPE_HASH( SCH_BITMAP ), TYPE_HASH( SCH_ITEM ) );
  189. }
  190. } _SCH_BITMAP_DESC;
  191. bool SCH_BITMAP::operator==( const SCH_ITEM& aItem ) const
  192. {
  193. if( Type() != aItem.Type() )
  194. return false;
  195. const SCH_BITMAP* bitmap = static_cast<const SCH_BITMAP*>( &aItem );
  196. if( GetPosition() != bitmap->GetPosition() )
  197. return false;
  198. if( GetSize() != bitmap->GetSize() )
  199. return false;
  200. if( GetImage() != bitmap->GetImage() )
  201. return false;
  202. return true;
  203. }
  204. double SCH_BITMAP::Similarity( const SCH_ITEM& aItem ) const
  205. {
  206. if( Type() != aItem.Type() )
  207. return 0.0;
  208. if( m_Uuid == aItem.m_Uuid )
  209. return 1.0;
  210. const SCH_BITMAP* bitmap = static_cast<const SCH_BITMAP*>( &aItem );
  211. if( GetImage() != bitmap->GetImage() )
  212. return 0.0;
  213. // If it is the same image but a different UUID and a different size,
  214. // then it _might be different_.
  215. if( GetSize() != bitmap->GetSize() )
  216. return 0.5;
  217. return 1.0;
  218. }