Exemple #1
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;
}
const EDA_RECT TEXTE_PCB::GetBoundingBox() const
{
    EDA_RECT rect = GetTextBox( -1, -1 );

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

    return rect;
}
Exemple #3
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 );
}
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 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 );
    }
}
void TEXTE_PCB::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList )
{
    wxString    msg;

    wxCHECK_RET( m_Parent != NULL, wxT( "TEXTE_PCB::GetMsgPanelInfo() m_Parent is NULL." ) );

    if( m_Parent->Type() == PCB_DIMENSION_T )
        aList.push_back( MSG_PANEL_ITEM( _( "Dimension" ), GetShownText(), DARKGREEN ) );
    else
        aList.push_back( MSG_PANEL_ITEM( _( "PCB Text" ), GetShownText(), DARKGREEN ) );

    aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), GetLayerName(), BLUE ) );

    if( !IsMirrored() )
        aList.push_back( MSG_PANEL_ITEM( _( "Mirror" ), _( "No" ), DARKGREEN ) );
    else
        aList.push_back( MSG_PANEL_ITEM( _( "Mirror" ), _( "Yes" ), DARKGREEN ) );

    msg.Printf( wxT( "%.1f" ), GetTextAngle() / 10.0 );
    aList.push_back( MSG_PANEL_ITEM( _( "Angle" ), msg, DARKGREEN ) );

    msg = MessageTextFromValue( aUnits, GetThickness() );
    aList.push_back( MSG_PANEL_ITEM( _( "Thickness" ), msg, MAGENTA ) );

    msg = MessageTextFromValue( aUnits, GetTextWidth() );
    aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, RED ) );

    msg = MessageTextFromValue( aUnits, GetTextHeight() );
    aList.push_back( MSG_PANEL_ITEM( _( "Height" ), msg, RED ) );
}
Exemple #7
0
void LIB_TEXT::Plot( PLOTTER* plotter, const wxPoint& offset, bool fill,
                     const TRANSFORM& aTransform )
{
    wxASSERT( plotter != NULL );

    EDA_RECT bBox = GetBoundingBox();
    // convert coordinates from draw Y axis to libedit Y axis
    bBox.RevertYAxis();
    wxPoint txtpos = bBox.Centre();

    /* The text orientation may need to be flipped if the
     * transformation matrix causes xy axes to be flipped. */
    int t1  = ( aTransform.x1 != 0 ) ^ ( GetTextAngle() != 0 );
    wxPoint pos = aTransform.TransformCoordinate( txtpos ) + offset;

    // Get color
    COLOR4D color;

    if( plotter->GetColorMode() )       // Used normal color or selected color
        color = IsSelected() ? GetItemSelectedColor() : GetDefaultColor();
    else
        color = COLOR4D::BLACK;

    plotter->Text( pos, color, GetShownText(),
                   t1 ? TEXT_ANGLE_HORIZ : TEXT_ANGLE_VERT,
                   GetTextSize(), GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
                   GetPenSize(), IsItalic(), IsBold() );
}
void LIB_FIELD::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
                      const TRANSFORM& aTransform )
{
    if( IsVoid() )
        return;

    /* Calculate the text orientation, according to the component
     * orientation/mirror */
    int orient = (int) GetTextAngle();

    if( aTransform.y1 )  // Rotate component 90 deg.
    {
        if( orient == TEXT_ANGLE_HORIZ )
            orient = TEXT_ANGLE_VERT;
        else
            orient = TEXT_ANGLE_HORIZ;
    }

    EDA_RECT BoundaryBox = GetBoundingBox();
    BoundaryBox.RevertYAxis();

    EDA_TEXT_HJUSTIFY_T hjustify = GR_TEXT_HJUSTIFY_CENTER;
    EDA_TEXT_VJUSTIFY_T vjustify = GR_TEXT_VJUSTIFY_CENTER;
    wxPoint textpos = aTransform.TransformCoordinate( BoundaryBox.Centre() )
                      + aOffset;

    aPlotter->Text( textpos, GetDefaultColor(), GetShownText(),
                    orient, GetTextSize(),
                    hjustify, vjustify,
                    GetPenSize(), IsItalic(), IsBold() );
}
void TEXTE_PCB::Rotate( const wxPoint& aRotCentre, double aAngle )
{
    wxPoint pt = GetTextPos();
    RotatePoint( &pt, aRotCentre, aAngle );
    SetTextPos( pt );

    SetTextAngle( GetTextAngle() + aAngle );
}
const EDA_RECT SCH_FIELD::GetBoundingBox() const
{
    SCH_COMPONENT* parentComponent = (SCH_COMPONENT*) m_Parent;
    int linewidth = GetThickness() == 0 ? GetDefaultLineThickness() : GetThickness();

    // We must pass the effective text thickness to GetTextBox
    // when calculating the bounding box
    linewidth = Clamp_Text_PenSize( linewidth, GetTextSize(), IsBold() );

    // Calculate the text bounding box:
    EDA_RECT rect;

    if( m_id == REFERENCE )     // multi units have one letter or more added to reference
    {
        SCH_FIELD text( *this );    // Make a local copy to change text
                                    // because GetBoundingBox() is const
        text.SetText( GetFullyQualifiedText() );
        rect = text.GetTextBox( -1, linewidth );
    }
    else
        rect = GetTextBox( -1, linewidth );

    // Calculate the bounding box position relative to the component:
    wxPoint origin = parentComponent->GetPosition();
    wxPoint pos = GetTextPos() - origin;
    wxPoint begin = rect.GetOrigin() - origin;
    wxPoint end = rect.GetEnd() - origin;
    RotatePoint( &begin, pos, GetTextAngle() );
    RotatePoint( &end, pos, GetTextAngle() );

    // Due to the Y axis direction, we must mirror the bounding box,
    // relative to the text position:
    MIRROR( begin.y, pos.y );
    MIRROR( end.y,   pos.y );

    // Now, apply the component transform (mirror/rot)
    begin = parentComponent->GetTransform().TransformCoordinate( begin );
    end = parentComponent->GetTransform().TransformCoordinate( end );
    rect.SetOrigin( begin);
    rect.SetEnd( end);
    rect.Move( origin );
    rect.Normalize();
    return rect;
}
Exemple #11
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 );
}
Exemple #12
0
void LIB_TEXT::Rotate()
{
    if( InEditMode() )
    {
        m_rotate = true;
    }
    else
    {
        SetTextAngle( GetTextAngle() == TEXT_ANGLE_VERT ? TEXT_ANGLE_HORIZ : TEXT_ANGLE_VERT );
    }
}
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();
}
void TEXTE_PCB::TransformShapeWithClearanceToPolygonSet(
        SHAPE_POLY_SET& aCornerBuffer, int aClearanceValue, int aError ) const
{
    wxSize size = GetTextSize();

    if( IsMirrored() )
        size.x = -size.x;

    prms.m_cornerBuffer = &aCornerBuffer;
    prms.m_textWidth = GetThickness() + ( 2 * aClearanceValue );
    prms.m_error = aError;
    COLOR4D color = COLOR4D::BLACK;  // not actually used, but needed by DrawGraphicText

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

        for( unsigned ii = 0; ii < strings_list.Count(); ii++ )
        {
            wxString txt = strings_list.Item( ii );
            DrawGraphicText( NULL, NULL, positions[ii], color,
                             txt, GetTextAngle(), size,
                             GetHorizJustify(), GetVertJustify(),
                             GetThickness(), IsItalic(),
                             true, addTextSegmToPoly, &prms );
        }
    }
    else
    {
        DrawGraphicText( NULL, NULL, GetTextPos(), color,
                         GetShownText(), GetTextAngle(), size,
                         GetHorizJustify(), GetVertJustify(),
                         GetThickness(), IsItalic(),
                         true, addTextSegmToPoly, &prms );
    }
}
Exemple #16
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;
}
Exemple #17
0
void QtArc2D::mouseReleaseEvent ( QGraphicsSceneMouseEvent * event )
{
    if (event->button() & Qt::LeftButton && pending_db_save_) 
    {
        // if there is a pending db save, do the save now (this happens at the end of a drag event)
        SetTextLocation(GetTextRadius(),GetTextAngle());

        pending_db_save_ = false;
    }

    // let the base class do it's thing
    QGraphicsItem::mouseReleaseEvent(event);
}
Exemple #18
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;
}
void SCH_FIELD::Plot( PLOTTER* aPlotter )
{
    SCH_COMPONENT* parent = ( SCH_COMPONENT* ) GetParent();

    wxCHECK_RET( parent != NULL && parent->Type() == SCH_COMPONENT_T,
                 wxT( "Cannot plot field with invalid parent." ) );

    COLOR4D color = GetLayerColor( GetLayer() );

    if( !IsVisible() )
        return;

    if( IsVoid() )
        return;

    /* Calculate the text orientation, according to the component
     * orientation/mirror */
    int orient = GetTextAngle();

    if( parent->GetTransform().y1 )  // Rotate component 90 deg.
    {
        if( orient == TEXT_ANGLE_HORIZ )
            orient = TEXT_ANGLE_VERT;
        else
            orient = TEXT_ANGLE_HORIZ;
    }

    /* Calculate the text justification, according to the component
     * orientation/mirror
     * this is a bit complicated due to cumulative calculations:
     * - numerous cases (mirrored or not, rotation)
     * - the DrawGraphicText function recalculate also H and H justifications
     *      according to the text orientation.
     * - When a component is mirrored, the text is not mirrored and
     *   justifications are complicated to calculate
     * so the more easily way is to use no justifications ( Centered text )
     * and use GetBoundaryBox to know the text coordinate considered as centered
     */
    EDA_RECT BoundaryBox = GetBoundingBox();
    EDA_TEXT_HJUSTIFY_T hjustify = GR_TEXT_HJUSTIFY_CENTER;
    EDA_TEXT_VJUSTIFY_T vjustify = GR_TEXT_VJUSTIFY_CENTER;
    wxPoint  textpos = BoundaryBox.Centre();

    int      thickness = GetPenSize();

    aPlotter->Text( textpos, color, GetFullyQualifiedText(), orient, GetTextSize(),
            hjustify, vjustify,
            thickness, IsItalic(), IsBold() );
}
Exemple #20
0
bool LIB_TEXT::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFORM& aTransform ) const
{
    if( aThreshold < 0 )
        aThreshold = 0;

    EDA_TEXT tmp_text( *this );
    tmp_text.SetTextPos( aTransform.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 = ( aTransform.x1 != 0 ) ^ ( GetTextAngle() != 0 );

    tmp_text.SetTextAngle( t1 ? TEXT_ANGLE_HORIZ : TEXT_ANGLE_VERT );
    return tmp_text.TextHitTest( aPosition );
}
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 LIB_FIELD::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
                             void* aData, const TRANSFORM& aTransform )
{
    wxPoint  text_pos;
    COLOR4D  color = IsVisible() ? GetDefaultColor() : GetInvisibleItemColor();
    int      linewidth = GetPenSize();

    text_pos = aTransform.TransformCoordinate( GetTextPos() ) + aOffset;

    wxString text;

    if( aData )
        text = *(wxString*)aData;
    else
        text = m_Text;

    EDA_RECT* clipbox = aPanel? aPanel->GetClipBox() : NULL;

    DrawGraphicText( clipbox, aDC, text_pos, color, text, GetTextAngle(), GetTextSize(),
                     GetHorizJustify(), GetVertJustify(), linewidth, IsItalic(), IsBold() );
}
Exemple #23
0
void LIB_TEXT::calcEdit( const wxPoint& aPosition )
{
    if( m_rotate )
    {
        SetTextAngle( GetTextAngle() == TEXT_ANGLE_VERT ? TEXT_ANGLE_HORIZ : TEXT_ANGLE_VERT );
        m_rotate = false;
    }

    if( m_updateText )
    {
        std::swap( m_Text, m_savedText );
        m_updateText = false;
    }

    if( m_Flags == IS_NEW )
    {
        SetEraseLastDrawItem();
        SetTextPos( aPosition );
    }
    else if( m_Flags == IS_MOVED )
    {
        Move( m_initialPos + aPosition - m_initialCursorPos );
    }
}
double TEXTE_MODULE::GetDrawRotation() const
{
    MODULE* module = (MODULE*) m_Parent;
    double  rotation = GetTextAngle();

    if( module )
        rotation += module->GetOrientation();

    if( m_unlocked )
    {
        NORMALIZE_ANGLE_POS( rotation );
    }
    else
    {
        // Keep angle between -90 .. 90 deg. Otherwise the text is not easy to read
        while( rotation > 900 )
            rotation -= 1800;

        while( rotation < -900 )
            rotation += 1800;
    }

    return rotation;
}
Exemple #25
0
void QtArc2D::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget * /* widget */) 
{
	double level_of_detail = QStyleOptionGraphicsItem::levelOfDetailFromTransform(painter->worldTransform());
  
	DisplayProperties current_properties;

	// @fixme the way radius_properties is defined in the following if statement block will prevent the user from changing the display properties of the radius dimension or the points at run time since the DisplayProperties constructor is used to set these properties
	DisplayProperties radius_properties; 

	if(option->state & QStyle::State_MouseOver && IsSelectable())
	{
		current_properties = GetMouseHoverProperties();
		radius_properties = DisplayProperties(HoverAnnotation);
	} else if (option->state & QStyle::State_Selected) {
		current_properties = GetSelectedProperties();
		radius_properties = DisplayProperties(SelectedAnnotation);
	} else {
		current_properties = GetProperties();
		radius_properties = DisplayProperties(Annotation);
	}
	
	double leader_gap = current_properties.GetLeaderGap()/level_of_detail;
	double leader_extension = current_properties.GetLeaderExtension()/level_of_detail;

	double leader_extension_angle = ((leader_extension/GetRadius()->GetValue())*(180.0/mmcPI))/level_of_detail;
	double leader_gap_angle = ((leader_gap/GetRadius()->GetValue())*(180.0/mmcPI))/level_of_detail;

	double radius = GetRadius()->GetValue();
	QRectF rect(QPointF(GetSCenter()->GetValue()-radius,-GetTCenter()->GetValue()-radius),
 				QPointF(GetSCenter()->GetValue()+radius,-GetTCenter()->GetValue()+radius));

	double angle1 = GetTheta1()->GetValue()*((180.0)/(mmcPI));
	double angle2 = GetTheta2()->GetValue()*((180.0)/(mmcPI));
	double text_angle = GetTextAngle()*((180.0)/(mmcPI));

    // put angle1 and angle2 into a preditable form
    // angle2 > angle1 and angle2 - angle1 < 360.0
    if(angle1 > angle2)
    {
        double temp;
        temp = angle1;
        angle1 = angle2;
        angle2 = temp;
    }
    if(angle2-angle1 >= 360.0)
        angle2 = angle2 - floor((angle2-angle1)/(360.0))*360.0;
    if(text_angle-angle1 >= 360.0)
        text_angle = text_angle - floor((text_angle-angle1)/(360.0))*360.0;
    else if(angle2 - text_angle >= 360.0)
        text_angle = text_angle + floor((angle2-text_angle)/(360.0))*360.0;

	// create the radius dimension if necessary
	// Only display the radius if it is not a free parameter
	// If it is a free parameter, it is not really a constraint and should not be displayed as such
	if( ! radius_->IsFree())
	{
		painter->setPen(radius_properties.GetPen(level_of_detail));
		painter->setBrush(radius_properties.GetBrush());

		QPolygonF radius_arrow = GetArrowPolygon(s_center_->GetValue(),-t_center_->GetValue(),s_center_->GetValue()+radius_->GetValue()*cos(GetTextAngle()),
							   -(t_center_->GetValue()+radius_->GetValue()*sin(GetTextAngle())), 15.0/level_of_detail,12.0/level_of_detail);
		painter->drawPolygon(radius_arrow);

		// extend arc to radius arrow if radius arrow is outside the arc
		if(text_angle < angle1)
		{
			painter->drawArc(rect,(text_angle-leader_extension_angle)*16.0, ((angle1-leader_gap_angle)-(text_angle-leader_extension_angle))*16.0);
		} else if(text_angle > angle2) {
			painter->drawArc(rect,(angle2+leader_gap_angle)*16.0,((text_angle+leader_extension_angle)-(angle2+leader_gap_angle))*16.0);
		}

		// draw a line from the arc center point to the text location in case the text is outside of the arc
		painter->drawLine(QPointF(s_center_->GetValue(),-t_center_->GetValue()),
					      QPointF(s_center_->GetValue()+GetTextRadius()*cos(GetTextAngle()),-(t_center_->GetValue()+GetTextRadius()*sin(GetTextAngle()))));

		// create the line edit widget graphics item
		if(radius_widget_ == 0)
		{
			// @fixme need to make sure the following dyname_cast won't create a pointer that is need used even if this shared_ptr class is freed from memory
			radius_widget_ = new QtArc2DWidget(shared_from_this(),dynamic_cast<QGraphicsItem*>(const_cast<QtArc2D*>(this)));
		}
		radius_widget_->UpdateGeometry(level_of_detail);
	}

	painter->setPen(current_properties.GetPen(level_of_detail));
	painter->setBrush(current_properties.GetBrush());

	// paint the actual arc
	QPainterPath arc_selection_path;
	painter->drawPath(GetArcAndSelectionPath(GetSCenter()->GetValue(), -GetTCenter()->GetValue(), radius, angle1*(mmcPI/180.0), angle2*(mmcPI/180.0), arc_selection_path, level_of_detail));
	current_shape_ = arc_selection_path;
}
void LIB_FIELD::Rotate()
{
    SetTextAngle( GetTextAngle() == TEXT_ANGLE_VERT ? TEXT_ANGLE_HORIZ : TEXT_ANGLE_VERT );
}
Exemple #27
0
void LIB_TEXT::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
                            COLOR4D aColor, GR_DRAWMODE aDrawMode, void* aData,
                            const TRANSFORM& aTransform )
{
    COLOR4D color = GetDefaultColor();

    if( aColor == COLOR4D::UNSPECIFIED )       // Used normal color or selected color
    {
        if( IsSelected() )
            color = GetItemSelectedColor();
    }
    else
    {
        color = aColor;
    }

    GRSetDrawMode( aDC, aDrawMode );

    /* Calculate the text orientation, according to the component
     * orientation/mirror (needed when draw text in schematic)
     */
    int orient = GetTextAngle();

    if( aTransform.y1 )  // Rotate component 90 degrees.
    {
        if( orient == TEXT_ANGLE_HORIZ )
            orient = TEXT_ANGLE_VERT;
        else
            orient = TEXT_ANGLE_HORIZ;
    }

    /* Calculate the text justification, according to the component
     * orientation/mirror this is a bit complicated due to cumulative
     * calculations:
     * - numerous cases (mirrored or not, rotation)
     * - the DrawGraphicText function recalculate also H and H justifications
     *      according to the text orientation.
     * - When a component is mirrored, the text is not mirrored and
     *   justifications are complicated to calculate
     * so the more easily way is to use no justifications ( Centered text )
     * and use GetBoundaryBox to know the text coordinate considered as centered
    */
    EDA_RECT bBox = GetBoundingBox();

    // convert coordinates from draw Y axis to libedit Y axis:
    bBox.RevertYAxis();
    wxPoint txtpos = bBox.Centre();

    // Calculate pos according to mirror/rotation.
    txtpos = aTransform.TransformCoordinate( txtpos ) + aOffset;

    EDA_RECT* clipbox = aPanel? aPanel->GetClipBox() : NULL;
    DrawGraphicText( clipbox, aDC, txtpos, color, GetShownText(), orient, GetTextSize(),
                     GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, GetPenSize(),
                     IsItalic(), IsBold() );


    /* Enable this to draw the bounding box around the text field to validate
     * the bounding box calculations.
     */
#if 0
    // bBox already uses libedit Y axis.
    bBox = aTransform.TransformCoordinate( bBox );
    bBox.Move( aOffset );
    GRRect( clipbox, aDC, bBox, 0, LIGHTMAGENTA );
#endif
}
void QtAngleLine2D::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget * /* widget */)
{
    // @fixme need to handle the case where one of the lines has zero length (make sure there are no divide by zeros)

    double level_of_detail = QStyleOptionGraphicsItem::levelOfDetailFromTransform(painter->worldTransform());

    DisplayProperties current_properties;

    if(option->state & QStyle::State_MouseOver && IsSelectable())
    {
        current_properties = GetMouseHoverProperties();
    } else if (option->state & QStyle::State_Selected) {
        current_properties = GetSelectedProperties();
    } else {
        current_properties = GetProperties();
    }

    painter->setPen(current_properties.GetPen(level_of_detail));
    painter->setBrush(current_properties.GetBrush());

    double leader_gap = current_properties.GetLeaderGap()/level_of_detail;
    double leader_extension = current_properties.GetLeaderExtension()/level_of_detail;

    // first determine the intersection point of the two lines
    double x1 = GetLine1()->GetPoint1()->GetSValue();
    double x2 = GetLine1()->GetPoint2()->GetSValue();
    double x3 = GetLine2()->GetPoint1()->GetSValue();
    double x4 = GetLine2()->GetPoint2()->GetSValue();

    double y1 = GetLine1()->GetPoint1()->GetTValue();
    double y2 = GetLine1()->GetPoint2()->GetTValue();
    double y3 = GetLine2()->GetPoint1()->GetTValue();
    double y4 = GetLine2()->GetPoint2()->GetTValue();

    double denominator = (x1-x2)*(y3-y4)-(x3-x4)*(y1-y2);

    double text_x, text_y;
    double x_center, y_center;
    bool lines_parallel = false;
    double arrow_tip_x1;
    double arrow_tip_x2;
    double arrow_tip_y1;
    double arrow_tip_y2;

    if(denominator == 0.0)
    {
        // Lines are parallel
        lines_parallel = true;

        text_x = text_s_->GetValue();
        text_y = text_t_->GetValue();
    } else {
        // lines do intersect
        // finish calculating the intersection point
        double temp1 = x1*y2-y1*x2;
        double temp2 = x3*y4-x4*y3;

        x_center = (temp1*(x3-x4)-temp2*(x1-x2))/denominator;
        y_center = (temp1*(y3-y4)-temp2*(y1-y2))/denominator;

        text_x = x_center + GetTextRadius()*cos(GetTextAngle());
        text_y = y_center + GetTextRadius()*sin(GetTextAngle());
    }

    if(!lines_parallel)
    {
        // normal case where lines are not parallel
        double line1_theta = atan2(y2-y1, x2-x1);
        double line2_theta = atan2(y4-y3, x4-x3);
        if(line2_theta < line1_theta)
            line2_theta += 2.0*mmcPI;

        double theta;
        bool theta_is_interior;

        if(line2_theta - line1_theta > mmcPI)
        {
            theta_is_interior = false;
            theta = line2_theta - line1_theta - mmcPI;
        } else {
            theta_is_interior = true;
            theta = line2_theta - line1_theta;
        }

        double alpha1 = line1_theta;

        double alpha2 = alpha1 + theta;
        double alpha3 = alpha1 + mmcPI;
        double alpha4 = alpha1 + mmcPI + theta;
        double alpha5 = alpha1 + 2.0*mmcPI;

        double text_theta = GetTextAngle();

        // determine which sector the text is nearest too
        // first increment text_theta so that it is greater then alpha1 and less then alpha5
        if(text_theta < alpha1)
        {
            while (text_theta < alpha1)
                text_theta += 2.0*mmcPI;
        } else if (text_theta > alpha5) {
            while (text_theta > alpha5)
                text_theta -= 2.0*mmcPI;
        }

        double arrow_arc_theta1;
        double arrow_arc_theta2;
        if(IsInteriorAngle() && theta_is_interior || !IsInteriorAngle() && !theta_is_interior)
        {
            // either sector 1 or sector 3 for an interior angle
            double sector_1_delta = fabs((alpha1+alpha2)*0.5-text_theta);
            double sector_3_delta = fabs((alpha3+alpha4)*0.5-text_theta);

            if(sector_1_delta < sector_3_delta)
            {
                arrow_arc_theta1 = alpha1;
                arrow_arc_theta2 = alpha2;
            } else {
                arrow_arc_theta1 = alpha3;
                arrow_arc_theta2 = alpha4;
            }

            // theta1 correspnds to line1
            arrow_tip_x1 = x_center + GetTextRadius()*cos(arrow_arc_theta1);
            arrow_tip_y1 = y_center + GetTextRadius()*sin(arrow_arc_theta1);

            arrow_tip_x2 = x_center + GetTextRadius()*cos(arrow_arc_theta2);
            arrow_tip_y2 = y_center + GetTextRadius()*sin(arrow_arc_theta2);

        } else {
            // either sector 2 or sector 4 for an exterior angle
            double sector_2_delta = fabs((alpha2+alpha3)*0.5-text_theta);
            double sector_4_delta = fabs((alpha4+alpha5)*0.5-text_theta);

            if(sector_2_delta < sector_4_delta)
            {
                arrow_arc_theta1 = alpha2;
                arrow_arc_theta2 = alpha3;
            } else {
                arrow_arc_theta1 = alpha4;
                arrow_arc_theta2 = alpha5;
            }

            // theta1 correspnds to line2
            arrow_tip_x2 = x_center + GetTextRadius()*cos(arrow_arc_theta1);
            arrow_tip_y2 = y_center + GetTextRadius()*sin(arrow_arc_theta1);

            arrow_tip_x1 = x_center + GetTextRadius()*cos(arrow_arc_theta2);
            arrow_tip_y1 = y_center + GetTextRadius()*sin(arrow_arc_theta2);
        }

        // display the arrow arc
        QPainterPath selection_path;
        QPainterPath arrow_arc = GetArcArrowPathAndSelectionPath(x_center, -y_center, GetTextRadius(),arrow_arc_theta1,arrow_arc_theta2,15.0/level_of_detail,12.0/level_of_detail,selection_path,level_of_detail);
        painter->drawPath(arrow_arc);
        current_shape_ = selection_path;

        // draw an additional arc to the text if text is outside of the arrow arc
        QRectF rect(QPointF(x_center-GetTextRadius(),-y_center-GetTextRadius()),
                    QPointF(x_center+GetTextRadius(),-y_center+GetTextRadius()));
        if(text_theta < arrow_arc_theta1)
            painter->drawArc(rect,(text_theta)*(180.0/mmcPI)*16.0,(arrow_arc_theta1-text_theta)*(180.0/mmcPI)*16.0);
        else if (text_theta > arrow_arc_theta2)
            painter->drawArc(rect,(arrow_arc_theta2)*(180.0/mmcPI)*16.0,((text_theta)-(arrow_arc_theta2))*(180.0/mmcPI)*16.0);

        // display the editable text
        // create the line edit widget graphics item
        if(angle_widget_ == 0)
        {
            // @fixme need to make sure the following dyname_cast won't create a pointer that is need used even if this shared_ptr class is freed from memory
            angle_widget_ = new QtAngleLine2DWidget(shared_from_this(),dynamic_cast<QGraphicsItem*>(const_cast<QtAngleLine2D*>(this)));
        }
        angle_widget_->UpdateGeometry(text_x, text_y, level_of_detail);

        // create leader for line1 if necessary
        double delta1, delta2;
        double line1_length = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
        delta1 = sqrt((arrow_tip_x1-x1)*(arrow_tip_x1-x1)+(arrow_tip_y1-y1)*(arrow_tip_y1-y1));
        delta2 = sqrt((arrow_tip_x1-x2)*(arrow_tip_x1-x2)+(arrow_tip_y1-y2)*(arrow_tip_y1-y2));
        if(delta1 > line1_length && delta1 > delta2)
        {
            double direction_x = arrow_tip_x1-x1;
            double direction_y = arrow_tip_y1-y1;
            double direction_length = sqrt(direction_x*direction_x + direction_y*direction_y);
            direction_x = direction_x / direction_length;
            direction_y = direction_y / direction_length;

            painter->drawLine(QPointF(x2+leader_gap*direction_x,-(y2+leader_gap*direction_y)),
                              QPointF(x1+(delta1+leader_extension)*direction_x,-(y1+(delta1+leader_extension)*direction_y)));
        } else if (delta2 > line1_length) {
            double direction_x = arrow_tip_x1-x2;
            double direction_y = arrow_tip_y1-y2;
            double direction_length = sqrt(direction_x*direction_x + direction_y*direction_y);
            direction_x = direction_x / direction_length;
            direction_y = direction_y / direction_length;

            painter->drawLine(QPointF(x1+leader_gap*direction_x,-(y1+leader_gap*direction_y)),
                              QPointF(x2+(delta2+leader_extension)*direction_x,-(y2+(delta2+leader_extension)*direction_y)));
        }

        // create leader for line2 if necessary
        double line2_length = sqrt((x3-x4)*(x3-x4)+(y3-y4)*(y3-y4));
        delta1 = sqrt((arrow_tip_x2-x3)*(arrow_tip_x2-x3)+(arrow_tip_y2-y3)*(arrow_tip_y2-y3));
        delta2 = sqrt((arrow_tip_x2-x4)*(arrow_tip_x2-x4)+(arrow_tip_y2-y4)*(arrow_tip_y2-y4));
        if(delta1 > line2_length && delta1 > delta2)
        {
            double direction_x = arrow_tip_x2-x3;
            double direction_y = arrow_tip_y2-y3;
            double direction_length = sqrt(direction_x*direction_x + direction_y*direction_y);
            direction_x = direction_x / direction_length;
            direction_y = direction_y / direction_length;

            painter->drawLine(QPointF(x4+leader_gap*direction_x,-(y4+leader_gap*direction_y)),
                              QPointF(x3+(delta1+leader_extension)*direction_x,-(y3+(delta1+leader_extension)*direction_y)));
        } else if (delta2 > line2_length) {
            double direction_x = arrow_tip_x2-x4;
            double direction_y = arrow_tip_y2-y4;
            double direction_length = sqrt(direction_x*direction_x + direction_y*direction_y);
            direction_x = direction_x / direction_length;
            direction_y = direction_y / direction_length;

            painter->drawLine(QPointF(x3+leader_gap*direction_x,-(y3+leader_gap*direction_y)),
                              QPointF(x4+(delta2+leader_extension)*direction_x,-(y4+(delta2+leader_extension)*direction_y)));
        }

    } else {
        // the case where the lines are parallel

        // display an arrow to the center point of each of the lines
        QPainterPath selection_path;

        QPolygonF arrow1 = GetArrowPolygonAndSelectionPath(text_x, -text_y, 0.5*(x1+x2), -0.5*(y1+y2),15.0/level_of_detail,12.0/level_of_detail,selection_path,level_of_detail);
        painter->drawPolygon(arrow1);
        current_shape_ = selection_path;

        QPolygonF arrow2 = GetArrowPolygonAndSelectionPath(text_x, -text_y, 0.5*(x3+x4), -0.5*(y3+y4),15.0/level_of_detail,12.0/level_of_detail,selection_path,level_of_detail);
        painter->drawPolygon(arrow2);
        current_shape_.addPath(selection_path);

        // display the editable text
        // create the line edit widget graphics item
        if(angle_widget_ == 0)
        {
            // @fixme need to make sure the following dyname_cast won't create a pointer that is need used even if this shared_ptr class is freed from memory
            angle_widget_ = new QtAngleLine2DWidget(shared_from_this(),dynamic_cast<QGraphicsItem*>(const_cast<QtAngleLine2D*>(this)));
        }
        angle_widget_->UpdateGeometry(text_x, text_y, level_of_detail);

    } // if(!lines_parallel)

}
void SCH_FIELD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
                      GR_DRAWMODE aDrawMode, COLOR4D aColor )
{
    int            orient;
    COLOR4D        color;
    wxPoint        textpos;
    SCH_COMPONENT* parentComponent = (SCH_COMPONENT*) m_Parent;
    int            lineWidth = GetThickness();

    if( lineWidth == 0 )   // Use default values for pen size
    {
        if( IsBold() )
            lineWidth = GetPenSizeForBold( GetTextWidth() );
        else
            lineWidth = GetDefaultLineThickness();
    }

    // Clip pen size for small texts:
    lineWidth = Clamp_Text_PenSize( lineWidth, GetTextSize(), IsBold() );

    if( ( !IsVisible() && !m_forceVisible) || IsVoid() )
        return;

    GRSetDrawMode( aDC, aDrawMode );

    // Calculate the text orientation according to the component orientation.
    orient = GetTextAngle();

    if( parentComponent->GetTransform().y1 )  // Rotate component 90 degrees.
    {
        if( orient == TEXT_ANGLE_HORIZ )
            orient = TEXT_ANGLE_VERT;
        else
            orient = TEXT_ANGLE_HORIZ;
    }

    /* Calculate the text justification, according to the component
     * orientation/mirror this is a bit complicated due to cumulative
     * calculations:
     * - numerous cases (mirrored or not, rotation)
     * - the DrawGraphicText function recalculate also H and H justifications
     *      according to the text orientation.
     * - When a component is mirrored, the text is not mirrored and
     *   justifications are complicated to calculate
     * so the more easily way is to use no justifications ( Centered text )
     * and use GetBoundaryBox to know the text coordinate considered as centered
     */
    EDA_RECT boundaryBox = GetBoundingBox();
    textpos = boundaryBox.Centre() + aOffset;

    if( m_forceVisible )
    {
        color = COLOR4D( DARKGRAY );
    }
    else
    {
        if( m_id == REFERENCE )
            color = GetLayerColor( LAYER_REFERENCEPART );
        else if( m_id == VALUE )
            color = GetLayerColor( LAYER_VALUEPART );
        else
            color = GetLayerColor( LAYER_FIELDS );
    }

    EDA_RECT* clipbox = aPanel ? aPanel->GetClipBox() : NULL;
    DrawGraphicText( clipbox, aDC, textpos, color, GetFullyQualifiedText(), orient, GetTextSize(),
                     GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
                     lineWidth, IsItalic(), IsBold() );

    // While moving: don't loose visual contact to which component this label belongs.
    if ( IsWireImage() )
    {
        const wxPoint origin = parentComponent->GetPosition();
        textpos  = GetTextPos() - origin;
        textpos  = parentComponent->GetScreenCoord( textpos );
        textpos += parentComponent->GetPosition();
        GRLine( clipbox, aDC, origin, textpos, 2, DARKGRAY );
    }

    /* Enable this to draw the bounding box around the text field to validate
     * the bounding box calculations.
     */
#if 0

    // Draw boundary box:
    GRRect( aPanel->GetClipBox(), aDC, boundaryBox, 0, BROWN );

    // Draw the text anchor point

    /* Calculate the text position, according to the component
     * orientation/mirror */
    textpos  = m_Pos - parentComponent->GetPosition();
    textpos  = parentComponent->GetScreenCoord( textpos );
    textpos += parentComponent->GetPosition();
    const int len = 10;
    GRLine( clipbox, aDC,
            textpos.x - len, textpos.y, textpos.x + len, textpos.y, 0, BLUE );
    GRLine( clipbox, aDC,
            textpos.x, textpos.y - len, textpos.x, textpos.y + len, 0, BLUE );
#endif
}