void EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon(
        SHAPE_POLY_SET* aCornerBuffer, int aClearanceValue ) const
{
    // Oh dear.  When in UTF-8 mode, wxString puts string iterators in a linked list, and
    // that linked list is not thread-safe.
    std::lock_guard<std::mutex> guard( m_mutex );

    if( GetText().Length() == 0 )
        return;

    wxPoint  corners[4];    // Buffer of polygon corners

    EDA_RECT rect = GetTextBox( -1 );
    rect.Inflate( aClearanceValue );
    corners[0].x = rect.GetOrigin().x;
    corners[0].y = rect.GetOrigin().y;
    corners[1].y = corners[0].y;
    corners[1].x = rect.GetRight();
    corners[2].x = corners[1].x;
    corners[2].y = rect.GetBottom();
    corners[3].y = corners[2].y;
    corners[3].x = corners[0].x;

    aCornerBuffer->NewOutline();

    for( int ii = 0; ii < 4; ii++ )
    {
        // Rotate polygon
        RotatePoint( &corners[ii].x, &corners[ii].y, GetTextPos().x, GetTextPos().y, GetTextAngle() );
        aCornerBuffer->Append( corners[ii].x, corners[ii].y );
    }
}
Beispiel #2
0
void SCH_TEXT::Rotate( wxPoint aPosition )
{
    int dy;

    wxPoint pt = GetTextPos();
    RotatePoint( &pt, aPosition, 900 );
    SetTextPos( pt );

    int spin = GetLabelSpinStyle();

    // Global and hierarchical labels spin backwards.  Fix here because
    // changing SetLabelSpinStyle would break existing designs.
    if( this->Type() == SCH_GLOBAL_LABEL_T || this->Type() == SCH_HIERARCHICAL_LABEL_T )
        SetLabelSpinStyle( ( spin - 1 >= 0 ? ( spin - 1 ) : 3 ) );
    else
        SetLabelSpinStyle( ( spin + 1 ) % 4 );

    if( this->Type() == SCH_TEXT_T )
    {
        switch( GetLabelSpinStyle() )
        {
        case 0:  dy = GetTextHeight(); break;     // horizontal text
        case 1:  dy = 0;               break;     // Vert Orientation UP
        case 2:  dy = GetTextHeight(); break;     // invert horizontal text
        case 3:  dy = 0;               break;     // Vert Orientation BOTTOM
        default: dy = 0;               break;
        }

        SetTextY( GetTextPos().y + dy );
    }
}
Beispiel #3
0
const EDA_RECT SCH_TEXT::GetBoundingBox() const
{
    // We must pass the effective text thickness to GetTextBox
    // when calculating the bounding box
    int linewidth = GetThickness() == 0 ? GetDefaultLineThickness() : GetThickness();

    linewidth = Clamp_Text_PenSize( linewidth, GetTextSize(), IsBold() );

    EDA_RECT rect = GetTextBox( -1, linewidth );

    if( GetTextAngle() != 0 )      // Rotate rect
    {
        wxPoint pos = rect.GetOrigin();
        wxPoint end = rect.GetEnd();

        RotatePoint( &pos, GetTextPos(), GetTextAngle() );
        RotatePoint( &end, GetTextPos(), GetTextAngle() );

        rect.SetOrigin( pos );
        rect.SetEnd( end );
    }

    rect.Normalize();
    return rect;
}
Beispiel #4
0
int LIB_TEXT::compare( const LIB_ITEM& other ) const
{
    wxASSERT( other.Type() == LIB_TEXT_T );

    const LIB_TEXT* tmp = ( LIB_TEXT* ) &other;

    int result = m_Text.CmpNoCase( tmp->m_Text );

    if( result != 0 )
        return result;

    if( GetTextPos().x != tmp->GetTextPos().x )
        return GetTextPos().x - tmp->GetTextPos().x;

    if( GetTextPos().y != tmp->GetTextPos().y )
        return GetTextPos().y - tmp->GetTextPos().y;

    if( GetTextWidth() != tmp->GetTextWidth() )
        return GetTextWidth() - tmp->GetTextWidth();

    if( GetTextHeight() != tmp->GetTextHeight() )
        return GetTextHeight() - tmp->GetTextHeight();

    return 0;
}
void TEXTE_MODULE::Mirror( const wxPoint& aCentre, bool aMirrorAroundXAxis )
{
    // Used in modedit, to transform the footprint
    // the mirror is around the Y axis or X axis if aMirrorAroundXAxis = true
    // the position is mirrored, but the text itself is not mirrored
    if( aMirrorAroundXAxis )
        SetTextY( ::Mirror( GetTextPos().y, aCentre.y ) );
    else
        SetTextX( ::Mirror( GetTextPos().x, aCentre.x ) );

    SetLocalCoord();
}
Beispiel #6
0
const EDA_RECT SCH_GLOBALLABEL::GetBoundingBox() const
{
    int x, y, dx, dy, length, height;

    x  = GetTextPos().x;
    y  = GetTextPos().y;
    dx = dy = 0;

    int width = GetThickness() == 0 ? GetDefaultLineThickness() : GetThickness();

    height = ( (GetTextHeight() * 15) / 10 ) + width + 2 * TXT_MARGIN;

    // text X size add height for triangular shapes(bidirectional)
    length = LenSize( GetShownText(), width ) + height + DANGLING_SYMBOL_SIZE;

    switch( GetLabelSpinStyle() )    // respect orientation
    {
    default:
    case 0:                             // Horiz Normal Orientation (left justified)
        dx = -length;
        dy = height;
        x += DANGLING_SYMBOL_SIZE;
        y -= height / 2;
        break;

    case 1:     // Vert Orientation UP
        dx = height;
        dy = -length;
        x -= height / 2;
        y += DANGLING_SYMBOL_SIZE;
        break;

    case 2:     // Horiz Orientation - Right justified
        dx = length;
        dy = height;
        x -= DANGLING_SYMBOL_SIZE;
        y -= height / 2;
        break;

    case 3:     //  Vert Orientation BOTTOM
        dx = height;
        dy = length;
        x -= height / 2;
        y -= DANGLING_SYMBOL_SIZE;
        break;
    }

    EDA_RECT box( wxPoint( x, y ), wxSize( dx, dy ) );
    box.Normalize();
    return box;
}
Beispiel #7
0
void SCH_TEXT::Plot( PLOTTER* aPlotter )
{
    static std::vector <wxPoint> Poly;
    COLOR4D  color = GetLayerColor( GetLayer() );
    int      tmp = GetThickness();
    int      thickness = GetPenSize();

    // Two thicknesses are set here:
    // The first is for EDA_TEXT, which controls the interline spacing based on text thickness
    // The second is for the output that sets the actual stroke size
    SetThickness( thickness );
    aPlotter->SetCurrentLineWidth( thickness );

    if( IsMultilineAllowed() )
    {
        std::vector<wxPoint> positions;
        wxArrayString strings_list;
        wxStringSplit( GetShownText(), strings_list, '\n' );
        positions.reserve( strings_list.Count() );

        GetPositionsOfLinesOfMultilineText(positions, (int) strings_list.Count() );

        for( unsigned ii = 0; ii < strings_list.Count(); ii++ )
        {
            wxPoint textpos = positions[ii] + GetSchematicTextOffset();
            wxString& txt = strings_list.Item( ii );
            aPlotter->Text( textpos, color, txt, GetTextAngle(), GetTextSize(),
                            GetHorizJustify(), GetVertJustify(),
                            thickness, IsItalic(), IsBold() );
        }
    }
    else
    {
        wxPoint textpos = GetTextPos() + GetSchematicTextOffset();

        aPlotter->Text( textpos, color, GetShownText(), GetTextAngle(), GetTextSize(),
                        GetHorizJustify(), GetVertJustify(),
                        thickness, IsItalic(), IsBold() );
    }

    // Draw graphic symbol for global or hierarchical labels
    CreateGraphicShape( Poly, GetTextPos() );

    aPlotter->SetCurrentLineWidth( GetPenSize() );

    if( Poly.size() )
        aPlotter->PlotPoly( Poly, NO_FILL );

    SetThickness( tmp );
}
Beispiel #8
0
void SCH_SHEET_PIN::ConstrainOnEdge( wxPoint Pos )
{
    SCH_SHEET* sheet = GetParent();

    if( sheet == NULL )
        return;

    wxPoint center = sheet->m_pos + ( sheet->m_size / 2 );

    if( m_edge == SHEET_LEFT_SIDE || m_edge == SHEET_RIGHT_SIDE )
    {
        if( Pos.x > center.x )
        {
            SetEdge( SHEET_RIGHT_SIDE );
        }
        else
        {
            SetEdge( SHEET_LEFT_SIDE );
        }

        SetTextY( Pos.y );

        if( GetTextPos().y < sheet->m_pos.y )
            SetTextY( sheet->m_pos.y );

        if( GetTextPos().y > (sheet->m_pos.y + sheet->m_size.y) )
            SetTextY( sheet->m_pos.y + sheet->m_size.y );
    }
    else
    {
        if( Pos.y > center.y )
        {
            SetEdge( SHEET_BOTTOM_SIDE );
        }
        else
        {
            SetEdge( SHEET_TOP_SIDE );
        }

        SetTextX( Pos.x );

        if( GetTextPos().x < sheet->m_pos.x )
            SetTextX( sheet->m_pos.x );

        if( GetTextPos().x > (sheet->m_pos.x + sheet->m_size.x) )
            SetTextX( sheet->m_pos.x + sheet->m_size.x );
    }
}
Beispiel #9
0
void SCH_TEXT::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
                               SCH_SHEET_PATH*      aSheetPath )
{
    if( GetLayer() == LAYER_NOTES || GetLayer() == LAYER_SHEETLABEL )
        return;

    NETLIST_OBJECT* item = new NETLIST_OBJECT();
    item->m_SheetPath = *aSheetPath;
    item->m_SheetPathInclude = *aSheetPath;
    item->m_Comp = (SCH_ITEM*) this;
    item->m_Type = NET_LABEL;

    if( GetLayer() == LAYER_GLOBLABEL )
        item->m_Type = NET_GLOBLABEL;
    else if( GetLayer() == LAYER_HIERLABEL )
        item->m_Type = NET_HIERLABEL;

    item->m_Label = m_Text;
    item->m_Start = item->m_End = GetTextPos();

    aNetListItems.push_back( item );

    // If a bus connects to label
    if( Connection( *aSheetPath )->IsBusLabel( m_Text ) )
    {
        item->ConvertBusToNetListItems( aNetListItems );
    }
}
Beispiel #10
0
void SCH_SHEET_PIN::Rotate( wxPoint aPosition )
{
    wxPoint pt = GetTextPos();
    RotatePoint( &pt, aPosition, 900 );
    SetTextPos( pt );

    switch( m_edge )
    {
    case SHEET_LEFT_SIDE:     //pin on left side
        SetEdge( SHEET_BOTTOM_SIDE );
        break;

    case SHEET_RIGHT_SIDE:     //pin on right side
        SetEdge( SHEET_TOP_SIDE );
        break;

    case SHEET_TOP_SIDE:      //pin on top side
        SetEdge( SHEET_LEFT_SIDE );
        break;

    case SHEET_BOTTOM_SIDE:     //pin on bottom side
        SetEdge( SHEET_RIGHT_SIDE );
        break;

    default:
        break;
    }
}
Beispiel #11
0
bool LIB_FIELD::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
    // Because HitTest is mainly used to select the field return false if it is void
    if( IsVoid() )
        return false;

    // Build a temporary copy of the text for hit testing
    EDA_TEXT tmp_text( *this );

    // Reference designator text has one or 2 additional character (displays
    // U? or U?A)
    if( m_id == REFERENCE )
    {
        wxString extended_text = tmp_text.GetText();
        extended_text.Append('?');
        const LIB_PART*      parent = static_cast<const LIB_PART*>( m_Parent );

        if ( parent && ( parent->GetUnitCount() > 1 ) )
            extended_text.Append('A');
        tmp_text.SetText( extended_text );
    }

    tmp_text.SetTextPos( DefaultTransform.TransformCoordinate( GetTextPos() ) );

    /* The text orientation may need to be flipped if the
     *  transformation matrix causes xy axes to be flipped.
     * this simple algo works only for schematic matrix (rot 90 or/and mirror)
     */
    bool t1 = ( DefaultTransform.x1 != 0 ) ^ ( GetTextAngle() != 0 );
    tmp_text.SetTextAngle( t1 ? TEXT_ANGLE_HORIZ : TEXT_ANGLE_VERT );

    return tmp_text.TextHitTest( aPosition, aAccuracy );
}
void TEXTE_MODULE::SetLocalCoord()
{
    const MODULE* module = static_cast<const MODULE*>( m_Parent );

    if( module )
    {
        m_Pos0 = GetTextPos() - module->GetPosition();

        double angle = module->GetOrientation();

        RotatePoint( &m_Pos0.x, &m_Pos0.y, -angle );
    }
    else
    {
        m_Pos0 = GetTextPos();
    }
}
bool SCH_FIELD::Save( FILE* aFile ) const
{
    char hjustify = 'C';

    if( GetHorizJustify() == GR_TEXT_HJUSTIFY_LEFT )
        hjustify = 'L';
    else if( GetHorizJustify() == GR_TEXT_HJUSTIFY_RIGHT )
        hjustify = 'R';

    char vjustify = 'C';

    if( GetVertJustify() == GR_TEXT_VJUSTIFY_BOTTOM )
        vjustify = 'B';
    else if( GetVertJustify() == GR_TEXT_VJUSTIFY_TOP )
        vjustify = 'T';

    if( fprintf( aFile, "F %d %s %c %-3d %-3d %-3d %4.4X %c %c%c%c",
                 m_id,
                 EscapedUTF8( m_Text ).c_str(),     // wraps in quotes too
                 GetTextAngle() == TEXT_ANGLE_HORIZ ? 'H' : 'V',
                 GetTextPos().x, GetTextPos().y,
                 GetTextWidth(),
                 !IsVisible(),
                 hjustify, vjustify,
                 IsItalic() ? 'I' : 'N',
                 IsBold() ? 'B' : 'N' ) == EOF )
    {
        return false;
    }

    // Save field name, if the name is user definable
    if( m_id >= FIELD1 )
    {
        if( fprintf( aFile, " %s", EscapedUTF8( m_name ).c_str() ) == EOF )
        {
            return false;
        }
    }

    if( fprintf( aFile, "\n" ) == EOF )
    {
        return false;
    }

    return true;
}
void TEXTE_PCB::Rotate( const wxPoint& aRotCentre, double aAngle )
{
    wxPoint pt = GetTextPos();
    RotatePoint( &pt, aRotCentre, aAngle );
    SetTextPos( pt );

    SetTextAngle( GetTextAngle() + aAngle );
}
wxPoint SCH_FIELD::GetPosition() const
{
    SCH_COMPONENT* component = (SCH_COMPONENT*) GetParent();

    wxPoint pos = GetTextPos() - component->GetPosition();

    return component->GetTransform().TransformCoordinate( pos ) + component->GetPosition();
}
Beispiel #16
0
void SCH_TEXT::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
{
    // Normal text labels do not have connection points.  All others do.
    if( Type() == SCH_TEXT_T )
        return;

    aPoints.push_back( GetTextPos() );
}
const EDA_RECT TEXTE_PCB::GetBoundingBox() const
{
    EDA_RECT rect = GetTextBox( -1, -1 );

    if( GetTextAngle() )
        rect = rect.GetBoundingBoxRotated( GetTextPos(), GetTextAngle() );

    return rect;
}
Beispiel #18
0
void SCH_TEXT::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
{
    // Normal text labels cannot be tested for dangling ends.
    if( Type() == SCH_TEXT_T )
        return;

    DANGLING_END_ITEM item( LABEL_END, this, GetTextPos() );
    aItemList.push_back( item );
}
void TEXTE_PCB::Flip( const wxPoint& aCentre )
{
    SetTextY( aCentre.y - ( GetTextPos().y - aCentre.y ) );

    int copperLayerCount = GetBoard()->GetCopperLayerCount();

    SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
    SetMirrored( !IsMirrored() );
}
Beispiel #20
0
void LIB_TEXT::MirrorVertical( const wxPoint& center )
{
    int y = GetTextPos().y;

    y -= center.y;
    y *= -1;
    y += center.y;

    SetTextY( y );
}
Beispiel #21
0
void LIB_TEXT::Rotate( const wxPoint& center, bool aRotateCCW )
{
    int rot_angle = aRotateCCW ? -900 : 900;

    wxPoint pt = GetTextPos();
    RotatePoint( &pt, center, rot_angle );
    SetTextPos( pt );

    SetTextAngle( GetTextAngle() != 0.0 ? 0 : 900 );
}
const BOX2I TEXTE_MODULE::ViewBBox() const
{
    double   angle = GetDrawRotation();
    EDA_RECT text_area = GetTextBox( -1, -1 );

    if( angle )
        text_area = text_area.GetBoundingBoxRotated( GetTextPos(), angle );

    return BOX2I( text_area.GetPosition(), text_area.GetSize() );
}
Beispiel #23
0
void LIB_TEXT::MirrorHorizontal( const wxPoint& center )
{
    int x = GetTextPos().x;

    x -= center.x;
    x *= -1;
    x += center.x;

    SetTextX( x );
}
const EDA_RECT TEXTE_MODULE::GetBoundingBox() const
{
    double   angle = GetDrawRotation();
    EDA_RECT text_area = GetTextBox( -1, -1 );

    if( angle )
        text_area = text_area.GetBoundingBoxRotated( GetTextPos(), angle );

    return text_area;
}
Beispiel #25
0
bool SCH_TEXT::IsSelectStateChanged( const wxRect& aRect )
{
    bool previousState = IsSelected();

    if( aRect.Contains( GetTextPos() ) )
        SetFlags( SELECTED );
    else
        ClearFlags( SELECTED );

    return previousState != IsSelected();
}
bool TEXTE_MODULE::TextHitTest( const wxPoint& aPoint, int aAccuracy ) const
{
    EDA_RECT rect = GetTextBox( -1 );
    wxPoint location = aPoint;

    rect.Inflate( aAccuracy );

    RotatePoint( &location, GetTextPos(), -GetDrawRotation() );

    return rect.Contains( location );
}
void TEXTE_MODULE::Flip( const wxPoint& aCentre )
{
    // flipping the footprint is relative to the X axis
    SetTextY( ::Mirror( GetTextPos().y, aCentre.y ) );

    SetTextAngle( -GetTextAngle() );

    SetLayer( FlipLayer( GetLayer() ) );
    SetMirrored( IsBackLayer( GetLayer() ) );
    SetLocalCoord();
}
void TEXTE_MODULE::Rotate( const wxPoint& aRotCentre, double aAngle )
{
    // Used in footprint edition
    // Note also in module editor, m_Pos0 = m_Pos

    wxPoint pt = GetTextPos();
    RotatePoint( &pt, aRotCentre, aAngle );
    SetTextPos( pt );

    SetTextAngle( GetTextAngle() + aAngle );
    SetLocalCoord();
}
Beispiel #29
0
const EDA_RECT SCH_LABEL::GetBoundingBox() const
{
    int         linewidth = GetThickness() == 0 ? GetDefaultLineThickness() : GetThickness();
    EDA_RECT    rect = GetTextBox( -1, linewidth );

    if( GetTextAngle() != 0.0 )
    {
        // Rotate rect
        wxPoint pos = rect.GetOrigin();
        wxPoint end = rect.GetEnd();

        RotatePoint( &pos, GetTextPos(), GetTextAngle() );
        RotatePoint( &end, GetTextPos(), GetTextAngle() );

        rect.SetOrigin( pos );
        rect.SetEnd( end );

        rect.Normalize();
    }

    return rect;
}
Beispiel #30
0
const EDA_RECT LIB_TEXT::GetBoundingBox() const
{
    /* Y coordinates for LIB_ITEMS are bottom to top, so we must invert the Y position when
     * calling GetTextBox() that works using top to bottom Y axis orientation.
     */
    EDA_RECT rect = GetTextBox( -1, -1, true );
    rect.RevertYAxis();

    // We are using now a bottom to top Y axis.
    wxPoint orig = rect.GetOrigin();
    wxPoint end  = rect.GetEnd();

    RotatePoint( &orig, GetTextPos(), -GetTextAngle() );
    RotatePoint( &end,  GetTextPos(), -GetTextAngle() );

    rect.SetOrigin( orig );
    rect.SetEnd( end );

    // We are using now a top to bottom Y axis:
    rect.RevertYAxis();

    return rect;
}