 // 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 |
|
/*
* This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2012 Wayne Stambaugh <stambaughw@gmail.com> * Copyright The KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, you may find one here: * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
#include <gr_basic.h>
#include <plotters/plotter.h>
#include <trigo.h>
#include <math/util.h> // for KiROUND
#include <font/font.h>
#include <callback_gal.h>
int GetPenSizeForBold( int aTextSize ){ return KiROUND( aTextSize / 5.0 );}
int GetPenSizeForDemiBold( int aTextSize ){ return KiROUND( aTextSize / 6 );}
int GetPenSizeForBold( const wxSize& aTextSize ){ return GetPenSizeForBold( std::min( aTextSize.x, aTextSize.y ) );}
int GetPenSizeForDemiBold( const wxSize& aTextSize ){ return GetPenSizeForDemiBold( std::min( aTextSize.x, aTextSize.y ) );}
int GetPenSizeForNormal( int aTextSize ){ return KiROUND( aTextSize / 8.0 );}
int GetPenSizeForNormal( const wxSize& aTextSize ){ return GetPenSizeForNormal( std::min( aTextSize.x, aTextSize.y ) );}
int ClampTextPenSize( int aPenSize, int aSize, bool aStrict ){ double scale = aStrict ? 0.18 : 0.25; int maxWidth = KiROUND( (double) aSize * scale );
return std::min( aPenSize, maxWidth );}
float ClampTextPenSize( float aPenSize, int aSize, bool aStrict ){ double scale = aStrict ? 0.18 : 0.25; float maxWidth = (float) aSize * scale;
return std::min( aPenSize, maxWidth );}
int ClampTextPenSize( int aPenSize, const VECTOR2I& aSize, bool aStrict ){ int size = std::min( std::abs( aSize.x ), std::abs( aSize.y ) );
return ClampTextPenSize( aPenSize, size, aStrict );}
int GRTextWidth( const wxString& aText, KIFONT::FONT* aFont, const VECTOR2I& aSize, int aThickness, bool aBold, bool aItalic, const KIFONT::METRICS& aFontMetrics ){ if( !aFont ) aFont = KIFONT::FONT::GetFont();
return KiROUND( aFont->StringBoundaryLimits( aText, aSize, aThickness, aBold, aItalic, aFontMetrics ).x );}
void GRPrintText( wxDC* aDC, const VECTOR2I& aPos, const COLOR4D& aColor, const wxString& aText, const EDA_ANGLE& aOrient, const VECTOR2I& aSize, enum GR_TEXT_H_ALIGN_T aH_justify, enum GR_TEXT_V_ALIGN_T aV_justify, int aWidth, bool aItalic, bool aBold, KIFONT::FONT* aFont, const KIFONT::METRICS& aFontMetrics ){ KIGFX::GAL_DISPLAY_OPTIONS empty_opts; bool fill_mode = true;
if( !aFont ) aFont = KIFONT::FONT::GetFont();
if( aWidth == 0 ) // Use default values if aWidth == 0
{ if( aBold ) aWidth = GetPenSizeForBold( std::min( aSize.x, aSize.y ) ); else aWidth = GetPenSizeForNormal( std::min( aSize.x, aSize.y ) ); }
if( aWidth < 0 ) { aWidth = -aWidth; fill_mode = false; }
CALLBACK_GAL callback_gal( empty_opts, // Stroke callback
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 ) { if( fill_mode ) GRLine( aDC, aPt1, aPt2, aWidth, aColor ); else GRCSegm( aDC, aPt1, aPt2, aWidth, aColor ); }, // Polygon callback
[&]( const SHAPE_LINE_CHAIN& aPoly ) { GRClosedPoly( aDC, aPoly.PointCount(), aPoly.CPoints().data(), true, aColor ); } );
TEXT_ATTRIBUTES attributes; attributes.m_Angle = aOrient; attributes.m_StrokeWidth = aWidth; attributes.m_Italic = aItalic; attributes.m_Bold = aBold; attributes.m_Halign = aH_justify; attributes.m_Valign = aV_justify; attributes.m_Size = aSize;
aFont->Draw( &callback_gal, aText, aPos, attributes, aFontMetrics );}
|