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.

286 lines
8.8 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  5. * Copyright (C) 2012 KiCad Developers, see CHANGELOG.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. #include <common.h>
  25. #include <page_info.h>
  26. #include <macros.h>
  27. // late arriving wxPAPER_A0, wxPAPER_A1
  28. #if wxABI_VERSION >= 20999
  29. #define PAPER_A0 wxPAPER_A0
  30. #define PAPER_A1 wxPAPER_A1
  31. #else
  32. #define PAPER_A0 wxPAPER_A2
  33. #define PAPER_A1 wxPAPER_A2
  34. #endif
  35. // Standard paper sizes nicknames.
  36. const wxChar PAGE_INFO::A5[] = wxT( "A5" );
  37. const wxChar PAGE_INFO::A4[] = wxT( "A4" );
  38. const wxChar PAGE_INFO::A3[] = wxT( "A3" );
  39. const wxChar PAGE_INFO::A2[] = wxT( "A2" );
  40. const wxChar PAGE_INFO::A1[] = wxT( "A1" );
  41. const wxChar PAGE_INFO::A0[] = wxT( "A0" );
  42. const wxChar PAGE_INFO::A[] = wxT( "A" );
  43. const wxChar PAGE_INFO::B[] = wxT( "B" );
  44. const wxChar PAGE_INFO::C[] = wxT( "C" );
  45. const wxChar PAGE_INFO::D[] = wxT( "D" );
  46. const wxChar PAGE_INFO::E[] = wxT( "E" );
  47. const wxChar PAGE_INFO::GERBER[] = wxT( "GERBER" );
  48. const wxChar PAGE_INFO::USLetter[] = wxT( "USLetter" );
  49. const wxChar PAGE_INFO::USLegal[] = wxT( "USLegal" );
  50. const wxChar PAGE_INFO::USLedger[] = wxT( "USLedger" );
  51. const wxChar PAGE_INFO::Custom[] = wxT( "User" );
  52. // Standard page sizes in mils, all constants
  53. // see: https://lists.launchpad.net/kicad-developers/msg07389.html
  54. // also see: wx/defs.h
  55. // local readability macro for millimeter wxSize
  56. #define MMsize( x, y ) wxSize( Mm2mils( x ), Mm2mils( y ) )
  57. // All MUST be defined as landscape.
  58. const PAGE_INFO PAGE_INFO::pageA5( MMsize( 210, 148 ), wxT( "A5" ), wxPAPER_A5 );
  59. const PAGE_INFO PAGE_INFO::pageA4( MMsize( 297, 210 ), wxT( "A4" ), wxPAPER_A4 );
  60. const PAGE_INFO PAGE_INFO::pageA3( MMsize( 420, 297 ), wxT( "A3" ), wxPAPER_A3 );
  61. const PAGE_INFO PAGE_INFO::pageA2( MMsize( 594, 420 ), wxT( "A2" ), wxPAPER_A2 );
  62. const PAGE_INFO PAGE_INFO::pageA1( MMsize( 841, 594 ), wxT( "A1" ), PAPER_A1 );
  63. const PAGE_INFO PAGE_INFO::pageA0( MMsize( 1189, 841 ), wxT( "A0" ), PAPER_A0 );
  64. const PAGE_INFO PAGE_INFO::pageA( wxSize( 11000, 8500 ), wxT( "A" ), wxPAPER_LETTER );
  65. const PAGE_INFO PAGE_INFO::pageB( wxSize( 17000, 11000 ), wxT( "B" ), wxPAPER_TABLOID );
  66. const PAGE_INFO PAGE_INFO::pageC( wxSize( 22000, 17000 ), wxT( "C" ), wxPAPER_CSHEET );
  67. const PAGE_INFO PAGE_INFO::pageD( wxSize( 34000, 22000 ), wxT( "D" ), wxPAPER_DSHEET );
  68. const PAGE_INFO PAGE_INFO::pageE( wxSize( 44000, 34000 ), wxT( "E" ), wxPAPER_ESHEET );
  69. const PAGE_INFO PAGE_INFO::pageGERBER( wxSize( 32000, 32000 ), wxT( "GERBER" ), wxPAPER_NONE );
  70. const PAGE_INFO PAGE_INFO::pageUser( wxSize( 17000, 11000 ), Custom, wxPAPER_NONE );
  71. // US paper sizes
  72. const PAGE_INFO PAGE_INFO::pageUSLetter( wxSize( 11000, 8500 ), wxT( "USLetter" ), wxPAPER_LETTER );
  73. const PAGE_INFO PAGE_INFO::pageUSLegal( wxSize( 14000, 8500 ), wxT( "USLegal" ), wxPAPER_LEGAL );
  74. const PAGE_INFO PAGE_INFO::pageUSLedger( wxSize( 17000, 11000 ), wxT( "USLedger" ), wxPAPER_TABLOID );
  75. // Custom paper size for next instantiation of type "User"
  76. int PAGE_INFO::s_user_width = 17000;
  77. int PAGE_INFO::s_user_height = 11000;
  78. inline void PAGE_INFO::updatePortrait()
  79. {
  80. // update m_portrait based on orientation of m_size.x and m_size.y
  81. m_portrait = ( m_size.y > m_size.x );
  82. }
  83. PAGE_INFO::PAGE_INFO( const wxSize& aSizeMils, const wxString& aType, wxPaperSize aPaperId ) :
  84. m_type( aType ), m_size( aSizeMils ), m_paper_id( aPaperId )
  85. {
  86. updatePortrait();
  87. // This constructor is protected, and only used by const PAGE_INFO's known
  88. // only to class implementation, so no further changes to "this" object are
  89. // expected.
  90. }
  91. PAGE_INFO::PAGE_INFO( const wxString& aType, bool aIsPortrait )
  92. {
  93. SetType( aType, aIsPortrait );
  94. }
  95. bool PAGE_INFO::SetType( const wxString& aType, bool aIsPortrait )
  96. {
  97. bool rc = true;
  98. // all are landscape initially
  99. if( aType == pageA5.GetType() )
  100. *this = pageA5;
  101. else if( aType == pageA4.GetType() )
  102. *this = pageA4;
  103. else if( aType == pageA3.GetType() )
  104. *this = pageA3;
  105. else if( aType == pageA2.GetType() )
  106. *this = pageA2;
  107. else if( aType == pageA1.GetType() )
  108. *this = pageA1;
  109. else if( aType == pageA0.GetType() )
  110. *this = pageA0;
  111. else if( aType == pageA.GetType() )
  112. *this = pageA;
  113. else if( aType == pageB.GetType() )
  114. *this = pageB;
  115. else if( aType == pageC.GetType() )
  116. *this = pageC;
  117. else if( aType == pageD.GetType() )
  118. *this = pageD;
  119. else if( aType == pageE.GetType() )
  120. *this = pageE;
  121. else if( aType == pageGERBER.GetType() )
  122. *this = pageGERBER;
  123. else if( aType == pageUSLetter.GetType() )
  124. *this = pageUSLetter;
  125. else if( aType == pageUSLegal.GetType() )
  126. *this = pageUSLegal;
  127. else if( aType == pageUSLedger.GetType() )
  128. *this = pageUSLedger;
  129. else if( aType == pageUser.GetType() )
  130. {
  131. // pageUser is const, and may not and does not hold the custom size,
  132. // so customize *this later
  133. *this = pageUser;
  134. // customize:
  135. m_size.x = s_user_width;
  136. m_size.y = s_user_height;
  137. updatePortrait();
  138. }
  139. else
  140. rc = false;
  141. if( aIsPortrait )
  142. {
  143. // all private PAGE_INFOs are landscape, must swap x and y
  144. m_size = wxSize( m_size.y, m_size.x );
  145. updatePortrait();
  146. }
  147. return rc;
  148. }
  149. bool PAGE_INFO::IsCustom() const
  150. {
  151. return m_type == Custom;
  152. }
  153. void PAGE_INFO::SetPortrait( bool aIsPortrait )
  154. {
  155. if( m_portrait != aIsPortrait )
  156. {
  157. // swap x and y in m_size
  158. m_size = wxSize( m_size.y, m_size.x );
  159. m_portrait = aIsPortrait;
  160. // margins are not touched, do that if you want
  161. }
  162. }
  163. static int clampWidth( int aWidthInMils )
  164. {
  165. /* was giving EESCHEMA single component SVG plotter grief
  166. However a minimal test is made to avoid values that crashes Kicad
  167. if( aWidthInMils < 4000 ) // 4" is about a baseball card
  168. aWidthInMils = 4000;
  169. else if( aWidthInMils > 44000 ) //44" is plotter size
  170. aWidthInMils = 44000;
  171. */
  172. if( aWidthInMils < 10 )
  173. aWidthInMils = 10;
  174. return aWidthInMils;
  175. }
  176. static int clampHeight( int aHeightInMils )
  177. {
  178. /* was giving EESCHEMA single component SVG plotter grief
  179. clamping is best done at the UI, i.e. dialog, levels
  180. However a minimal test is made to avoid values that crashes Kicad
  181. if( aHeightInMils < 4000 )
  182. aHeightInMils = 4000;
  183. else if( aHeightInMils > 44000 )
  184. aHeightInMils = 44000;
  185. */
  186. if( aHeightInMils < 10 )
  187. aHeightInMils = 10;
  188. return aHeightInMils;
  189. }
  190. void PAGE_INFO::SetCustomWidthMils( int aWidthInMils )
  191. {
  192. s_user_width = clampWidth( aWidthInMils );
  193. }
  194. void PAGE_INFO::SetCustomHeightMils( int aHeightInMils )
  195. {
  196. s_user_height = clampHeight( aHeightInMils );
  197. }
  198. void PAGE_INFO::SetWidthMils( int aWidthInMils )
  199. {
  200. if( m_size.x != aWidthInMils )
  201. {
  202. m_size.x = clampWidth( aWidthInMils );
  203. m_type = Custom;
  204. m_paper_id = wxPAPER_NONE;
  205. updatePortrait();
  206. }
  207. }
  208. void PAGE_INFO::SetHeightMils( int aHeightInMils )
  209. {
  210. if( m_size.y != aHeightInMils )
  211. {
  212. m_size.y = clampHeight( aHeightInMils );
  213. m_type = Custom;
  214. m_paper_id = wxPAPER_NONE;
  215. updatePortrait();
  216. }
  217. }
  218. void PAGE_INFO::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
  219. {
  220. aFormatter->Print( aNestLevel, "(paper %s", aFormatter->Quotew( GetType() ).c_str() );
  221. // The page dimensions are only required for user defined page sizes.
  222. // Internally, the page size is in mils
  223. if( GetType() == PAGE_INFO::Custom )
  224. aFormatter->Print( 0, " %g %g",
  225. GetWidthMils() * 25.4 / 1000.0,
  226. GetHeightMils() * 25.4 / 1000.0 );
  227. if( !IsCustom() && IsPortrait() )
  228. aFormatter->Print( 0, " portrait" );
  229. aFormatter->Print( 0, ")\n" );
  230. }