void STROKE_FONT::Draw( const UTF8& aText, const VECTOR2D& aPosition, double aRotationAngle ) { // Context needs to be saved before any transformations m_gal->Save(); m_gal->Translate( aPosition ); m_gal->Rotate( -aRotationAngle ); // Single line height int lineHeight = getInterline(); // The overall height of all lines of text double textBlockHeight = lineHeight * ( linesCount( aText ) - 1 ); switch( m_verticalJustify ) { case GR_TEXT_VJUSTIFY_CENTER: m_gal->Translate( VECTOR2D( 0, -textBlockHeight / 2.0 ) ); break; case GR_TEXT_VJUSTIFY_BOTTOM: m_gal->Translate( VECTOR2D( 0, -textBlockHeight ) ); break; case GR_TEXT_VJUSTIFY_TOP: break; default: break; } m_gal->SetIsStroke( true ); m_gal->SetIsFill( false ); if( m_bold ) m_gal->SetLineWidth( m_gal->GetLineWidth() * BOLD_FACTOR ); // Split multiline strings into separate ones and draw them line by line size_t begin = 0; size_t newlinePos = aText.find( '\n' ); while( newlinePos != aText.npos ) { size_t length = newlinePos - begin; drawSingleLineText( aText.substr( begin, length ) ); m_gal->Translate( VECTOR2D( 0.0, lineHeight ) ); begin = newlinePos + 1; newlinePos = aText.find( '\n', begin ); } // Draw the last (or the only one) line if( !aText.empty() ) drawSingleLineText( aText.substr( begin ) ); m_gal->Restore(); }
int FPID::Parse( const UTF8& aId ) { clear(); const char* buffer = aId.c_str(); const char* rev = EndsWithRev( buffer, buffer+aId.length(), '/' ); size_t revNdx; size_t partNdx; int offset; //=====<revision>========================================= // in a FPID like discret:R3/rev4 if( rev ) { revNdx = rev - buffer; // no need to check revision, EndsWithRev did that. revision = aId.substr( revNdx ); --revNdx; // back up to omit the '/' which precedes the rev } else { revNdx = aId.size(); } //=====<nickname>========================================== if( ( partNdx = aId.find( ':' ) ) != aId.npos ) { offset = SetLibNickname( aId.substr( 0, partNdx ) ); if( offset > -1 ) { return offset; } ++partNdx; // skip ':' } else { partNdx = 0; } //=====<footprint name>==================================== if( partNdx >= revNdx ) return partNdx; // Error: no footprint name. // Be sure the footprint name is valid. // Some chars can be found in board file (in old board files // or converted files from an other EDA tool std::string fpname = aId.substr( partNdx, revNdx-partNdx ); ReplaceIllegalFileNameChars( &fpname, '_' ); SetFootprintName( UTF8( fpname ) ); return -1; }
int FPID::Parse( const UTF8& aId ) { clear(); size_t cnt = aId.length() + 1; char tmp[cnt]; // C string for speed std::strcpy( tmp, aId.c_str() ); const char* rev = EndsWithRev( tmp, tmp+aId.length(), '/' ); size_t revNdx; size_t partNdx; int offset; //=====<revision>========================================= if( rev ) { revNdx = rev - aId.c_str(); // no need to check revision, EndsWithRev did that. revision = aId.substr( revNdx ); --revNdx; // back up to omit the '/' which precedes the rev } else { revNdx = aId.size(); } //=====<nickname>========================================== if( ( partNdx = aId.find( ':' ) ) != aId.npos ) { offset = SetLibNickname( aId.substr( 0, partNdx ) ); if( offset > -1 ) { return offset; } ++partNdx; // skip ':' } else { partNdx = 0; } //=====<footprint name>==================================== if( partNdx >= revNdx ) return partNdx; SetFootprintName( aId.substr( partNdx, revNdx ) ); return -1; }
int FPID::SetFootprintName( const UTF8& aFootprintName ) { int separation = int( aFootprintName.find_first_of( "/" ) ); if( separation != -1 ) { nickname = aFootprintName.substr( separation+1 ); return separation + (int) nickname.size() + 1; } else { footprint = aFootprintName; } return -1; }
int FPID::SetFootprintName( const UTF8& aFootprintName ) { int separation = int( aFootprintName.find_first_of( "/" ) ); if( separation != -1 ) { footprint = aFootprintName.substr( 0, separation-1 ); return separation; } else { footprint = aFootprintName; } return -1; }
int LIB_ID::SetLibItemName( const UTF8& aLibItemName, bool aTestForRev ) { int separation = int( aLibItemName.find_first_of( "/" ) ); if( aTestForRev && separation != -1 ) { item_name = aLibItemName.substr( 0, separation-1 ); return separation; } else { item_name = aLibItemName; } return -1; }
void STROKE_FONT::Draw( const UTF8& aText, const VECTOR2D& aPosition, double aRotationAngle ) { if( aText.empty() ) return; // Context needs to be saved before any transformations m_gal->Save(); m_gal->Translate( aPosition ); m_gal->Rotate( -aRotationAngle ); // Single line height int lineHeight = getInterline( ); int lineCount = linesCount( aText ); const VECTOR2D& glyphSize = m_gal->GetGlyphSize(); // align the 1st line of text switch( m_gal->GetVerticalJustify() ) { case GR_TEXT_VJUSTIFY_TOP: m_gal->Translate( VECTOR2D( 0, glyphSize.y ) ); break; case GR_TEXT_VJUSTIFY_CENTER: m_gal->Translate( VECTOR2D( 0, glyphSize.y / 2.0 ) ); break; case GR_TEXT_VJUSTIFY_BOTTOM: break; default: break; } if( lineCount > 1 ) { switch( m_gal->GetVerticalJustify() ) { case GR_TEXT_VJUSTIFY_TOP: break; case GR_TEXT_VJUSTIFY_CENTER: m_gal->Translate( VECTOR2D(0, -( lineCount - 1 ) * lineHeight / 2) ); break; case GR_TEXT_VJUSTIFY_BOTTOM: m_gal->Translate( VECTOR2D(0, -( lineCount - 1 ) * lineHeight ) ); break; } } m_gal->SetIsStroke( true ); //m_gal->SetIsFill( false ); if( m_gal->IsFontBold() ) m_gal->SetLineWidth( m_gal->GetLineWidth() * BOLD_FACTOR ); // Split multiline strings into separate ones and draw them line by line size_t begin = 0; size_t newlinePos = aText.find( '\n' ); while( newlinePos != aText.npos ) { size_t length = newlinePos - begin; drawSingleLineText( aText.substr( begin, length ) ); m_gal->Translate( VECTOR2D( 0.0, lineHeight ) ); begin = newlinePos + 1; newlinePos = aText.find( '\n', begin ); } // Draw the last (or the only one) line if( !aText.empty() ) drawSingleLineText( aText.substr( begin ) ); m_gal->Restore(); }