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.

141 lines
3.8 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2021 Ola Rinta-Koski <gitlab@rinta-koski.net>
  5. * Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software: you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation, either version 3 of the License, or (at your
  10. * option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #include <vector>
  21. #include <font/glyph.h>
  22. #include <trigo.h>
  23. using namespace KIFONT;
  24. STROKE_GLYPH::STROKE_GLYPH( const STROKE_GLYPH& aGlyph )
  25. {
  26. for( const std::vector<VECTOR2D>& pointList : aGlyph )
  27. push_back( pointList );
  28. m_boundingBox = aGlyph.m_boundingBox;
  29. }
  30. void STROKE_GLYPH::AddPoint( const VECTOR2D& aPoint )
  31. {
  32. if( !m_penIsDown )
  33. {
  34. emplace_back();
  35. back().reserve( 16 ); // This handles all but 359 strokes (out of over 328,000)
  36. m_penIsDown = true;
  37. }
  38. back().push_back( aPoint );
  39. }
  40. void STROKE_GLYPH::RaisePen()
  41. {
  42. #if 0
  43. if( m_penIsDown )
  44. back().shrink_to_fit();
  45. #endif
  46. m_penIsDown = false;
  47. }
  48. void STROKE_GLYPH::Finalize()
  49. {
  50. // Shrinking the strokes saves a bit less than 512K of memory. It's not worth it for the
  51. // performance hit of doing more than 328,000 reallocs.
  52. #if 0
  53. if( !empty() && !back().empty() )
  54. back().shrink_to_fit();
  55. #endif
  56. }
  57. std::unique_ptr<GLYPH> STROKE_GLYPH::Transform( const VECTOR2D& aGlyphSize, const VECTOR2I& aOffset,
  58. double aTilt, const EDA_ANGLE& aAngle, bool aMirror,
  59. const VECTOR2I& aOrigin )
  60. {
  61. std::unique_ptr<STROKE_GLYPH> glyph = std::make_unique<STROKE_GLYPH>( *this );
  62. VECTOR2D end = glyph->m_boundingBox.GetEnd();
  63. end.x *= aGlyphSize.x;
  64. end.y *= aGlyphSize.y;
  65. if( aTilt )
  66. end.x -= end.y * aTilt;
  67. glyph->m_boundingBox.SetEnd( end );
  68. glyph->m_boundingBox.Offset( aOffset );
  69. for( std::vector<VECTOR2D>& pointList : *glyph.get() )
  70. {
  71. for( VECTOR2D& point : pointList )
  72. {
  73. point *= aGlyphSize;
  74. if( aTilt )
  75. point.x -= point.y * aTilt;
  76. point += aOffset;
  77. if( aMirror )
  78. point.x = aOrigin.x - ( point.x - aOrigin.x );
  79. if( !aAngle.IsZero() )
  80. RotatePoint( point, aOrigin, aAngle );
  81. }
  82. }
  83. return glyph;
  84. }
  85. BOX2D OUTLINE_GLYPH::BoundingBox()
  86. {
  87. BOX2I bbox = BBox();
  88. return BOX2D( bbox.GetOrigin(), bbox.GetSize() );
  89. }
  90. void OUTLINE_GLYPH::Triangulate( std::function<void( const VECTOR2I& aPt1,
  91. const VECTOR2I& aPt2,
  92. const VECTOR2I& aPt3 )> aCallback ) const
  93. {
  94. // Only call CacheTriangulation if it has never been done before. Otherwise we'll hash
  95. // the triangulation to see if it has been edited, and glyphs after creation are read-only.
  96. if( TriangulatedPolyCount() == 0 )
  97. const_cast<OUTLINE_GLYPH*>( this )->CacheTriangulation( false );
  98. for( unsigned int i = 0; i < TriangulatedPolyCount(); i++ )
  99. {
  100. const SHAPE_POLY_SET::TRIANGULATED_POLYGON* polygon = TriangulatedPolygon( i );
  101. for( size_t j = 0; j < polygon->GetTriangleCount(); j++ )
  102. {
  103. VECTOR2I a, b, c;
  104. polygon->GetTriangle( j, a, b, c );
  105. aCallback( a, b, c );
  106. }
  107. }
  108. }