/** * 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 (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) (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, 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, void (* aCallback)( int x0, int y0, int xf, int yf ), PLOTTER* aPlotter ) { bool fill_mode = true; if( aWidth == 0 && aBold ) // Use default values if aWidth == 0 aWidth = GetPenSizeForBold( std::min( aSize.x, aSize.y ) ); if( aWidth < 0 ) { aWidth = -aWidth; fill_mode = false; } basic_gal.SetIsFill( fill_mode ); basic_gal.SetLineWidth( aWidth ); EDA_TEXT dummy; dummy.SetItalic( aItalic ); dummy.SetBold( aBold ); dummy.SetHorizJustify( aH_justify ); dummy.SetVertJustify( aV_justify ); wxSize size = aSize; dummy.SetMirrored( size.x < 0 ); if( size.x < 0 ) size.x = - size.x; dummy.SetTextSize( size ); basic_gal.SetTextAttributes( &dummy ); basic_gal.SetPlotter( aPlotter ); basic_gal.SetCallback( aCallback ); basic_gal.m_DC = aDC; basic_gal.m_Color = aColor; basic_gal.SetClipBox( aClipBox ); basic_gal.StrokeText( aText, VECTOR2D( aPos ), aOrient * M_PI/1800 ); }
int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent ) { // first, check if we have a selection, or try to get one SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>(); const SELECTION& selection = selTool->GetSelection(); // Be sure that there is at least one item that we can modify if( !hoverSelection( selection ) ) return 0; bool originalItemsModified = false; // we have a selection to work on now, so start the tool process PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>(); editFrame->OnModify(); if( m_editModules ) { // Module editors do their undo point upfront for the whole module editFrame->SaveCopyInUndoList( editFrame->GetBoard()->m_Modules, UR_MODEDIT ); } else { // We may also change the original item editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); } DIALOG_CREATE_ARRAY::ARRAY_OPTIONS* array_opts = NULL; VECTOR2I rp = selection.GetCenter(); const wxPoint rotPoint( rp.x, rp.y ); DIALOG_CREATE_ARRAY dialog( editFrame, rotPoint, &array_opts ); int ret = dialog.ShowModal(); if( ret == wxID_OK && array_opts != NULL ) { PICKED_ITEMS_LIST newItemList; for( int i = 0; i < selection.Size(); ++i ) { BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i ); if( !item ) continue; wxString cachedString; if( item->Type() == PCB_MODULE_T ) { cachedString = static_cast<MODULE*>( item )->GetReferencePrefix(); } else if( EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( item ) ) { // Copy the text (not just take a reference cachedString = text->GetText(); } // iterate across the array, laying out the item at the // correct position const unsigned nPoints = array_opts->GetArraySize(); for( unsigned ptN = 0; ptN < nPoints; ++ptN ) { BOARD_ITEM* newItem = NULL; if( ptN == 0 ) newItem = item; else { // if renumbering, no need to increment const bool increment = !array_opts->ShouldRenumberItems(); // Some items cannot be duplicated // i.e. the ref and value fields of a footprint or zones // therefore newItem can be null if( m_editModules ) newItem = editFrame->GetBoard()->m_Modules->DuplicateAndAddItem( item, increment ); else { #if 0 // @TODO: see if we allow zone duplication here // Duplicate zones is especially tricky (overlaping zones must be merged) // so zones are not duplicated if( item->Type() == PCB_ZONE_AREA_T ) newItem = NULL; else #endif newItem = editFrame->GetBoard()->DuplicateAndAddItem( item, increment ); } if( newItem ) { array_opts->TransformItem( ptN, newItem, rotPoint ); m_toolMgr->RunAction( COMMON_ACTIONS::unselectItem, true, newItem ); newItemList.PushItem( newItem ); if( newItem->Type() == PCB_MODULE_T) { static_cast<MODULE*>( newItem )->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, getView(), _1 ) ); } editFrame->GetGalCanvas()->GetView()->Add( newItem ); getModel<BOARD>()->GetRatsnest()->Update( newItem ); } } // set the number if needed: if( newItem && array_opts->ShouldRenumberItems() ) { switch( newItem->Type() ) { case PCB_PAD_T: { const wxString padName = array_opts->GetItemNumber( ptN ); static_cast<D_PAD*>( newItem )->SetPadName( padName ); originalItemsModified = true; break; } case PCB_MODULE_T: { const wxString moduleName = array_opts->GetItemNumber( ptN ); MODULE* module = static_cast<MODULE*>( newItem ); module->SetReference( cachedString + moduleName ); originalItemsModified = true; break; } case PCB_MODULE_TEXT_T: case PCB_TEXT_T: { EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( newItem ); if( text ) text->SetText( array_opts->InterpolateNumberIntoString( ptN, cachedString ) ); originalItemsModified = true; break; } default: // no renumbering of other items break; } } } } if( !m_editModules ) { if( originalItemsModified ) { // Update the appearance of the original items selection.group->ItemsViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } // Add all items as a single undo point for PCB editors // TODO: Can this be merged into the previous undo point (where // we saved the original items) editFrame->SaveCopyInUndoList( newItemList, UR_NEW ); } } getModel<BOARD>()->GetRatsnest()->Recalculate(); return 0; }
void DXF2BRD_CONVERTER::addMText( const DRW_MText& aData ) { wxString text = toNativeString( wxString::FromUTF8( aData.text.c_str() ) ); wxString attrib, tmp; /* Some texts start by '\' and have formating chars (font name, font option...) * ending with ';' * Here are some mtext formatting codes: * Format code Purpose * \0...\o Turns overline on and off * \L...\l Turns underline on and off * \~ Inserts a nonbreaking space \\ Inserts a backslash \\\{...\} Inserts an opening and closing brace \\ \File name; Changes to the specified font file \\ \Hvalue; Changes to the text height specified in drawing units \\ \Hvaluex; Changes the text height to a multiple of the current text height \\ \S...^...; Stacks the subsequent text at the \, #, or ^ symbol \\ \Tvalue; Adjusts the space between characters, from.75 to 4 times \\ \Qangle; Changes obliquing angle \\ \Wvalue; Changes width factor to produce wide text \\ \A Sets the alignment value; valid values: 0, 1, 2 (bottom, center, top) while( text.StartsWith( wxT("\\") ) ) */ while( text.StartsWith( wxT( "\\" ) ) ) { attrib << text.BeforeFirst( ';' ); tmp = text.AfterFirst( ';' ); text = tmp; } BOARD_ITEM* brdItem; EDA_TEXT* textItem; if( m_useModuleItems ) { TEXTE_MODULE* modText = new TEXTE_MODULE( NULL ); brdItem = static_cast< BOARD_ITEM* >( modText ); textItem = static_cast< EDA_TEXT* >( modText ); } else { TEXTE_PCB* pcbText = new TEXTE_PCB( NULL ); brdItem = static_cast< BOARD_ITEM* >( pcbText ); textItem = static_cast< EDA_TEXT* >( pcbText ); } brdItem->SetLayer( ToLAYER_ID( m_brdLayer ) ); wxPoint textpos( mapX( aData.basePoint.x ), mapY( aData.basePoint.y ) ); textItem->SetTextPos( textpos ); textItem->SetTextAngle( aData.angle * 10 ); // The 0.8 factor gives a better height/width ratio with our font textItem->SetTextWidth( mapDim( aData.height * 0.8 ) ); textItem->SetTextHeight( mapDim( aData.height ) ); textItem->SetThickness( mapDim( aData.thickness == 0 ? m_defaultThickness : aData.thickness ) ); textItem->SetText( text ); // Initialize text justifications: if( aData.textgen <= 3 ) { textItem->SetVertJustify( GR_TEXT_VJUSTIFY_TOP ); } else if( aData.textgen <= 6 ) { textItem->SetVertJustify( GR_TEXT_VJUSTIFY_CENTER ); } else { textItem->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM ); } if( aData.textgen % 3 == 1 ) { textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); } else if( aData.textgen % 3 == 2 ) { textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER ); } else { textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT ); } #if 0 // These setting have no mening in Pcbnew if( data.alignH == 1 ) { // Text is left to right; } else if( data.alignH == 3 ) { // Text is top to bottom; } else { // use ByStyle; } if( aData.alignV == 1 ) { // use AtLeast; } else { // useExact; } #endif m_newItemsList.push_back( static_cast< BOARD_ITEM* >( brdItem ) ); }
/** * 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 DXF2BRD_CONVERTER::addText( const DRW_Text& aData ) { BOARD_ITEM* brdItem; EDA_TEXT* textItem; if( m_useModuleItems ) { TEXTE_MODULE* modText = new TEXTE_MODULE( NULL ); brdItem = static_cast< BOARD_ITEM* >( modText ); textItem = static_cast< EDA_TEXT* >( modText ); } else { TEXTE_PCB* pcbText = new TEXTE_PCB( NULL ); brdItem = static_cast< BOARD_ITEM* >( pcbText ); textItem = static_cast< EDA_TEXT* >( pcbText ); } brdItem->SetLayer( ToLAYER_ID( m_brdLayer ) ); wxPoint refPoint( mapX( aData.basePoint.x ), mapY( aData.basePoint.y ) ); wxPoint secPoint( mapX( aData.secPoint.x ), mapY( aData.secPoint.y ) ); if( aData.alignV != 0 || aData.alignH != 0 || aData.alignH == DRW_Text::HMiddle ) { if( aData.alignH != DRW_Text::HAligned && aData.alignH != DRW_Text::HFit ) { wxPoint tmp = secPoint; secPoint = refPoint; refPoint = tmp; } } switch( aData.alignV ) { case DRW_Text::VBaseLine: textItem->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM ); break; case DRW_Text::VBottom: textItem->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM ); break; case DRW_Text::VMiddle: textItem->SetVertJustify( GR_TEXT_VJUSTIFY_CENTER ); break; case DRW_Text::VTop: textItem->SetVertJustify( GR_TEXT_VJUSTIFY_TOP ); break; } switch( aData.alignH ) { case DRW_Text::HLeft: textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); break; case DRW_Text::HCenter: textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER ); break; case DRW_Text::HRight: textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT ); break; case DRW_Text::HAligned: // no equivalent options in text pcb. textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); break; case DRW_Text::HMiddle: // no equivalent options in text pcb. textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER ); break; case DRW_Text::HFit: // no equivalent options in text pcb. textItem->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); break; } #if 0 wxString sty = wxString::FromUTF8( aData.style.c_str() ); sty = sty.ToLower(); if( aData.textgen == 2 ) { // Text dir = left to right; } else if( aData.textgen == 4 ) { // Text dir = top to bottom; } else { } #endif wxString text = toNativeString( wxString::FromUTF8( aData.text.c_str() ) ); textItem->SetTextPos( refPoint ); textItem->SetTextAngle( aData.angle * 10 ); // The 0.8 factor gives a better height/width ratio with our font textItem->SetTextWidth( mapDim( aData.height * 0.8 ) ); textItem->SetTextHeight( mapDim( aData.height ) ); textItem->SetThickness( mapDim( aData.thickness == 0 ? m_defaultThickness : aData.thickness ) ); textItem->SetText( text ); m_newItemsList.push_back( static_cast< BOARD_ITEM* >( brdItem ) ); }