Commit 4f471eb5 authored by Dick Hollenbeck's avatar Dick Hollenbeck
Browse files

EAGLE_PLUGIN::Load() is now completed.

parent f5047b29
Loading
Loading
Loading
Loading
+165 −134
Original line number Original line Diff line number Diff line
@@ -462,21 +462,17 @@ struct EATTR
    opt_int     layer;
    opt_int     layer;
    opt_double  ratio;
    opt_double  ratio;
    opt_erot    rot;
    opt_erot    rot;
    opt_int     display;


    enum {  // for 'display' field above
    enum {  // for 'display'
        Off,
        Off,
        VALUE,
        VALUE,
        NAME,
        NAME,
        BOTH,
        BOTH,
    };
    };
    opt_int     display;


    EATTR( CPTREE& aTree );
    EATTR( CPTREE& aTree );

    EATTR() {}
    EATTR( const opt_erot& aOptRot, double childAngle ) :
        rot( aOptRot )
    {
    }
};
};


/**
/**
@@ -1292,8 +1288,6 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics )
            ETEXT   t( gr->second );
            ETEXT   t( gr->second );
            int     layer = kicad_layer( t.layer );
            int     layer = kicad_layer( t.layer );


            int     sign = 1;

            TEXTE_PCB* pcbtxt = new TEXTE_PCB( m_board );
            TEXTE_PCB* pcbtxt = new TEXTE_PCB( m_board );
            m_board->Add( pcbtxt, ADD_APPEND );
            m_board->Add( pcbtxt, ADD_APPEND );


@@ -1308,34 +1302,29 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics )


            pcbtxt->SetThickness( kicad( t.size * ratio / 100 ) );
            pcbtxt->SetThickness( kicad( t.size * ratio / 100 ) );


            int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT;

            if( t.rot )
            if( t.rot )
            {
            {
#if 0
                int sign = t.rot->mirror ? -1 : 1;
                if( t.rot->spin || ( t.rot->degrees != 180 && t.rot->degrees != 270 ) )
                pcbtxt->SetMirrored( t.rot->mirror );
                    pcbtxt->SetOrientation( t.rot->degrees * 10 );


                else
                double degrees = t.rot->degrees;
                    // flip the justification to opposite
                    sign = -1;
#else
                // eagles does not rotate text spun to 180 degrees unless spin is set.
                if( t.rot->spin || t.rot->degrees != 180 )
                    pcbtxt->SetOrientation( t.rot->degrees * 10 );


                else
                if( degrees == 90 || t.rot->spin )
                    // flip the justification to opposite
                    pcbtxt->SetOrientation( sign * t.rot->degrees * 10 );
                    sign = -1;


                if( t.rot->degrees == 270 )
                else if( degrees == 180 )
                    sign = -1;
                    align = ETEXT::TOP_RIGHT;
#endif
                pcbtxt->SetMirrored( t.rot->mirror );


                else if( degrees == 270 )
                {
                    pcbtxt->SetOrientation( sign * 90 * 10 );
                    align = ETEXT::TOP_RIGHT;
                }
            }
            }


            int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT;
            switch( align )

            switch( align * sign )  // if negative, opposite is chosen
            {
            {
            case ETEXT::CENTER:
            case ETEXT::CENTER:
                // this was the default in pcbtxt's constructor
                // this was the default in pcbtxt's constructor
@@ -1556,6 +1545,9 @@ void EAGLE_PLUGIN::loadElements( CPTREE& aElements )
{
{
    m_xpath->push( "elements.element", "name" );
    m_xpath->push( "elements.element", "name" );


    EATTR   name;
    EATTR   value;

    for( CITER it = aElements.begin();  it != aElements.end();  ++it )
    for( CITER it = aElements.begin();  it != aElements.end();  ++it )
    {
    {
        if( it->first.compare( "element" ) )
        if( it->first.compare( "element" ) )
@@ -1563,6 +1555,10 @@ void EAGLE_PLUGIN::loadElements( CPTREE& aElements )


        EELEMENT    e( it->second );
        EELEMENT    e( it->second );


        // use "NULL-ness" as an indiation of presence of the attribute:
        EATTR*      nameAttr  = 0;
        EATTR*      valueAttr = 0;

        m_xpath->Value( e.name.c_str() );
        m_xpath->Value( e.name.c_str() );


#if 1 && defined(DEBUG)
#if 1 && defined(DEBUG)
@@ -1586,13 +1582,12 @@ void EAGLE_PLUGIN::loadElements( CPTREE& aElements )
        }
        }


#if defined(DEBUG)
#if defined(DEBUG)
        if( !e.name.compare( "IC2" ) )
        if( !e.name.compare( "IC3" ) )
        {
        {
            int breakhere = 1;
            int breakhere = 1;
            (void) breakhere;
            (void) breakhere;
        }
        }
#endif
#endif

        // copy constructor to clone the template
        // copy constructor to clone the template
        MODULE* m = new MODULE( *mi->second );
        MODULE* m = new MODULE( *mi->second );
        m_board->Add( m, ADD_APPEND );
        m_board->Add( m, ADD_APPEND );
@@ -1616,19 +1611,7 @@ void EAGLE_PLUGIN::loadElements( CPTREE& aElements )
        m->SetValue( FROM_UTF8( e.value.c_str() ) );
        m->SetValue( FROM_UTF8( e.value.c_str() ) );
        // m->Value().SetVisible( false );
        // m->Value().SetVisible( false );


        if( e.rot )
        {
            if( e.rot->mirror )
            {
                m->Flip( m->GetPosition() );
            }
            m->SetOrientation( e.rot->degrees * 10 );
        }

        // initalize these to default values incase the <attribute> elements are not present.
        // initalize these to default values incase the <attribute> elements are not present.
        EATTR   reference( e.rot, m->Reference().GetOrientation()/10 );
        EATTR   value( e.rot, m->Value().GetOrientation()/10 );

        m_xpath->push( "attribute", "name" );
        m_xpath->push( "attribute", "name" );


        // VALUE and NAME can have something like our text "effects" overrides
        // VALUE and NAME can have something like our text "effects" overrides
@@ -1645,19 +1628,49 @@ void EAGLE_PLUGIN::loadElements( CPTREE& aElements )
            EATTR   a( ait->second );
            EATTR   a( ait->second );


            if( !a.name.compare( "NAME" ) )
            if( !a.name.compare( "NAME" ) )
                reference = a;
            {
                name = a;
                nameAttr = &name;
            }
            else if( !a.name.compare( "VALUE" ) )
            else if( !a.name.compare( "VALUE" ) )
            {
                value = a;
                value = a;
                valueAttr = &value;
            }
        }
        }


        m_xpath->pop();     // "attribute"
        m_xpath->pop();     // "attribute"


        for( int i=0; i<2; ++i )
        orientModuleAndText( m, e, nameAttr, valueAttr );
    }

    m_xpath->pop();     // "elements.element"
}


void EAGLE_PLUGIN::orientModuleAndText( MODULE* m, const EELEMENT& e,
                    const EATTR* nameAttr, const EATTR* valueAttr )
{
    if( e.rot )
    {
        if( e.rot->mirror )
        {
        {
            const EATTR&    a   = i ? reference: value;
            m->Flip( m->GetPosition() );
            TEXTE_MODULE*   txt = i ? &m->Reference() : &m->Value();
        }
        m->SetOrientation( e.rot->degrees * 10 );
    }

    orientModuleText( m, e, &m->Reference(), nameAttr );
    orientModuleText( m, e, &m->Value(), valueAttr );
}


            m_xpath->Value( a.name.c_str() );   // breadcrum: element[name=*]

void EAGLE_PLUGIN::orientModuleText( MODULE* m, const EELEMENT& e,
                            TEXTE_MODULE* txt, const EATTR* aAttr )
{
    if( aAttr )
    {
        const EATTR& a = *aAttr;


        if( a.value )
        if( a.value )
        {
        {
@@ -1675,49 +1688,90 @@ void EAGLE_PLUGIN::loadElements( CPTREE& aElements )


        // Even though size and ratio are both optional, I am not seeing
        // Even though size and ratio are both optional, I am not seeing
        // a case where ratio is present but size is not.
        // a case where ratio is present but size is not.
        double  ratio = 8;
        wxSize  fontz = txt->GetSize();


        if( a.size )
        if( a.size )
        {
        {
                wxSize  fontz = kicad_fontz( *a.size );
            fontz = kicad_fontz( *a.size );
            txt->SetSize( fontz );
            txt->SetSize( fontz );


            if( a.ratio )
            if( a.ratio )
                {
                ratio = *a.ratio;
                    double  ratio = *a.ratio;
        }

        int  lw = int( fontz.y * ratio / 100.0 );
        int  lw = int( fontz.y * ratio / 100.0 );
        txt->SetThickness( lw );
        txt->SetThickness( lw );
                }

            }
        int align = ETEXT::BOTTOM_LEFT;     // bottom-left is eagle default


        // The "rot" in a EATTR seems to be assumed to be zero if it is not
        // The "rot" in a EATTR seems to be assumed to be zero if it is not
        // present, and this zero rotation becomes an override to the
        // present, and this zero rotation becomes an override to the
        // package's text field.  If they did not want zero, they specify
        // package's text field.  If they did not want zero, they specify
        // what they want explicitly.
        // what they want explicitly.
        double  degrees  = a.rot ? a.rot->degrees : 0;
        double  orient;      // relative to parent


            EROT rot;   // initialize degrees to zero here
        int     sign = 1;
        bool    spin = false;


        if( a.rot )
        if( a.rot )
        {
        {
                rot = *a.rot;
            spin = a.rot->spin;
                txt->SetMirrored( rot.mirror );
            sign = a.rot->mirror ? -1 : 1;
            txt->SetMirrored( a.rot->mirror );
        }
        }


            if( rot.spin || (rot.degrees != 180 && rot.degrees != 270) )
        if( degrees == 90 || degrees == 0 || spin )
        {
        {
                double angle = rot.degrees * 10;
            orient = degrees - m->GetOrientation() / 10;
                angle -= m->GetOrientation();   // subtract module's angle
            txt->SetOrientation( sign * orient * 10 );
                txt->SetOrientation( angle );
        }
        }
            else

        else if( degrees == 180 )
        {
        {
                // ETEXT::TOP_RIGHT:
            orient = 0 - m->GetOrientation() / 10;
            txt->SetOrientation( sign * orient * 10 );
            align = ETEXT::TOP_RIGHT;
        }

        else if( degrees == 270 )
        {
            orient = 90 - m->GetOrientation() / 10;
            align = ETEXT::TOP_RIGHT;
            txt->SetOrientation( sign * orient * 10 );
        }

        switch( align )
        {
        case ETEXT::TOP_RIGHT:
            txt->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
            txt->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
            txt->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
            txt->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
            }
            break;

        case ETEXT::BOTTOM_LEFT:
            txt->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
            txt->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
            break;

        default:
            ;
        }
        }
    }
    }


    m_xpath->pop();     // "elements.element"
    else    // the text is per the original package, sans <attribute>
    {
        double degrees = ( txt->GetOrientation() + m->GetOrientation() ) / 10;

        // @todo there are a few more cases than theses to contend with:
        if( (!txt->IsMirrored() && ( abs( degrees ) == 180 || abs( degrees ) == 270 ))
         || ( txt->IsMirrored() && ( degrees == 360 ) ) )
        {
            // ETEXT::TOP_RIGHT:
            txt->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
            txt->SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
        }
    }
}
}




@@ -1846,33 +1900,11 @@ void EAGLE_PLUGIN::packagePad( MODULE* aModule, CPTREE& aTree ) const
    }
    }
    else
    else
    {
    {
#if 0
        // The pad size is optional in the eagle DTD, so we must guess.
        // Supply something here that is a minimum copper surround, or otherwise
        // 120% of drillz whichever is greater.  But for PAD_OVAL, we can use
        // a smaller minimum than for a round pad, since there is a larger copper
        // body on the elongated ends.

        int min_copper;

        if( pad->GetShape() == PAD_OVAL )
            min_copper = Mils2iu( 4 );
        else
            min_copper = Mils2iu( 6 );

        // minz copper surround as a minimum, otherwise 110% of drillz.
        int drillz   = pad->GetDrillSize().x;
        int diameter = std::max( drillz + 2 * min_copper, int( drillz * 1.2 ) );

        pad->SetSize( wxSize( diameter, diameter ) );

#else
        double drillz  = pad->GetDrillSize().x;
        double drillz  = pad->GetDrillSize().x;
        double annulus = drillz * m_rules->rvPadTop;   // copper annulus, eagle "restring"
        double annulus = drillz * m_rules->rvPadTop;   // copper annulus, eagle "restring"
        annulus = Clamp( m_rules->rlMinPadTop, annulus, m_rules->rlMaxPadTop );
        annulus = Clamp( m_rules->rlMinPadTop, annulus, m_rules->rlMaxPadTop );
        int diameter = KiROUND( drillz + 2 * annulus );
        int diameter = KiROUND( drillz + 2 * annulus );
        pad->SetSize( wxSize( KiROUND( diameter ), KiROUND( diameter ) ) );
        pad->SetSize( wxSize( KiROUND( diameter ), KiROUND( diameter ) ) );
#endif
    }
    }


    if( pad->GetShape() == PAD_OVAL )
    if( pad->GetShape() == PAD_OVAL )
@@ -1918,13 +1950,6 @@ void EAGLE_PLUGIN::packageText( MODULE* aModule, CPTREE& aTree ) const
    txt->SetPosition( pos );
    txt->SetPosition( pos );
    txt->SetPos0( pos - aModule->GetPosition() );
    txt->SetPos0( pos - aModule->GetPosition() );


    /*
    switch( layer )
    {
    case COMMENT_N: layer = SILKSCREEN_N_FRONT; break;
    }
    */

    txt->SetLayer( layer );
    txt->SetLayer( layer );


    txt->SetSize( kicad_fontz( t.size ) );
    txt->SetSize( kicad_fontz( t.size ) );
@@ -1933,26 +1958,32 @@ void EAGLE_PLUGIN::packageText( MODULE* aModule, CPTREE& aTree ) const


    txt->SetThickness( kicad( t.size * ratio / 100 ) );
    txt->SetThickness( kicad( t.size * ratio / 100 ) );


    double angle = t.rot ? t.rot->degrees * 10 : 0;
    int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT;  // bottom-left is eagle default


    // An eagle package is never rotated, the DTD does not allow it.
    // An eagle package is never rotated, the DTD does not allow it.
    // angle -= aModule->GetOrienation();
    // angle -= aModule->GetOrienation();


    int sign = 1;
    if( t.rot )
    if( t.rot )
    {
    {
        if( t.rot->spin || (angle != 1800 && angle != 2700) )
        int sign = t.rot->mirror ? -1 : 1;
            txt->SetOrientation( angle );
        txt->SetMirrored( t.rot->mirror );


        else    // 180 or 270 degrees, reverse justification below, don't spin
        double degrees = t.rot->degrees;
            sign = -1;


        txt->SetMirrored( t.rot->mirror );
        if( degrees == 90 || t.rot->spin )
    }
            txt->SetOrientation( sign * degrees * 10 );


    int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT;  // bottom-left is eagle default
        else if( degrees == 180 )
            align = ETEXT::TOP_RIGHT;

        else if( degrees == 270 )
        {
            align = ETEXT::TOP_RIGHT;
            txt->SetOrientation( sign * 90 * 10 );
        }
    }


    switch( align * sign )  // when negative, opposites are chosen
    switch( align )
    {
    {
    case ETEXT::CENTER:
    case ETEXT::CENTER:
        // this was the default in pcbtxt's constructor
        // this was the default in pcbtxt's constructor
+7 −0
Original line number Original line Diff line number Diff line
@@ -62,8 +62,11 @@ typedef NET_MAP::const_iterator NET_MAP_CITER;
typedef boost::property_tree::ptree     PTREE;
typedef boost::property_tree::ptree     PTREE;
typedef const PTREE                     CPTREE;
typedef const PTREE                     CPTREE;


class EELEMENT;
class XPATH;
class XPATH;
struct ERULES;
struct ERULES;
struct EATTR;
class TEXTE_MODULE;




/**
/**
@@ -183,6 +186,10 @@ private:
    void loadLibraries( CPTREE& aLibs );
    void loadLibraries( CPTREE& aLibs );
    void loadElements( CPTREE& aElements );
    void loadElements( CPTREE& aElements );


    void orientModuleAndText( MODULE* m, const EELEMENT& e, const EATTR* nameAttr, const EATTR* valueAttr );
    void orientModuleText( MODULE* m, const EELEMENT& e, TEXTE_MODULE* txt, const EATTR* a );


    /// move the BOARD into the center of the page
    /// move the BOARD into the center of the page
    void centerBoard();
    void centerBoard();