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.

190 lines
6.2 KiB

// Dick Hollenbeck's KiROUND R&D // This provides better project control over rounding to int from double // than wxRound() did. This scheme provides better logging in Debug builds // and it provides for compile time calculation of constants. #include <stdio.h> #include <assert.h> #include <limits.h> //-----<KiROUND KIT>------------------------------------------------------------ /** * KiROUND * rounds a floating point number to an int using * "round halfway cases away from zero". * In Debug build an assert fires if will not fit into an int. */ #if defined( DEBUG ) // DEBUG: a macro to capture line and file, then calls this inline static inline int KiRound( double v, int line, const char* filename ) { v = v < 0 ? v - 0.5 : v + 0.5; if( v > INT_MAX + 0.5 ) { printf( "%s: in file %s on line %d, val: %.16g too ' > 0 ' for int\n", __FUNCTION__, filename, line, v ); } else if( v < INT_MIN - 0.5 ) { printf( "%s: in file %s on line %d, val: %.16g too ' < 0 ' for int\n", __FUNCTION__, filename, line, v ); } return int( v ); } #define KiROUND( v ) KiRound( v, __LINE__, __FILE__ ) #else // RELEASE: a macro so compile can pre-compute constants. #define KiROUND( v ) int( (v) < 0 ? (v) - 0.5 : (v) + 0.5 ) #endif //-----</KiROUND KIT>----------------------------------------------------------- // Only a macro is compile time calculated, an inline function causes a static constructor // in a situation like this. // Therefore the Release build is best done with a MACRO not an inline function. int Computed = KiROUND( 14.3 * 8 ); int main( int argc, char** argv ) { for( double d = double(INT_MAX)-1; d < double(INT_MAX)+8; d += 2.0 ) { int i = KiROUND( d ); printf( "t: %d %.16g\n", i, d ); } return 0; }
14 years ago
18 years ago
18 years ago
18 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
  5. * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  6. * Copyright (C) 2012 Wayne Stambaugh <stambaughw@gmail.com>
  7. * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version 2
  12. * of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, you may find one here:
  21. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  22. * or you may search the http://www.gnu.org website for the version 2 license,
  23. * or you may write to the Free Software Foundation, Inc.,
  24. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  25. */
  26. #include <gr_basic.h>
  27. #include <plotters/plotter.h>
  28. #include <trigo.h>
  29. #include <math/util.h> // for KiROUND
  30. #include <font/font.h>
  31. #include <callback_gal.h>
  32. /**
  33. * @param aTextSize is the char size (height or width).
  34. * @return the "best" value for a pen size to draw/plot a bold text.
  35. */
  36. int GetPenSizeForBold( int aTextSize )
  37. {
  38. return KiROUND( aTextSize / 5.0 );
  39. }
  40. int GetPenSizeForDemiBold( int aTextSize )
  41. {
  42. return KiROUND( aTextSize / 6 );
  43. }
  44. int GetPenSizeForBold( const wxSize& aTextSize )
  45. {
  46. return GetPenSizeForBold( std::min( aTextSize.x, aTextSize.y ) );
  47. }
  48. int GetPenSizeForDemiBold( const wxSize& aTextSize )
  49. {
  50. return GetPenSizeForDemiBold( std::min( aTextSize.x, aTextSize.y ) );
  51. }
  52. int GetPenSizeForNormal( int aTextSize )
  53. {
  54. return KiROUND( aTextSize / 8.0 );
  55. }
  56. int GetPenSizeForNormal( const wxSize& aTextSize )
  57. {
  58. return GetPenSizeForNormal( std::min( aTextSize.x, aTextSize.y ) );
  59. }
  60. /**
  61. * Pen width should not allow characters to become cluttered up in their own fatness. Normal
  62. * text is normally around 15% the fontsize, and bold text around 20%. So we set a hard limit
  63. * at 25%, and a secondary limit for non-decorative text that must be readable at small sizes
  64. * at 18%.
  65. *
  66. * @param aPenSize is the pen size to clamp.
  67. * @param aSize is the character size (height or width).
  68. * @param aBold use true if text accept bold pen size.
  69. * @return the max pen size allowed.
  70. */
  71. int Clamp_Text_PenSize( int aPenSize, int aSize, bool aStrict )
  72. {
  73. double scale = aStrict ? 0.18 : 0.25;
  74. int maxWidth = KiROUND( (double) aSize * scale );
  75. return std::min( aPenSize, maxWidth );
  76. }
  77. float Clamp_Text_PenSize( float aPenSize, int aSize, bool aStrict )
  78. {
  79. double scale = aStrict ? 0.18 : 0.25;
  80. float maxWidth = (float) aSize * scale;
  81. return std::min( aPenSize, maxWidth );
  82. }
  83. int Clamp_Text_PenSize( int aPenSize, const VECTOR2I& aSize, bool aStrict )
  84. {
  85. int size = std::min( std::abs( aSize.x ), std::abs( aSize.y ) );
  86. return Clamp_Text_PenSize( aPenSize, size, aStrict );
  87. }
  88. int GRTextWidth( const wxString& aText, KIFONT::FONT* aFont, const VECTOR2I& aSize,
  89. int aThickness, bool aBold, bool aItalic, const KIFONT::METRICS& aFontMetrics )
  90. {
  91. if( !aFont )
  92. aFont = KIFONT::FONT::GetFont();
  93. return KiROUND( aFont->StringBoundaryLimits( aText, aSize, aThickness, aBold, aItalic,
  94. aFontMetrics ).x );
  95. }
  96. /**
  97. * Print a graphic text through wxDC.
  98. *
  99. * @param aDC is the current Device Context.
  100. * @param aPos is the text position (according to h_justify, v_justify).
  101. * @param aColor is the text color.
  102. * @param aText is the text to draw.
  103. * @param aOrient is the angle.
  104. * @param aSize is the text size (size.x or size.y can be < 0 for mirrored texts).
  105. * @param aH_justify is the horizontal justification (Left, center, right).
  106. * @param aV_justify is the vertical justification (bottom, center, top).
  107. * @param aWidth is the line width (pen width) (use default width if aWidth = 0).
  108. * if width < 0 : draw segments in sketch mode, width = abs(width)
  109. * Use a value min(aSize.x, aSize.y) / 5 for a bold text.
  110. * @param aItalic is the true to simulate an italic font.
  111. * @param aBold use true to use a bold font. Useful only with default width value (aWidth = 0).
  112. * @param aFont is the font to use, or nullptr for the KiCad stroke font
  113. */
  114. void GRPrintText( wxDC* aDC, const VECTOR2I& aPos, const COLOR4D& aColor, const wxString& aText,
  115. const EDA_ANGLE& aOrient, const VECTOR2I& aSize,
  116. enum GR_TEXT_H_ALIGN_T aH_justify, enum GR_TEXT_V_ALIGN_T aV_justify,
  117. int aWidth, bool aItalic, bool aBold, KIFONT::FONT* aFont,
  118. const KIFONT::METRICS& aFontMetrics )
  119. {
  120. KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
  121. bool fill_mode = true;
  122. if( !aFont )
  123. aFont = KIFONT::FONT::GetFont();
  124. if( aWidth == 0 && aBold ) // Use default values if aWidth == 0
  125. aWidth = GetPenSizeForBold( std::min( aSize.x, aSize.y ) );
  126. if( aWidth < 0 )
  127. {
  128. aWidth = -aWidth;
  129. fill_mode = false;
  130. }
  131. CALLBACK_GAL callback_gal( empty_opts,
  132. // Stroke callback
  133. [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
  134. {
  135. if( fill_mode )
  136. GRLine( aDC, aPt1, aPt2, aWidth, aColor );
  137. else
  138. GRCSegm( aDC, aPt1, aPt2, aWidth, aColor );
  139. },
  140. // Polygon callback
  141. [&]( const SHAPE_LINE_CHAIN& aPoly )
  142. {
  143. GRClosedPoly( aDC, aPoly.PointCount(), aPoly.CPoints().data(), true, aColor );
  144. } );
  145. TEXT_ATTRIBUTES attributes;
  146. attributes.m_Angle = aOrient;
  147. attributes.m_StrokeWidth = aWidth;
  148. attributes.m_Italic = aItalic;
  149. attributes.m_Bold = aBold;
  150. attributes.m_Halign = aH_justify;
  151. attributes.m_Valign = aV_justify;
  152. attributes.m_Size = aSize;
  153. aFont->Draw( &callback_gal, aText, aPos, attributes, aFontMetrics );
  154. }