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.

146 lines
4.9 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2015 CERN
  5. * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
  6. * @author Maciej Suminski <maciej.suminski@cern.ch>
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, you may find one here:
  20. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  21. * or you may search the http://www.gnu.org website for the version 2 license,
  22. * or you may write to the Free Software Foundation, Inc.,
  23. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  24. */
  25. #include <array>
  26. #include <eda_draw_frame.h>
  27. #include <gal/graphics_abstraction_layer.h>
  28. #include <geometry/geometry_utils.h>
  29. #include <origin_viewitem.h>
  30. using namespace KIGFX;
  31. ORIGIN_VIEWITEM::ORIGIN_VIEWITEM( const COLOR4D& aColor, MARKER_STYLE aStyle, int aSize, const VECTOR2D& aPosition ) :
  32. EDA_ITEM( nullptr, NOT_USED ), // this item is never added to a BOARD/SCHEMATIC so it needs no type
  33. m_position( aPosition ),
  34. m_size( aSize ),
  35. m_color( aColor ),
  36. m_style( aStyle ),
  37. m_drawAtZero( false )
  38. {
  39. }
  40. ORIGIN_VIEWITEM::ORIGIN_VIEWITEM( const VECTOR2D& aPosition, EDA_ITEM_FLAGS flags ) :
  41. EDA_ITEM( nullptr, NOT_USED ), // this item is never added to a BOARD/SCHEMATIC so it needs no type
  42. m_position( aPosition ),
  43. m_size( NOT_USED ),
  44. m_color( UNSPECIFIED_COLOR ),
  45. m_style( NO_GRAPHIC ),
  46. m_drawAtZero( false )
  47. {
  48. SetFlags( flags );
  49. }
  50. ORIGIN_VIEWITEM* ORIGIN_VIEWITEM::Clone() const
  51. {
  52. return new ORIGIN_VIEWITEM( m_color, m_style, m_size, m_position );
  53. }
  54. const BOX2I ORIGIN_VIEWITEM::ViewBBox() const
  55. {
  56. BOX2I bbox;
  57. bbox.SetMaximum();
  58. return bbox;
  59. }
  60. void ORIGIN_VIEWITEM::ViewDraw( int, VIEW* aView ) const
  61. {
  62. GAL* gal = aView->GetGAL();
  63. // Nothing to do if the target shouldn't be drawn at 0,0 and that's where the target is.
  64. if( !m_drawAtZero && ( m_position.x == 0 ) && ( m_position.y == 0 ) )
  65. return;
  66. gal->SetIsStroke( true );
  67. gal->SetIsFill( false );
  68. gal->SetLineWidth( 1 );
  69. gal->SetStrokeColor( m_color );
  70. VECTOR2D scaledSize = aView->ToWorld( VECTOR2D( m_size, m_size ), false );
  71. // Draw a circle around the marker's centre point if the style demands it
  72. if( ( m_style == CIRCLE_CROSS ) || ( m_style == CIRCLE_DOT ) || ( m_style == CIRCLE_X ) )
  73. gal->DrawCircle( m_position, fabs( scaledSize.x ) );
  74. switch( m_style )
  75. {
  76. case NO_GRAPHIC:
  77. break;
  78. case CROSS:
  79. case CIRCLE_CROSS:
  80. gal->DrawLine( m_position - VECTOR2D( scaledSize.x, 0 ),
  81. m_position + VECTOR2D( scaledSize.x, 0 ) );
  82. gal->DrawLine( m_position - VECTOR2D( 0, scaledSize.y ),
  83. m_position + VECTOR2D( 0, scaledSize.y ) );
  84. break;
  85. case DASH_LINE:
  86. {
  87. gal->DrawCircle( m_position, scaledSize.x / 4 );
  88. VECTOR2D start( m_position );
  89. VECTOR2D end( m_end );
  90. BOX2I clip( VECTOR2I( start ), VECTOR2I( end.x - start.x, end.y - start.y ) );
  91. clip.Normalize();
  92. double theta = atan2( end.y - start.y, end.x - start.x );
  93. std::array<double,2> strokes = { scaledSize.x, scaledSize.x / 2 };
  94. for( size_t i = 0; i < 10000; ++i )
  95. {
  96. VECTOR2D next( start.x + strokes[ i % 2 ] * cos( theta ),
  97. start.y + strokes[ i % 2 ] * sin( theta ) );
  98. // Drawing each segment can be done rounded to ints.
  99. VECTOR2I segStart( KiROUND( start.x ), KiROUND( start.y ) );
  100. VECTOR2I segEnd( KiROUND( next.x ), KiROUND( next.y ) );
  101. if( ClipLine( &clip, segStart.x, segStart.y, segEnd.x, segEnd.y ) )
  102. break;
  103. else if( i % 2 == 0 )
  104. gal->DrawLine( segStart, segEnd );
  105. start = next;
  106. }
  107. gal->DrawCircle( m_end, scaledSize.x / 4 );
  108. break;
  109. }
  110. case X:
  111. case CIRCLE_X:
  112. gal->DrawLine( m_position - scaledSize, m_position + scaledSize );
  113. scaledSize.y = -scaledSize.y;
  114. gal->DrawLine( m_position - scaledSize, m_position + scaledSize );
  115. break;
  116. case DOT:
  117. case CIRCLE_DOT:
  118. gal->DrawCircle( m_position, scaledSize.x / 4 );
  119. break;
  120. }
  121. }