/**
 * Function PLOTTER::Text
 *  same as DrawGraphicText, but plot graphic text insteed of draw it
 *  @param aPos = text position (according to aH_justify, aV_justify)
 *  @param aColor (COLOR4D) = text color
 *  @param aText = text to draw
 *  @param aOrient = angle in 0.1 degree
 *  @param aSize = text size (size.x or size.y can be < 0 for mirrored texts)
 *  @param aH_justify = horizontal justification (Left, center, right)
 *  @param aV_justify = vertical justification (bottom, center, top)
 *  @param aWidth = line width (pen width) (default = 0)
 *      if width < 0 : draw segments in sketch mode, width = abs(width)
 *      Use a value min(aSize.x, aSize.y) / 5 for a bold text
 *  @param aItalic = true to simulate an italic font
 *  @param aBold = true to use a bold font Useful only with default width value (aWidth = 0)
 *  @param aMultilineAllowed = true to plot text as multiline, otherwise single line
 */
void PLOTTER::Text( const wxPoint&              aPos,
                    const COLOR4D               aColor,
                    const wxString&             aText,
                    double                      aOrient,
                    const wxSize&               aSize,
                    enum EDA_TEXT_HJUSTIFY_T    aH_justify,
                    enum EDA_TEXT_VJUSTIFY_T    aV_justify,
                    int                         aWidth,
                    bool                        aItalic,
                    bool                        aBold,
                    bool                        aMultilineAllowed,
                    void*                       aData )
{
    int textPensize = aWidth;

    if( textPensize == 0 && aBold ) // Use default values if aWidth == 0
        textPensize = GetPenSizeForBold( std::min( aSize.x, aSize.y ) );

    if( textPensize >= 0 )
        textPensize = Clamp_Text_PenSize( aWidth, aSize, aBold );
    else
        textPensize = -Clamp_Text_PenSize( -aWidth, aSize, aBold );

    SetCurrentLineWidth( textPensize, aData );

    SetColor( aColor );

    DrawGraphicText( NULL, NULL, aPos, aColor, aText,
                     aOrient, aSize,
                     aH_justify, aV_justify,
                     textPensize, aItalic, aBold, NULL, this );

    if( aWidth != textPensize )
        SetCurrentLineWidth( aWidth, aData );
}
Esempio n. 2
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;
}
Esempio n. 3
0
EDA_RECT SCH_FIELD::GetBoundingBox() const
{
    SCH_COMPONENT* parentComponent = (SCH_COMPONENT*) m_Parent;
    int linewidth = ( m_Thickness == 0 ) ? GetDefaultLineThickness() : m_Thickness;

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

    // Calculate the text bounding box:
    EDA_RECT rect;

    // set USE_TEXT_JUSTIFY_INITIAL_BEHAVIOR to 0 to use
    // a justification relative to the text itself
    // i.e. justification relative to an horizontal text
    // or to 1 to keep the initial behavior
#if (USE_TEXT_JUSTIFY_INITIAL_BEHAVIOR == 1 )
    if( m_Orient == TEXT_ORIENT_VERT )
    {
        // For vertical texts, exchange the horizontal and the vertical justification
        // The idea is to keep the justification always left or top for instance,
        // no matter the text orientation
        SCH_FIELD text( *this );    // Make a local copy to swap justifications
                                    // because GetBoundingBox() is const
        int tmp = (int)text.m_VJustify;
        NEGATE( tmp );
        text.m_VJustify  = (EDA_TEXT_VJUSTIFY_T)text.m_HJustify;
        text.m_HJustify = (EDA_TEXT_HJUSTIFY_T)tmp;
        rect = text.GetTextBox( -1, linewidth );
    }
    else
#endif
        rect = GetTextBox( -1, linewidth );

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

    // Due to the Y axis direction, we must mirror the bounding box,
    // relative to the text position:
    begin.y -= pos.y;
    end.y -= pos.y;
    NEGATE( begin.y );
    NEGATE( end.y );
    begin.y += pos.y;
    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;
}
Esempio n. 4
0
void SCH_TEXT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& aOffset,
                     GR_DRAWMODE DrawMode, EDA_COLOR_T Color )
{
    EDA_COLOR_T color;
    int         linewidth = ( m_Thickness == 0 ) ? GetDefaultLineThickness() : m_Thickness;

    linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );

    if( Color >= 0 )
        color = Color;
    else
        color = ReturnLayerColor( m_Layer );

    GRSetDrawMode( DC, DrawMode );

    wxPoint text_offset = aOffset + GetSchematicTextOffset();
    EXCHG( linewidth, m_Thickness );            // Set the minimum width
    EDA_TEXT::Draw( panel, DC, text_offset, color, DrawMode, FILLED, UNSPECIFIED_COLOR );
    EXCHG( linewidth, m_Thickness );            // set initial value

    if( m_isDangling )
        DrawDanglingSymbol( panel, DC, m_Pos + aOffset, color );

    // Enable these line to draw the bounding box (debug tests purposes only)
#if 0
    {
        EDA_RECT BoundaryBox = GetBoundingBox();
        GRRect( panel->GetClipBox(), DC, BoundaryBox, 0, BROWN );
    }
#endif
}
Esempio n. 5
0
void DIALOG_DIMENSION_EDITOR::OnOKClick( wxCommandEvent& event )
{
    if( m_DC )     // Delete old text.
    {
        CurrentDimension->Draw( m_Parent->GetCanvas(), m_DC, GR_XOR );
    }

    m_Parent->SaveCopyInUndoList(CurrentDimension, UR_CHANGED);

    if( m_Name->GetValue() != wxEmptyString )
    {
        CurrentDimension->SetText( m_Name->GetValue() );
    }

    wxString msg;

    // Get new size value:
    msg = m_TxtSizeXCtrl->GetValue();
    CurrentDimension->Text().SetWidth( ReturnValueFromString( g_UserUnit, msg ) );
    msg = m_TxtSizeYCtrl->GetValue();
    CurrentDimension->Text().SetHeight( ReturnValueFromString( g_UserUnit, msg ) );

    // Get new position value:
    // It will be copied later in dimension, because
    msg = m_textCtrlPosX->GetValue();
    wxPoint pos;
    pos.x = ReturnValueFromString( g_UserUnit, msg );
    msg = m_textCtrlPosY->GetValue();
    pos.y = ReturnValueFromString( g_UserUnit, msg );
    CurrentDimension->Text().SetTextPosition( pos );

    // Get new line thickness value:
    msg = m_TxtWidthCtrl->GetValue();
    int width = ReturnValueFromString( g_UserUnit, msg );
    int maxthickness = Clamp_Text_PenSize( width, CurrentDimension->Text().GetSize() );

    if( width > maxthickness )
    {
        DisplayError( NULL,
                      _( "The text thickness is too large for the text size. It will be clamped") );
        width = maxthickness;
    }

    CurrentDimension->SetWidth( width );
    CurrentDimension->Text().SetThickness( width );

    CurrentDimension->Text().SetMirrored( ( m_rbMirror->GetSelection() == 1 ) ? true : false );

    CurrentDimension->SetLayer( m_SelLayerBox->GetLayerSelection() );

    if( m_DC )     // Display new text
    {
        CurrentDimension->Draw( m_Parent->GetCanvas(), m_DC, GR_OR );
    }

    m_Parent->OnModify();
    EndModal( 1 );
}
void LIB_FIELD::drawGraphic( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
                             EDA_COLOR_T aColor, GR_DRAWMODE aDrawMode, void* aData,
                             const TRANSFORM& aTransform )
{
    wxPoint  text_pos;
    int      color;
    int      linewidth = GetPenSize();

    if( m_Bold )
        linewidth = GetPenSizeForBold( m_Size.x );
    else
        linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );

    if( ( m_Attributs & TEXT_NO_VISIBLE ) && ( aColor < 0 ) )
    {
        color = GetInvisibleItemColor();
    }
    else if( IsSelected() && ( aColor < 0 ) )
    {
        color = GetItemSelectedColor();
    }
    else
    {
        color = aColor;
    }

    if( color < 0 )
        color = GetDefaultColor();

    text_pos = aTransform.TransformCoordinate( m_Pos ) + aOffset;

    wxString text;

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

    GRSetDrawMode( aDC, aDrawMode );
    EDA_RECT* clipbox = aPanel? aPanel->GetClipBox() : NULL;
    DrawGraphicText( clipbox, aDC, text_pos, (EDA_COLOR_T) color, text, m_Orient, m_Size,
                     m_HJustify, m_VJustify, linewidth, m_Italic, m_Bold );

    /* Set to one (1) to draw bounding box around field text to validate
     * bounding box calculation. */
#if 0
    EDA_RECT bBox = GetBoundingBox();
    EDA_RECT grBox;
    grBox.SetOrigin( aTransform.TransformCoordinate( bBox.GetOrigin() ) );
    grBox.SetEnd( aTransform.TransformCoordinate( bBox.GetEnd() ) );
    grBox.Move( aOffset );
    GRRect( clipbox, aDC, grBox, 0, LIGHTMAGENTA );
#endif
}
Esempio n. 7
0
DIMENSION* PCB_EDIT_FRAME::EditDimension( DIMENSION* aDimension, wxDC* aDC )
{
    wxPoint pos;

    if( aDimension == NULL )
    {
        status_dimension = 1;
        pos = GetCrossHairPosition();

        aDimension = new DIMENSION( GetBoard() );
        aDimension->SetFlags( IS_NEW );
        aDimension->SetLayer( GetActiveLayer() );
        aDimension->SetOrigin( pos );
        aDimension->SetEnd( pos );

        aDimension->Text().SetSize( GetBoard()->GetDesignSettings().m_PcbTextSize );
        int width = GetBoard()->GetDesignSettings().m_PcbTextWidth;
        int maxthickness = Clamp_Text_PenSize(width, aDimension->Text().GetSize() );

        if( width > maxthickness )
        {
            width = maxthickness;
        }

        aDimension->Text().SetThickness( width );
        aDimension->SetWidth( width );
        aDimension->AdjustDimensionDetails();
        aDimension->Draw( m_canvas, aDC, GR_XOR );

        m_canvas->SetMouseCapture( BuildDimension, AbortBuildDimension );
        return aDimension;
    }

    // Dimension != NULL
    if( status_dimension == 1 )
    {
        status_dimension = 2;
        return aDimension;
    }

    aDimension->Draw( m_canvas, aDC, GR_OR );
    aDimension->ClearFlags();

    /* ADD this new item in list */
    GetBoard()->Add( aDimension );

    // Add store it in undo/redo list
    SaveCopyInUndoList( aDimension, UR_NEW );

    OnModify();
    m_canvas->SetMouseCapture( NULL, NULL );

    return NULL;
}
const EDA_RECT SCH_FIELD::GetBoundingBox() const
{
    SCH_COMPONENT* parentComponent = (SCH_COMPONENT*) m_Parent;
    int linewidth = ( m_Thickness == 0 ) ? GetDefaultLineThickness() : m_Thickness;

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

    // 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 = m_Pos - origin;
    wxPoint begin = rect.GetOrigin() - origin;
    wxPoint end = rect.GetEnd() - origin;
    RotatePoint( &begin, pos, m_Orient );
    RotatePoint( &end, pos, m_Orient );

    // Due to the Y axis direction, we must mirror the bounding box,
    // relative to the text position:
    begin.y -= pos.y;
    end.y -= pos.y;
    NEGATE( begin.y );
    NEGATE( end.y );
    begin.y += pos.y;
    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;
}
Esempio n. 9
0
int LIB_TEXT::GetPenSize() const
{
    int pensize = GetThickness();

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

    // Clip pen size for small texts:
    pensize = Clamp_Text_PenSize( pensize, GetTextSize(), IsBold() );
    return pensize;
}
Esempio n. 10
0
int SCH_FIELD::GetPenSize() const
{
    int pensize = m_Thickness;

    if( pensize == 0 )   // Use default values for pen size
    {
        if( m_Bold  )
            pensize = GetPenSizeForBold( m_Size.x );
        else
            pensize = GetDefaultLineThickness();
    }

    // Clip pen size for small texts:
    pensize = Clamp_Text_PenSize( pensize, m_Size, m_Bold );
    return pensize;
}
Esempio n. 11
0
wxPoint SCH_GLOBALLABEL::GetSchematicTextOffset() const
{
    wxPoint text_offset;
    int     width = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;

    width = Clamp_Text_PenSize( width, m_Size, m_Bold );
    int     HalfSize = m_Size.x / 2;
    int     offset   = width;

    switch( m_shape )
    {
    case NET_INPUT:
    case NET_BIDI:
    case NET_TRISTATE:
        offset += HalfSize;
        break;

    case NET_OUTPUT:
    case NET_UNSPECIFIED:
        offset += TXTMARGE;
        break;

    default:
        break;
    }

    switch( m_schematicOrientation )
    {
    case 0:             /* Orientation horiz normal */
        text_offset.x -= offset;
        break;

    case 1:             /* Orientation vert UP */
        text_offset.y -= offset;
        break;

    case 2:             /* Orientation horiz inverse */
        text_offset.x += offset;
        break;

    case 3:             /* Orientation vert BOTTOM */
        text_offset.y += offset;
        break;
    }

    return text_offset;
}
Esempio n. 12
0
void SCH_TEXT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& aOffset )
{
    COLOR4D     color = GetLayerColor( m_Layer );
    int         linewidth = GetThickness() == 0 ? GetDefaultLineThickness() : GetThickness();
    EDA_RECT*   clipbox = panel? panel->GetClipBox() : NULL;

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

    wxPoint text_offset = aOffset + GetSchematicTextOffset();

    int savedWidth = GetThickness();
    SetThickness( linewidth );              // Set the minimum width

    EDA_TEXT::Draw( clipbox, DC, text_offset, color, GR_DEFAULT_DRAWMODE );

    SetThickness( savedWidth );
}
Esempio n. 13
0
void SCH_GLOBALLABEL::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& aOffset )
{
    static std::vector <wxPoint> Poly;
    COLOR4D color = GetLayerColor( m_Layer );
    wxPoint text_offset = aOffset + GetSchematicTextOffset();

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

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

    int save_width = GetThickness();
    SetThickness( linewidth );

    EDA_RECT* clipbox = panel? panel->GetClipBox() : NULL;
    EDA_TEXT::Draw( clipbox, DC, text_offset, color, GR_DEFAULT_DRAWMODE );

    SetThickness( save_width );   // restore initial value

    CreateGraphicShape( Poly, GetTextPos() + aOffset );
    GRPoly( clipbox, DC, Poly.size(), &Poly[0], 0, linewidth, color, color );
}
Esempio n. 14
0
void SCH_HIERLABEL::Draw( EDA_DRAW_PANEL* panel,
                          wxDC*           DC,
                          const wxPoint&  offset,
                          GR_DRAWMODE     DrawMode,
                          EDA_COLOR_T     Color )
{
    static std::vector <wxPoint> Poly;
    EDA_COLOR_T color;
    int         linewidth = m_Thickness == 0 ?
                            GetDefaultLineThickness() : m_Thickness;
    EDA_RECT* clipbox = panel? panel->GetClipBox() : NULL;

    linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );

    if( Color >= 0 )
        color = Color;
    else
        color = GetLayerColor( m_Layer );

    GRSetDrawMode( DC, DrawMode );

    std::swap( linewidth, m_Thickness );            // Set the minimum width
    wxPoint text_offset = offset + GetSchematicTextOffset();
    EDA_TEXT::Draw( clipbox, DC, text_offset, color, DrawMode, FILLED, UNSPECIFIED_COLOR );
    std::swap( linewidth, m_Thickness );            // set initial value

    CreateGraphicShape( Poly, m_Pos + offset );
    GRPoly( clipbox, DC, Poly.size(), &Poly[0], 0, linewidth, color, color );

    if( m_isDangling && panel )
        DrawDanglingSymbol( panel, DC, m_Pos + offset, color );

    // Enable these line to draw the bounding box (debug tests purposes only)
#if 0
    {
        EDA_RECT BoundaryBox = GetBoundingBox();
        GRRect( clipbox, DC, BoundaryBox, 0, BROWN );
    }
#endif
}
/* Add a new graphical text to the active module (footprint)
 *  Note there always are 2 mandatory texts: reference and value.
 *  New texts have the member TEXTE_MODULE.GetType() set to TEXT_is_DIVERS
 */
TEXTE_MODULE* FOOTPRINT_EDIT_FRAME::CreateTextModule( MODULE* aModule, wxDC* aDC )
{
    TEXTE_MODULE* text = new TEXTE_MODULE( aModule );

    text->SetFlags( IS_NEW );

    GetDesignSettings().m_ModuleTextWidth = Clamp_Text_PenSize( GetDesignSettings().m_ModuleTextWidth,
            std::min( GetDesignSettings().m_ModuleTextSize.x, GetDesignSettings().m_ModuleTextSize.y ), true );
    text->SetTextSize( GetDesignSettings().m_ModuleTextSize );
    text->SetThickness( GetDesignSettings().m_ModuleTextWidth );
    text->SetPosition( GetCrossHairPosition() );

    if( LSET::AllTechMask().test( GetActiveLayer() ) )    // i.e. a possible layer for a text
        text->SetLayer( GetActiveLayer() );

    InstallTextModOptionsFrame( text, NULL );

    m_canvas->MoveCursorToCrossHair();

    if( text->GetText().IsEmpty() )
    {
        delete text;
        return NULL;
    }

    // Add the new text object to the beginning of the footprint draw list.
    if( aModule )
        aModule->GraphicalItems().PushFront( text );

    text->ClearFlags();

    if( aDC )
        text->Draw( m_canvas, aDC, GR_OR );

    SetMsgPanel( text );

    return text;
}
Esempio n. 16
0
EDA_RECT SCH_TEXT::GetBoundingBox() const
{
    // We must pass the effective text thickness to GetTextBox
    // when calculating the bounding box
    int linewidth = ( m_Thickness == 0 ) ? GetDefaultLineThickness() : m_Thickness;

    linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );

    EDA_RECT rect = GetTextBox( -1, linewidth );

    if( m_Orient )                          // Rotate rect
    {
        wxPoint pos = rect.GetOrigin();
        wxPoint end = rect.GetEnd();
        RotatePoint( &pos, m_Pos, m_Orient );
        RotatePoint( &end, m_Pos, m_Orient );
        rect.SetOrigin( pos );
        rect.SetEnd( end );
    }

    rect.Normalize();
    return rect;
}
Esempio n. 17
0
wxPoint SCH_GLOBALLABEL::GetSchematicTextOffset() const
{
    wxPoint text_offset;
    int     width = GetThickness() == 0 ? GetDefaultLineThickness() : GetThickness();

    width = Clamp_Text_PenSize( width, GetTextSize(), IsBold() );
    int     halfSize = GetTextWidth() / 2;
    int     offset   = width;

    switch( m_shape )
    {
    case NET_INPUT:
    case NET_BIDI:
    case NET_TRISTATE:
        offset += halfSize;
        break;

    case NET_OUTPUT:
    case NET_UNSPECIFIED:
        offset += TXT_MARGIN;
        break;

    default:
        break;
    }

    switch( GetLabelSpinStyle() )
    {
    default:
    case 0: text_offset.x -= offset; break;    // Orientation horiz normal
    case 1: text_offset.y -= offset; break;    // Orientation vert UP
    case 2: text_offset.x += offset; break;    // Orientation horiz inverse
    case 3: text_offset.y += offset; break;    // Orientation vert BOTTOM
    }

    return text_offset;
}
Esempio n. 18
0
void SCH_FIELD::Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
                      const wxPoint& offset, GR_DRAWMODE DrawMode, EDA_COLOR_T Color )
{
    int            orient;
    EDA_COLOR_T    color;
    wxPoint        textpos;
    SCH_COMPONENT* parentComponent = (SCH_COMPONENT*) m_Parent;
    int            LineWidth = m_Thickness;

    if( LineWidth == 0 )   // Use default values for pen size
    {
        if( m_Bold  )
            LineWidth = GetPenSizeForBold( m_Size.x );
        else
            LineWidth = GetDefaultLineThickness();
    }


    // Clip pen size for small texts:
    LineWidth = Clamp_Text_PenSize( LineWidth, m_Size, m_Bold );

    if( ((m_Attributs & TEXT_NO_VISIBLE) && !m_forceVisible) || IsVoid() )
        return;

    GRSetDrawMode( DC, DrawMode );

    // Calculate the text orientation according to the component orientation.
    orient = m_Orient;

    if( parentComponent->GetTransform().y1 )  // Rotate component 90 degrees.
    {
        if( orient == TEXT_ORIENT_HORIZ )
            orient = TEXT_ORIENT_VERT;
        else
            orient = TEXT_ORIENT_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();

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

    DrawGraphicText( panel, DC, textpos, color, GetText(), orient, m_Size,
                     GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
                     LineWidth, m_Italic, m_Bold );

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

    // Draw boundary box:
    GRRect( panel->GetClipBox(), DC, 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( panel->GetClipBox(), DC,
            textpos.x - len, textpos.y, textpos.x + len, textpos.y, 0, BLUE );
    GRLine( panel->GetClipBox(), DC,
            textpos.x, textpos.y - len, textpos.x, textpos.y + len, 0, BLUE );
#endif
}
bool DIALOG_TEXT_PROPERTIES::TransferDataFromWindow()
{
    if( !DIALOG_TEXT_PROPERTIES_BASE::TransferDataFromWindow() )
        return false;

    if( !m_textWidth.Validate( TEXTS_MIN_SIZE, TEXTS_MAX_SIZE )
        || !m_textHeight.Validate( TEXTS_MIN_SIZE, TEXTS_MAX_SIZE ) )
        return false;

    BOARD_COMMIT commit( m_Parent );
    commit.Modify( m_item );

    // If no other command in progress, prepare undo command
    // (for a command in progress, will be made later, at the completion of command)
    bool pushCommit = ( m_item->GetEditFlags() == 0 );

    /* set flag in edit to force undo/redo/abort proper operation,
     * and avoid new calls to SaveCopyInUndoList for the same text
     * this can occurs when a text is moved, and then rotated, edited ..
    */
    if( !pushCommit )
        m_item->SetFlags( IN_EDIT );

    // Set the new text content
    if( m_SingleLineText->IsShown() )
    {
        if( !m_SingleLineText->GetValue().IsEmpty() )
            m_edaText->SetText( m_SingleLineText->GetValue() );
    }
    else if( m_MultiLineText->IsShown() )
    {
        if( !m_MultiLineText->GetValue().IsEmpty() )
            m_edaText->SetText( m_MultiLineText->GetValue() );
    }
    else if( m_DimensionText->IsShown() )
    {
        if( !m_DimensionText->GetValue().IsEmpty() )
            m_edaText->SetText( m_DimensionText->GetValue() );

        DIMENSION* dimension = (DIMENSION*) m_item;

        switch( m_DimensionUnitsOpt->GetSelection() )
        {
        case 0: dimension->SetUnits( INCHES, false );      break;
        case 1: dimension->SetUnits( INCHES, true );       break;
        case 2: dimension->SetUnits( MILLIMETRES, false ); break;
        default: break;
        }
    }

    m_item->SetLayer( ToLAYER_ID( m_LayerSelectionCtrl->GetLayerSelection() ) );

    m_edaText->SetTextSize( wxSize( m_textWidth.GetValue(), m_textHeight.GetValue() ) );
    m_edaText->SetThickness( m_thickness.GetValue() );
    m_edaText->SetTextPos( wxPoint( m_posX.GetValue(), m_posY.GetValue() ) );

    if( m_modText )
        m_modText->SetLocalCoord();

    // Test for acceptable values for thickness and size and clamp if fails
    int maxthickness = Clamp_Text_PenSize( m_edaText->GetThickness(), m_edaText->GetTextSize() );

    if( m_edaText->GetThickness() > maxthickness )
    {
        DisplayError( this, _( "The text thickness is too large for the text size.\n"
                               "It will be clamped." ) );
        m_edaText->SetThickness( maxthickness );
    }

    m_edaText->SetVisible( m_Visible->GetValue() );
    m_edaText->SetItalic( m_Italic->GetValue() );
    m_edaText->SetTextAngle( KiROUND( m_OrientValue * 10.0 ) );
    m_edaText->SetMirrored( m_Mirrored->GetValue() );

    if( m_modText )
        m_modText->SetKeepUpright( m_KeepUpright->GetValue() );

    switch( m_JustifyChoice->GetSelection() )
    {
    case 0: m_edaText->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );   break;
    case 1: m_edaText->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER ); break;
    case 2: m_edaText->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );  break;
    default: break;
    }

    m_Parent->Refresh();

    if( pushCommit )
        commit.Push( _( "Change text properties" ) );

    return true;
}
Esempio n. 20
0
/**
 * Function DrawGraphicText
 * Draw a graphic text (like module texts)
 *  @param aClipBox = the clipping rect, or NULL if no clipping
 *  @param aDC = the current Device Context. NULL if draw within a 3D GL Canvas
 *  @param aPos = text position (according to h_justify, v_justify)
 *  @param aColor (enum EDA_COLOR_T) = text color
 *  @param aText = text to draw
 *  @param aOrient = angle in 0.1 degree
 *  @param aSize = text size (size.x or size.y can be < 0 for mirrored texts)
 *  @param aH_justify = horizontal justification (Left, center, right)
 *  @param aV_justify = vertical justification (bottom, center, top)
 *  @param aWidth = line width (pen width) (use default width if aWidth = 0)
 *      if width < 0 : draw segments in sketch mode, width = abs(width)
 *      Use a value min(aSize.x, aSize.y) / 5 for a bold text
 *  @param aItalic = true to simulate an italic font
 *  @param aBold = true to use a bold font. Useful only with default width value (aWidth = 0)
 *  @param aCallback() = function called (if non null) to draw each segment.
 *                  used to draw 3D texts or for plotting, NULL for normal drawings
 *  @param aPlotter = a pointer to a PLOTTER instance, when this function is used to plot
 *                  the text. NULL to draw this text.
 */
void DrawGraphicText( EDA_RECT* aClipBox,
                      wxDC* aDC,
                      const wxPoint& aPos,
                      EDA_COLOR_T aColor,
                      const wxString& aText,
                      double aOrient,
                      const wxSize& aSize,
                      enum EDA_TEXT_HJUSTIFY_T aH_justify,
                      enum EDA_TEXT_VJUSTIFY_T aV_justify,
                      int aWidth,
                      bool aItalic,
                      bool aBold,
                      void (* aCallback)( int x0, int y0, int xf, int yf ),
                      PLOTTER* aPlotter )
{
    int         AsciiCode;
    int         x0, y0;
    int         size_h, size_v;
    unsigned    ptr;
    int         dx, dy;                     // Draw coordinate for segments to draw. also used in some other calculation
    wxPoint     current_char_pos;           // Draw coordinates for the current char
    wxPoint     overbar_pos;                // Start point for the current overbar
    int         overbar_italic_comp;        // Italic compensation for overbar
    #define        BUF_SIZE 100
    wxPoint coord[BUF_SIZE + 1];                // Buffer coordinate used to draw polylines (one char shape)
    bool    sketch_mode     = false;
    bool    italic_reverse  = false;            // true for mirrored texts with m_Size.x < 0

    size_h  = aSize.x;                          /* PLEASE NOTE: H is for HORIZONTAL not for HEIGHT */
    size_v  = aSize.y;

    if( aWidth == 0 && aBold ) // Use default values if aWidth == 0
        aWidth = GetPenSizeForBold( std::min( aSize.x, aSize.y ) );

    if( aWidth < 0 )
    {
        aWidth = -aWidth;
        sketch_mode = true;
    }

#ifdef CLIP_PEN      // made by draw and plot functions
    aWidth = Clamp_Text_PenSize( aWidth, aSize, aBold );
#endif

    if( size_h < 0 ) // text is mirrored using size.x < 0 (mirror / Y axis)
        italic_reverse = true;

    unsigned char_count = NegableTextLength( aText );

    if( char_count == 0 )
        return;

    current_char_pos = aPos;

    dx  = GraphicTextWidth( aText, size_h, aItalic, aWidth );
    dy  = size_v;

    /* Do not draw the text if out of draw area! */
    if( aClipBox )
    {
        int xm, ym, ll, xc, yc;
        ll = std::abs( dx );

        xc  = current_char_pos.x;
        yc  = current_char_pos.y;

        x0  = aClipBox->GetX() - ll;
        y0  = aClipBox->GetY() - ll;
        xm  = aClipBox->GetRight() + ll;
        ym  = aClipBox->GetBottom() + ll;

        if( xc < x0 )
            return;

        if( yc < y0 )
            return;

        if( xc > xm )
            return;

        if( yc > ym )
            return;
    }


    /* Compute the position of the first letter of the text
     * this position is the position of the left bottom point of the letter
     * this is the same as the text position only for a left and bottom justified text
     * In others cases, this position must be calculated from the text position ans size
     */

    switch( aH_justify )
    {
    case GR_TEXT_HJUSTIFY_CENTER:
        current_char_pos.x -= dx / 2;
        break;

    case GR_TEXT_HJUSTIFY_RIGHT:
        current_char_pos.x -= dx;
        break;

    case GR_TEXT_HJUSTIFY_LEFT:
        break;
    }

    switch( aV_justify )
    {
    case GR_TEXT_VJUSTIFY_CENTER:
        current_char_pos.y += dy / 2;
        break;

    case GR_TEXT_VJUSTIFY_TOP:
        current_char_pos.y += dy;
        break;

    case GR_TEXT_VJUSTIFY_BOTTOM:
        break;
    }

    // Note: if aPanel == NULL, we are using a GL Canvas that handle scaling
    if( aSize.x == 0 )
        return;

    /* if a text size is too small, the text cannot be drawn, and it is drawn as a single
     * graphic line */
    if( aDC && ( aDC->LogicalToDeviceYRel( std::abs( aSize.y ) ) < MIN_DRAWABLE_TEXT_SIZE ))
    {
        // draw the text as a line always vertically centered
        wxPoint end( current_char_pos.x + dx, current_char_pos.y );

        RotatePoint( &current_char_pos, aPos, aOrient );
        RotatePoint( &end, aPos, aOrient );

        if( aPlotter )
        {
            aPlotter->MoveTo( current_char_pos );
            aPlotter->FinishTo( end );
        }
        else if( aCallback )
        {
            aCallback( current_char_pos.x, current_char_pos.y, end.x, end.y );
        }
        else
            GRLine( aClipBox, aDC,
                    current_char_pos.x, current_char_pos.y, end.x, end.y, aWidth, aColor );

        return;
    }

    if( aItalic )
    {
        overbar_italic_comp = OverbarPositionY( size_v ) / 8;

        if( italic_reverse )
        {
            overbar_italic_comp = -overbar_italic_comp;
        }
    }
    else
    {
        overbar_italic_comp = 0;
    }

    int overbars = 0;   // Number of '~' seen (except '~~')
    ptr = 0;            // ptr = text index

    while( ptr < char_count )
    {
        if( aText[ptr + overbars] == '~' )
        {
            if( ptr + overbars + 1 < aText.length()
                && aText[ptr + overbars + 1] == '~' )   /* '~~' draw as '~' */
                ptr++;                                  // skip first '~' char and draw second

            else
            {
                // Found an overbar, adjust the pointers
                overbars++;

                if( overbars & 1 )      // odd overbars count
                {
                    // Starting the overbar
                    overbar_pos     = current_char_pos;
                    overbar_pos.x   += overbar_italic_comp;
                    overbar_pos.y   -= OverbarPositionY( size_v );
                    RotatePoint( &overbar_pos, aPos, aOrient );
                }
                else
                {
                    // Ending the overbar
                    coord[0]        = overbar_pos;
                    overbar_pos     = current_char_pos;
                    overbar_pos.x   += overbar_italic_comp;
                    overbar_pos.y   -= OverbarPositionY( size_v );
                    RotatePoint( &overbar_pos, aPos, aOrient );
                    coord[1] = overbar_pos;
                    // Plot the overbar segment
                    DrawGraphicTextPline( aClipBox, aDC, aColor, aWidth,
                                          sketch_mode, 2, coord, aCallback, aPlotter );
                }

                continue;    // Skip ~ processing
            }
        }

        AsciiCode = aText.GetChar( ptr + overbars );

        const char* ptcar = GetHersheyShapeDescription( AsciiCode );
        // Get metrics
        int         xsta    = *ptcar++ - 'R';
        int         xsto    = *ptcar++ - 'R';
        int         point_count = 0;
        bool        endcar = false;

        while( !endcar )
        {
            int hc1, hc2;
            hc1 = *ptcar++;

            if( hc1 )
            {
                hc2 = *ptcar++;
            }
            else
            {
                // End of character, insert a synthetic pen up:
                hc1    = ' ';
                hc2    = 'R';
                endcar = true;
            }

            // Do the Hershey decode thing:
            // coordinates values are coded as <value> + 'R'
            hc1 -= 'R';
            hc2 -= 'R';

            // Pen up request
            if( hc1 == -50 && hc2 == 0 )
            {
                if( point_count )
                {
                    if( aWidth <= 1 )
                        aWidth = 0;

                    DrawGraphicTextPline( aClipBox, aDC, aColor, aWidth,
                                          sketch_mode, point_count, coord,
                                          aCallback, aPlotter );
                }

                point_count = 0;
            }
            else
            {
                wxPoint currpoint;
                hc1 -= xsta; hc2 -= 10;    // Align the midpoint
                hc1  = KiROUND( hc1 * size_h * s_HersheyScaleFactor );
                hc2  = KiROUND( hc2 * size_v * s_HersheyScaleFactor );

                // To simulate an italic font,
                // add a x offset depending on the y offset
                if( aItalic )
                    hc1 -= KiROUND( italic_reverse ? -hc2 / 8.0 : hc2 / 8.0 );

                currpoint.x = hc1 + current_char_pos.x;
                currpoint.y = hc2 + current_char_pos.y;

                RotatePoint( &currpoint, aPos, aOrient );
                coord[point_count] = currpoint;

                if( point_count < BUF_SIZE - 1 )
                    point_count++;
            }
        }    // end draw 1 char

        ptr++;

        // Apply the advance width
        current_char_pos.x += KiROUND( size_h * (xsto - xsta) * s_HersheyScaleFactor );
    }

    if( overbars % 2 )
    {
        // Close the last overbar
        coord[0]       = overbar_pos;
        overbar_pos    = current_char_pos;
        overbar_pos.y -= OverbarPositionY( size_v );
        RotatePoint( &overbar_pos, aPos, aOrient );
        coord[1] = overbar_pos;

        // Plot the overbar segment
        DrawGraphicTextPline( aClipBox, aDC, aColor, aWidth,
                              sketch_mode, 2, coord, aCallback, aPlotter );
    }
}
bool DialogEditModuleText::TransferDataFromWindow()
{
    if( !Validate() || !DialogEditModuleText_base::TransferDataFromWindow() )
        return false;

    if( m_module )
        m_parent->SaveCopyInUndoList( m_module, UR_CHANGED );

#ifndef USE_WX_OVERLAY
    if( m_dc )     //Erase old text on screen
    {
        m_currentText->Draw( m_parent->GetCanvas(), m_dc, GR_XOR,
                             (m_currentText->IsMoving()) ? MoveVector : wxPoint( 0, 0 ) );
    }
#endif

    m_currentText->SetText( m_Name->GetValue() );
    m_currentText->SetItalic( m_Style->GetSelection() == 1 );

    wxPoint tmp;

    tmp.x = ValueFromString( g_UserUnit, m_TxtPosCtrlX->GetValue() );
    tmp.y = ValueFromString( g_UserUnit, m_TxtPosCtrlY->GetValue() );

    m_currentText->SetPos0( tmp );

    wxSize textSize( wxSize( ValueFromString( g_UserUnit, m_TxtSizeCtrlX->GetValue() ),
                             ValueFromString( g_UserUnit, m_TxtSizeCtrlY->GetValue() ) ) );

    // Test for a reasonable size:
    if( textSize.x < TEXTS_MIN_SIZE )
        textSize.x = TEXTS_MIN_SIZE;

    if( textSize.y < TEXTS_MIN_SIZE )
        textSize.y = TEXTS_MIN_SIZE;

    m_currentText->SetSize( textSize );

    int width = ValueFromString( g_UserUnit, m_TxtWidthCtlr->GetValue() );

    // Test for a reasonable width:
    if( width <= 1 )
        width = 1;

    int maxthickness = Clamp_Text_PenSize(width, m_currentText->GetSize() );

    if( width > maxthickness )
    {
        DisplayError( NULL,
                      _( "The text thickness is too large for the text size. It will be clamped" ) );
        width = maxthickness;
    }

    m_currentText->SetThickness( width );

    m_currentText->SetVisible( m_Show->GetSelection() == 0 );

    bool custom_orientation = false;
    switch( m_Orient->GetSelection() )
    {
    case 0:
        m_currentText->SetOrientation( 0 );
        break;

    case 1:
        m_currentText->SetOrientation( 900 );
        break;

    case 2:
        m_currentText->SetOrientation( -900 );
        break;

    default:
        custom_orientation = true;
        m_currentText->SetOrientation( KiROUND( m_OrientValue * 10.0 ) );
        break;
    };

    switch( int( m_currentText->GetOrientation() ) )
    {
    case 0:
        m_Orient->SetSelection( 0 );
        break;

    case 900:
    case -2700:
        m_Orient->SetSelection( 1 );
        break;

    case -900:
    case 2700:
        m_Orient->SetSelection( 2 );
        break;

    default:
        m_Orient->SetSelection( 3 );
        m_currentText->SetOrientation( KiROUND( m_OrientValue * 10.0 ) );
        custom_orientation = true;
        break;
    }
    m_OrientValue = 10.0 * m_currentText->GetOrientation();
    m_OrientValueCtrl->Enable( custom_orientation );
    m_OrientValidator.TransferToWindow();

    m_currentText->SetDrawCoord();

    LAYER_NUM layer = m_LayerSelectionCtrl->GetLayerSelection();
    m_currentText->SetLayer( ToLAYER_ID( layer ) );
    m_currentText->SetMirrored( IsBackLayer( m_currentText->GetLayer() ) );

#ifndef USE_WX_OVERLAY
    if( m_dc )     // Display new text
    {
        m_currentText->Draw( m_parent->GetCanvas(), m_dc, GR_XOR,
                (m_currentText->IsMoving()) ? MoveVector : wxPoint( 0, 0 ) );
    }
#else
    m_parent->Refresh();
#endif

    m_parent->OnModify();

    if( m_module )
        m_module->SetLastEditTime();

    return true;
}
int Clamp_Text_PenSize( int aPenSize, wxSize aSize, bool aBold )
{
    int size = std::min( std::abs( aSize.x ), std::abs( aSize.y ) );

    return Clamp_Text_PenSize( aPenSize, size, aBold );
}
Esempio n. 23
0
void DIALOG_DIMENSION_EDITOR::OnOKClick( wxCommandEvent& event )
{
    LAYER_ID newlayer = ToLAYER_ID( m_SelLayerBox->GetLayerSelection() );

    if( !m_Parent->GetBoard()->IsLayerEnabled( newlayer ) )
    {
        wxMessageBox( _( "The layer currently selected is not enabled for this board\n"
                         "You cannot use it" ) );
        return;
    }

#ifndef USE_WX_OVERLAY
    if( m_DC )     // Delete old text.
    {
        CurrentDimension->Draw( m_Parent->GetCanvas(), m_DC, GR_XOR );
    }
#endif

    m_Parent->SaveCopyInUndoList(CurrentDimension, UR_CHANGED);

    if( m_Name->GetValue() != wxEmptyString )
    {
        CurrentDimension->SetText( m_Name->GetValue() );
    }

    wxString msg;

    // Get new size value:
    msg = m_TxtSizeXCtrl->GetValue();
    CurrentDimension->Text().SetWidth( ValueFromString( g_UserUnit, msg ) );
    msg = m_TxtSizeYCtrl->GetValue();
    CurrentDimension->Text().SetHeight( ValueFromString( g_UserUnit, msg ) );

    // Get new position value:
    // It will be copied later in dimension, because
    msg = m_textCtrlPosX->GetValue();
    wxPoint pos;
    pos.x = ValueFromString( g_UserUnit, msg );
    msg = m_textCtrlPosY->GetValue();
    pos.y = ValueFromString( g_UserUnit, msg );
    CurrentDimension->Text().SetTextPosition( pos );

    // Get new line thickness value:
    msg = m_TxtWidthCtrl->GetValue();
    int width = ValueFromString( g_UserUnit, msg );
    int maxthickness = Clamp_Text_PenSize( width, CurrentDimension->Text().GetSize() );

    if( width > maxthickness )
    {
        DisplayError( NULL,
                      _( "The text thickness is too large for the text size.  "
                         "It will be clamped" ) );
        width = maxthickness;
    }

    CurrentDimension->SetWidth( width );
    CurrentDimension->Text().SetThickness( width );
    CurrentDimension->Text().SetMirrored( ( m_rbMirror->GetSelection() == 1 ) ? true : false );
    CurrentDimension->SetLayer( newlayer );

#ifndef USE_WX_OVERLAY
    if( m_DC )     // Display new text
    {
        CurrentDimension->Draw( m_Parent->GetCanvas(), m_DC, GR_OR );
    }
#else
    m_Parent->Refresh();
#endif

    m_Parent->OnModify();
    EndModal( 1 );
}
Esempio n. 24
0
int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
{
    DIMENSION* dimension = NULL;
    int width, maxThickness;

    // if one day it is possible to draw dimensions in the footprint editor,
    // then hereby I'm letting you know that this tool does not handle UR_MODEDIT undo yet
    assert( !m_editModules );

    // Add a VIEW_GROUP that serves as a preview for the new item
    KIGFX::VIEW_GROUP preview( m_view );
    m_view->Add( &preview );

    m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
    m_controls->ShowCursor( true );
    m_controls->SetSnapping( true );

    Activate();
    m_frame->SetToolID( ID_PCB_DIMENSION_BUTT, wxCURSOR_PENCIL, _( "Add dimension" ) );

    enum DIMENSION_STEPS
    {
        SET_ORIGIN = 0,
        SET_END,
        SET_HEIGHT,
        FINISHED
    };
    int step = SET_ORIGIN;

    // Main loop: keep receiving events
    while( OPT_TOOL_EVENT evt = Wait() )
    {
        VECTOR2I cursorPos = m_controls->GetCursorPosition();

        if( evt->IsCancel() || evt->IsActivate() )
        {
            if( step != SET_ORIGIN )    // start from the beginning
            {
                preview.Clear();
                preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );

                delete dimension;
                step = SET_ORIGIN;
            }
            else
                break;

            if( evt->IsActivate() )  // now finish unconditionally
                break;
        }

        else if( evt->IsAction( &COMMON_ACTIONS::incWidth ) && step != SET_ORIGIN )
        {
            dimension->SetWidth( dimension->GetWidth() + WIDTH_STEP );
            preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
        }

        else if( evt->IsAction( &COMMON_ACTIONS::decWidth ) && step != SET_ORIGIN )
        {
            int width = dimension->GetWidth();

            if( width > WIDTH_STEP )
            {
                dimension->SetWidth( width - WIDTH_STEP );
                preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
            }
        }

        else if( evt->IsClick( BUT_LEFT ) )
        {
            switch( step )
            {
            case SET_ORIGIN:
                {
                    LAYER_ID layer = m_frame->GetScreen()->m_Active_Layer;

                    if( IsCopperLayer( layer ) || layer == Edge_Cuts )
                    {
                        DisplayInfoMessage( NULL, _( "Dimension not allowed on Copper or Edge Cut layers" ) );
                        --step;
                    }
                    else
                    {
                        // Init the new item attributes
                        dimension = new DIMENSION( m_board );
                        dimension->SetLayer( layer );
                        dimension->SetOrigin( wxPoint( cursorPos.x, cursorPos.y ) );
                        dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
                        dimension->Text().SetSize( m_board->GetDesignSettings().m_PcbTextSize );

                        width = m_board->GetDesignSettings().m_PcbTextWidth;
                        maxThickness = Clamp_Text_PenSize( width, dimension->Text().GetSize() );

                        if( width > maxThickness )
                            width = maxThickness;

                        dimension->Text().SetThickness( width );
                        dimension->SetWidth( width );
                        dimension->AdjustDimensionDetails();

                        preview.Add( dimension );

                        m_controls->SetAutoPan( true );
                        m_controls->CaptureCursor( true );
                    }
                }
                break;

            case SET_END:
                dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );

                // Dimensions that have origin and end in the same spot are not valid
                if( dimension->GetOrigin() == dimension->GetEnd() )
                    --step;
                break;

            case SET_HEIGHT:
                {
                    if( wxPoint( cursorPos.x, cursorPos.y ) != dimension->GetPosition() )
                    {
                        assert( dimension->GetOrigin() != dimension->GetEnd() );
                        assert( dimension->GetWidth() > 0 );

                        m_view->Add( dimension );
                        m_board->Add( dimension );
                        dimension->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );

                        m_frame->OnModify();
                        m_frame->SaveCopyInUndoList( dimension, UR_NEW );

                        preview.Remove( dimension );
                    }
                }
                break;
            }

            if( ++step == FINISHED )
            {
                step = SET_ORIGIN;
                m_controls->SetAutoPan( false );
                m_controls->CaptureCursor( false );
            }
        }

        else if( evt->IsMotion() )
        {
            switch( step )
            {
            case SET_END:
                dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) );
                break;

            case SET_HEIGHT:
            {
                // Calculating the direction of travel perpendicular to the selected axis
                double angle = dimension->GetAngle() + ( M_PI / 2 );

                wxPoint pos( cursorPos.x, cursorPos.y );
                wxPoint delta( pos - dimension->m_featureLineDO );
                double height  = ( delta.x * cos( angle ) ) + ( delta.y * sin( angle ) );
                dimension->SetHeight( height );
            }
            break;
            }

            // Show a preview of the item
            preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
        }
    }

    if( step != SET_ORIGIN )
        delete dimension;

    m_controls->ShowCursor( false );
    m_controls->SetSnapping( false );
    m_controls->SetAutoPan( false );
    m_controls->CaptureCursor( false );
    m_view->Remove( &preview );

    m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );

    return 0;
}
Esempio n. 25
0
/**
 * Function PlotGraphicText
 *  same as DrawGraphicText, but plot graphic text insteed of draw it
 *  @param aPos = text position (according to aH_justify, aV_justify)
 *  @param aColor (enum EDA_COLOR_T) = text color
 *  @param aText = text to draw
 *  @param aOrient = angle in 0.1 degree
 *  @param aSize = text size (size.x or size.y can be < 0 for mirrored texts)
 *  @param aH_justify = horizontal justification (Left, center, right)
 *  @param aV_justify = vertical justification (bottom, center, top)
 *  @param aWidth = line width (pen width) (default = 0)
 *      if width < 0 : draw segments in sketch mode, width = abs(width)
 *      Use a value min(aSize.x, aSize.y) / 5 for a bold text
 *  @param aItalic = true to simulate an italic font
 *  @param aBold = true to use a bold font Useful only with default width value (aWidth = 0)
 *  @param aMultilineAllowed = true to plot text as multiline, otherwise single line
 */
void PLOTTER::Text( const wxPoint&              aPos,
                    enum EDA_COLOR_T            aColor,
                    const wxString&             aText,
                    double                      aOrient,
                    const wxSize&               aSize,
                    enum EDA_TEXT_HJUSTIFY_T    aH_justify,
                    enum EDA_TEXT_VJUSTIFY_T    aV_justify,
                    int                         aWidth,
                    bool                        aItalic,
                    bool                        aBold,
                    bool                        aMultilineAllowed )
{
    int textPensize = aWidth;

    if( textPensize == 0 && aBold ) // Use default values if aWidth == 0
        textPensize = GetPenSizeForBold( std::min( aSize.x, aSize.y ) );

    if( textPensize >= 0 )
        textPensize = Clamp_Text_PenSize( aWidth, aSize, aBold );
    else
        textPensize = -Clamp_Text_PenSize( -aWidth, aSize, aBold );

    SetCurrentLineWidth( textPensize );

    if( aColor >= 0 )
        SetColor( aColor );

    if( aMultilineAllowed )
    {
        // EDA_TEXT needs for calculations of the position of every
        // line according to orientation and justifications
        wxArrayString strings;
        EDA_TEXT* multilineText = new EDA_TEXT( aText );
        multilineText->SetSize( aSize );
        multilineText->SetTextPosition( aPos );
        multilineText->SetOrientation( aOrient );
        multilineText->SetHorizJustify( aH_justify );
        multilineText->SetVertJustify( aV_justify );
        multilineText->SetThickness( aWidth );
        multilineText->SetMultilineAllowed( aMultilineAllowed );

        std::vector<wxPoint> positions;
        wxStringSplit( aText, strings, '\n' );
        positions.reserve( strings.Count() );

        multilineText->GetPositionsOfLinesOfMultilineText(
                positions, strings.Count() );

        for( unsigned ii = 0; ii < strings.Count(); ii++ )
        {
            wxString& txt = strings.Item( ii );
            DrawGraphicText( NULL, NULL, positions[ii], aColor, txt,
                             aOrient, aSize,
                             aH_justify, aV_justify,
                             textPensize, aItalic, aBold, NULL, this );
        }

        delete multilineText;
    }
    else
    {
        DrawGraphicText( NULL, NULL, aPos, aColor, aText,
                         aOrient, aSize,
                         aH_justify, aV_justify,
                         textPensize, aItalic, aBold, NULL, this );
    }

    if( aWidth != textPensize )
        SetCurrentLineWidth( aWidth );
}
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
}
Esempio n. 27
0
void SCH_SHEET::Plot( PLOTTER* aPlotter )
{
    COLOR4D    txtcolor = COLOR4D::UNSPECIFIED;
    wxSize      size;
    wxString    Text;
    int         name_orientation;
    wxPoint     pos_sheetname, pos_filename;
    wxPoint     pos;

    aPlotter->SetColor( GetLayerColor( GetLayer() ) );

    int thickness = GetPenSize();
    aPlotter->SetCurrentLineWidth( thickness );

    aPlotter->MoveTo( m_pos );
    pos = m_pos;
    pos.x += m_size.x;

    aPlotter->LineTo( pos );
    pos.y += m_size.y;

    aPlotter->LineTo( pos );
    pos = m_pos;
    pos.y += m_size.y;

    aPlotter->LineTo( pos );
    aPlotter->FinishTo( m_pos );

    if( IsVerticalOrientation() )
    {
        pos_sheetname    = wxPoint( m_pos.x - 8, m_pos.y + m_size.y );
        pos_filename     = wxPoint( m_pos.x + m_size.x + 4, m_pos.y + m_size.y );
        name_orientation = TEXT_ANGLE_VERT;
    }
    else
    {
        pos_sheetname    = wxPoint( m_pos.x, m_pos.y - 4 );
        pos_filename     = wxPoint( m_pos.x, m_pos.y + m_size.y + 4 );
        name_orientation = TEXT_ANGLE_HORIZ;
    }

    /* Draw texts: SheetName */
    Text = m_name;
    size = wxSize( m_sheetNameSize, m_sheetNameSize );

    //pos  = m_pos; pos.y -= 4;
    thickness = GetDefaultLineThickness();
    thickness = Clamp_Text_PenSize( thickness, size, false );

    aPlotter->SetColor( GetLayerColor( LAYER_SHEETNAME ) );

    bool italic = false;
    aPlotter->Text( pos_sheetname, txtcolor, Text, name_orientation, size,
                    GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_BOTTOM,
                    thickness, italic, false );

    /*Draw texts : FileName */
    Text = GetFileName();
    size = wxSize( m_fileNameSize, m_fileNameSize );
    thickness = GetDefaultLineThickness();
    thickness = Clamp_Text_PenSize( thickness, size, false );

    aPlotter->SetColor( GetLayerColor( LAYER_SHEETFILENAME ) );

    aPlotter->Text( pos_filename, txtcolor, Text, name_orientation, size,
                    GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_TOP,
                    thickness, italic, false );

    aPlotter->SetColor( GetLayerColor( GetLayer() ) );

    /* Draw texts : SheetLabel */
    for( size_t i = 0; i < m_pins.size(); i++ )
    {
        m_pins[i].Plot( aPlotter );
    }
}
void DialogEditModuleText::OnOkClick( wxCommandEvent& event )
{
    wxString msg;

    if ( m_module)
        m_parent->SaveCopyInUndoList( m_module, UR_CHANGED );

#ifndef USE_WX_OVERLAY
    if( m_dc )     //Erase old text on screen
    {
        m_currentText->Draw( m_parent->GetCanvas(), m_dc, GR_XOR,
                             (m_currentText->IsMoving()) ? MoveVector : wxPoint( 0, 0 ) );
    }
#endif

    m_currentText->SetText( m_Name->GetValue() );
    m_currentText->SetItalic( m_Style->GetSelection() == 1 );

    wxPoint tmp;

    msg = m_TxtPosCtrlX->GetValue();
    tmp.x = ValueFromString( g_UserUnit, msg );

    msg = m_TxtPosCtrlY->GetValue();
    tmp.y = ValueFromString( g_UserUnit, msg );

    m_currentText->SetPos0( tmp );

    wxSize textSize( wxSize( ValueFromString( g_UserUnit, m_TxtSizeCtrlX->GetValue() ),
                             ValueFromString( g_UserUnit, m_TxtSizeCtrlY->GetValue() ) ) );

    // Test for a reasonnable size:
    if( textSize.x < TEXTS_MIN_SIZE )
        textSize.x = TEXTS_MIN_SIZE;
    if( textSize.y < TEXTS_MIN_SIZE )
        textSize.y = TEXTS_MIN_SIZE;

    m_currentText->SetSize( textSize ),

    msg = m_TxtWidthCtlr->GetValue();
    int width = ValueFromString( g_UserUnit, msg );

    // Test for a reasonnable width:
    if( width <= 1 )
        width = 1;

    int maxthickness = Clamp_Text_PenSize(width, m_currentText->GetSize() );

    if( width > maxthickness )
    {
        DisplayError( NULL,
                      _( "The text thickness is too large for the text size. It will be clamped" ) );
        width = maxthickness;
    }

    m_currentText->SetThickness( width );

    m_currentText->SetVisible( m_Show->GetSelection() == 0 );

    int text_orient = (m_Orient->GetSelection() == 0) ? 0 : 900;
    m_currentText->SetOrientation( text_orient );

    m_currentText->SetDrawCoord();

#ifndef USE_WX_OVERLAY
    if( m_dc )     // Display new text
    {
        m_currentText->Draw( m_parent->GetCanvas(), m_dc, GR_XOR,
                             (m_currentText->IsMoving()) ? MoveVector : wxPoint( 0, 0 ) );
    }
#else
    m_parent->Refresh();
#endif

    m_parent->OnModify();

    if( m_module )
        m_module->SetLastEditTime();

    EndModal(1);
}
Esempio n. 29
0
void SCH_GLOBALLABEL::CreateGraphicShape( std::vector <wxPoint>& aPoints, const wxPoint& Pos )
{
    int halfSize  = GetTextHeight() / 2;
    int linewidth = GetThickness() == 0 ? GetDefaultLineThickness() : GetThickness();

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

    aPoints.clear();

    int symb_len = LenSize( GetShownText(), linewidth ) + ( TXT_MARGIN * 2 );

    // Create outline shape : 6 points
    int x = symb_len + linewidth + 3;

    // Use negation bar Y position to calculate full vertical size
    // Search for overbar symbol
    bool hasOverBar = false;

    for( unsigned ii = 1; ii < m_Text.size(); ii++ )
    {
        if( m_Text[ii-1] == '~' && m_Text[ii] != '~' )
        {
            hasOverBar = true;
            break;
        }
    }

    #define Y_CORRECTION 1.40
    // Note: this factor is due to the fact the Y size of a few letters like [
    // are bigger than the y size value, and we need a margin for the graphic symbol.
    int y = KiROUND( halfSize * Y_CORRECTION );

    // Note: this factor is due to the fact we need a margin for the graphic symbol.
    #define Y_OVERBAR_CORRECTION 1.2
    if( hasOverBar )
        y = KiROUND( KIGFX::STROKE_FONT::GetInterline( halfSize, linewidth )
                     * Y_OVERBAR_CORRECTION );

    // Gives room for line thickess and margin
    y += linewidth          // for line thickess
         + linewidth/2;     // for margin

    // Starting point(anchor)
    aPoints.push_back( wxPoint( 0, 0 ) );
    aPoints.push_back( wxPoint( 0, -y ) );     // Up
    aPoints.push_back( wxPoint( -x, -y ) );    // left
    aPoints.push_back( wxPoint( -x, 0 ) );     // Up left
    aPoints.push_back( wxPoint( -x, y ) );     // left down
    aPoints.push_back( wxPoint( 0, y ) );      // down

    int x_offset = 0;

    switch( m_shape )
    {
    case NET_INPUT:
        x_offset = -halfSize;
        aPoints[0].x += halfSize;
        break;

    case NET_OUTPUT:
        aPoints[3].x -= halfSize;
        break;

    case NET_BIDI:
    case NET_TRISTATE:
        x_offset = -halfSize;
        aPoints[0].x += halfSize;
        aPoints[3].x -= halfSize;
        break;

    case NET_UNSPECIFIED:
    default:
        break;
    }

    int angle = 0;

    switch( GetLabelSpinStyle() )
    {
    default:
    case 0:               break;   // Orientation horiz normal
    case 1: angle = -900; break;   // Orientation vert UP
    case 2: angle = 1800; break;   // Orientation horiz inverse
    case 3: angle = 900;  break;   // Orientation vert BOTTOM
    }

    // Rotate outlines and move corners in real position
    for( wxPoint& aPoint : aPoints )
    {
        aPoint.x += x_offset;

        if( angle )
            RotatePoint( &aPoint, angle );

        aPoint += Pos;
    }

    aPoints.push_back( aPoints[0] ); // closing
}
Esempio n. 30
0
void SCH_GLOBALLABEL::CreateGraphicShape( std::vector <wxPoint>& aPoints, const wxPoint& Pos )
{
    int HalfSize  = m_Size.y / 2;
    int linewidth = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;

    linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );

    aPoints.clear();

    int symb_len = LenSize( m_Text ) + ( TXTMARGE * 2 );

    // Create outline shape : 6 points
    int x = symb_len + linewidth + 3;

    // Use negation bar Y position to calculate full vertical size
    #define Y_CORRECTION 1.22
    // Note: this factor is due to the fact the negation bar Y position
    // does not give exactly the full Y size of text
    // and is experimentally set  to this value
    int y = KiROUND( OverbarPositionY( HalfSize, linewidth ) * Y_CORRECTION );
    // add room for line thickness and space between top of text and graphic shape
    y += linewidth;

    // Starting point(anchor)
    aPoints.push_back( wxPoint( 0, 0 ) );
    aPoints.push_back( wxPoint( 0, -y ) );     // Up
    aPoints.push_back( wxPoint( -x, -y ) );    // left
    aPoints.push_back( wxPoint( -x, 0 ) );     // Up left
    aPoints.push_back( wxPoint( -x, y ) );     // left down
    aPoints.push_back( wxPoint( 0, y ) );      // down

    int x_offset = 0;

    switch( m_shape )
    {
    case NET_INPUT:
        x_offset = -HalfSize;
        aPoints[0].x += HalfSize;
        break;

    case NET_OUTPUT:
        aPoints[3].x -= HalfSize;
        break;

    case NET_BIDI:
    case NET_TRISTATE:
        x_offset = -HalfSize;
        aPoints[0].x += HalfSize;
        aPoints[3].x -= HalfSize;
        break;

    case NET_UNSPECIFIED:
    default:
        break;
    }

    int angle = 0;

    switch( m_schematicOrientation )
    {
    case 0:             /* Orientation horiz normal */
        break;

    case 1:             /* Orientation vert UP */
        angle = -900;
        break;

    case 2:             /* Orientation horiz inverse */
        angle = 1800;
        break;

    case 3:             /* Orientation vert BOTTOM */
        angle = 900;
        break;
    }

    // Rotate outlines and move corners in real position
    for( unsigned ii = 0; ii < aPoints.size(); ii++ )
    {
        aPoints[ii].x += x_offset;

        if( angle )
            RotatePoint( &aPoints[ii], angle );

        aPoints[ii] += Pos;
    }

    aPoints.push_back( aPoints[0] ); // closing
}