/** * 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 ); }
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; }
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; }
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 }
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 }
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; }
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; }
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; }
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; }
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 ); }
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 ); }
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; }
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; }
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; }
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; }
/** * 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( ¤t_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 ); }
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 ); }
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; }
/** * 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 }
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); }
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 }
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 }