/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2017 CERN * @author Maciej Suminski * * 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 #include #include #include #include #include using namespace std; // Common calculation part for all BOARD_ITEMs static inline size_t hash_board_item( const BOARD_ITEM* aItem, int aFlags ) { size_t ret = 0; if( aFlags & LAYER ) ret ^= hash{}( aItem->GetLayerSet().to_ullong() ); return ret; } size_t hash_eda( const EDA_ITEM* aItem, int aFlags ) { size_t ret = 0xa82de1c0; switch( aItem->Type() ) { case PCB_MODULE_T: { const MODULE* module = static_cast( aItem ); ret ^= hash_board_item( module, aFlags ); if( aFlags & POSITION ) { ret ^= hash{}( module->GetPosition().x ); ret ^= hash{}( module->GetPosition().y ); } if( aFlags & ROTATION ) ret ^= hash{}( module->GetOrientation() ); for( const BOARD_ITEM* i = module->GraphicalItemsList(); i; i = i->Next() ) ret ^= hash_eda( i, aFlags ); for( const D_PAD* i = module->PadsList(); i; i = i->Next() ) ret ^= hash_eda( i, aFlags ); } break; case PCB_PAD_T: { const D_PAD* pad = static_cast( aItem ); ret ^= hash_board_item( pad, aFlags ); ret ^= hash{}( pad->GetShape() << 16 ); ret ^= hash{}( pad->GetDrillShape() << 18 ); ret ^= hash{}( pad->GetSize().x << 8 ); ret ^= hash{}( pad->GetSize().y << 9 ); ret ^= hash{}( pad->GetOffset().x << 6 ); ret ^= hash{}( pad->GetOffset().y << 7 ); ret ^= hash{}( pad->GetDelta().x << 4 ); ret ^= hash{}( pad->GetDelta().y << 5 ); if( aFlags & POSITION ) { if( aFlags & REL_COORD ) { ret ^= hash{}( pad->GetPos0().x ); ret ^= hash{}( pad->GetPos0().y ); } else { ret ^= hash{}( pad->GetPosition().x ); ret ^= hash{}( pad->GetPosition().y ); } } if( aFlags & ROTATION ) ret ^= hash{}( pad->GetOrientation() ); if( aFlags & NET ) ret ^= hash{}( pad->GetNetCode() << 6 ); } break; case PCB_MODULE_TEXT_T: { const TEXTE_MODULE* text = static_cast( aItem ); if( !( aFlags & REFERENCE ) && text->GetType() == TEXTE_MODULE::TEXT_is_REFERENCE ) break; if( !( aFlags & VALUE ) && text->GetType() == TEXTE_MODULE::TEXT_is_VALUE ) break; ret ^= hash_board_item( text, aFlags ); ret ^= hash{}( text->GetText().ToStdString() ); ret ^= hash{}( text->IsItalic() ); ret ^= hash{}( text->IsBold() ); ret ^= hash{}( text->IsMirrored() ); ret ^= hash{}( text->GetTextWidth() ); ret ^= hash{}( text->GetTextHeight() ); ret ^= hash{}( text->GetHorizJustify() ); ret ^= hash{}( text->GetVertJustify() ); if( aFlags & POSITION ) { if( aFlags & REL_COORD ) { ret ^= hash{}( text->GetPos0().x ); ret ^= hash{}( text->GetPos0().y ); } else { ret ^= hash{}( text->GetPosition().x ); ret ^= hash{}( text->GetPosition().y ); } } if( aFlags & ROTATION ) ret ^= hash{}( text->GetTextAngle() ); } break; case PCB_MODULE_EDGE_T: { const EDGE_MODULE* segment = static_cast( aItem ); ret ^= hash_board_item( segment, aFlags ); ret ^= hash{}( segment->GetType() ); ret ^= hash{}( segment->GetShape() ); ret ^= hash{}( segment->GetWidth() ); ret ^= hash{}( segment->GetRadius() ); if( aFlags & POSITION ) { if( aFlags & REL_COORD ) { ret ^= hash{}( segment->GetStart0().x ); ret ^= hash{}( segment->GetStart0().y ); ret ^= hash{}( segment->GetEnd0().x ); ret ^= hash{}( segment->GetEnd0().y ); } else { ret ^= hash{}( segment->GetStart().x ); ret ^= hash{}( segment->GetStart().y ); ret ^= hash{}( segment->GetEnd().x ); ret ^= hash{}( segment->GetEnd().y ); } } if( aFlags & ROTATION ) ret ^= hash{}( segment->GetAngle() ); } break; default: wxASSERT_MSG( false, "Unhandled type in function hashModItem() (exporter_gencad.cpp)" ); } return ret; }