mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 18:23:15 +02:00
PCB Editor: Add User Background Images
This commit is contained in:
parent
1f4079802c
commit
3669cb4673
@ -512,6 +512,7 @@ set( PCB_COMMON_SRCS
|
|||||||
${CMAKE_SOURCE_DIR}/pcbnew/netinfo_list.cpp
|
${CMAKE_SOURCE_DIR}/pcbnew/netinfo_list.cpp
|
||||||
${CMAKE_SOURCE_DIR}/pcbnew/pad.cpp
|
${CMAKE_SOURCE_DIR}/pcbnew/pad.cpp
|
||||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_target.cpp
|
${CMAKE_SOURCE_DIR}/pcbnew/pcb_target.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/pcbnew/pcb_bitmap.cpp
|
||||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_text.cpp
|
${CMAKE_SOURCE_DIR}/pcbnew/pcb_text.cpp
|
||||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_textbox.cpp
|
${CMAKE_SOURCE_DIR}/pcbnew/pcb_textbox.cpp
|
||||||
${CMAKE_SOURCE_DIR}/pcbnew/board_stackup_manager/board_stackup.cpp
|
${CMAKE_SOURCE_DIR}/pcbnew/board_stackup_manager/board_stackup.cpp
|
||||||
|
@ -25,6 +25,10 @@
|
|||||||
#include <wx/dcclient.h>
|
#include <wx/dcclient.h>
|
||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
#include <bitmap_base.h>
|
#include <bitmap_base.h>
|
||||||
|
#include <pcb_base_edit_frame.h>
|
||||||
|
#include <pcb_bitmap.h>
|
||||||
|
#include <tool/tool_manager.h>
|
||||||
|
#include <tool/actions.h>
|
||||||
|
|
||||||
#include <dialogs/dialog_image_editor.h>
|
#include <dialogs/dialog_image_editor.h>
|
||||||
|
|
||||||
@ -129,3 +133,24 @@ void DIALOG_IMAGE_EDITOR::TransferToImage( BITMAP_BASE* aItem )
|
|||||||
m_workingImage->SetScale( scale );
|
m_workingImage->SetScale( scale );
|
||||||
aItem->ImportData( m_workingImage );
|
aItem->ImportData( m_workingImage );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PCB_BASE_EDIT_FRAME::ShowBitmapPropertiesDialog( BOARD_ITEM* aBitmap )
|
||||||
|
{
|
||||||
|
PCB_BITMAP* bitmap = static_cast<PCB_BITMAP*>( aBitmap );
|
||||||
|
DIALOG_IMAGE_EDITOR dlg( this, bitmap->GetImage() );
|
||||||
|
|
||||||
|
if( dlg.ShowModal() == wxID_OK )
|
||||||
|
{
|
||||||
|
// save old image in undo list if not already in edit
|
||||||
|
if( bitmap->GetEditFlags() == 0 )
|
||||||
|
SaveCopyInUndoList( bitmap, UNDO_REDO::CHANGED );
|
||||||
|
|
||||||
|
dlg.TransferToImage( bitmap->GetImage() );
|
||||||
|
|
||||||
|
// The bitmap is cached in Opengl: clear the cache in case it has become invalid
|
||||||
|
GetCanvas()->GetView()->RecacheAllItems();
|
||||||
|
m_toolManager->PostEvent( EVENTS::SelectedItemsModified );
|
||||||
|
this->OnModify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -315,6 +315,7 @@ static struct EDA_ITEM_DESC
|
|||||||
.Map( PCB_FOOTPRINT_T, _HKI( "Footprint" ) )
|
.Map( PCB_FOOTPRINT_T, _HKI( "Footprint" ) )
|
||||||
.Map( PCB_PAD_T, _HKI( "Pad" ) )
|
.Map( PCB_PAD_T, _HKI( "Pad" ) )
|
||||||
.Map( PCB_SHAPE_T, _HKI( "Graphic" ) )
|
.Map( PCB_SHAPE_T, _HKI( "Graphic" ) )
|
||||||
|
.Map( PCB_BITMAP_T, _HKI( "Bitmap" ) )
|
||||||
.Map( PCB_TEXT_T, _HKI( "Text" ) )
|
.Map( PCB_TEXT_T, _HKI( "Text" ) )
|
||||||
.Map( PCB_TEXTBOX_T, _HKI( "Text Box" ) )
|
.Map( PCB_TEXTBOX_T, _HKI( "Text Box" ) )
|
||||||
.Map( PCB_FP_TEXT_T, _HKI( "Text" ) )
|
.Map( PCB_FP_TEXT_T, _HKI( "Text" ) )
|
||||||
|
@ -480,10 +480,12 @@ void CAIRO_GAL_BASE::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CAIRO_GAL_BASE::DrawBitmap( const BITMAP_BASE& aBitmap )
|
void CAIRO_GAL_BASE::DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend )
|
||||||
{
|
{
|
||||||
cairo_save( m_currentContext );
|
cairo_save( m_currentContext );
|
||||||
|
|
||||||
|
alphaBlend = std::clamp( alphaBlend, 0.0, 1.0 );
|
||||||
|
|
||||||
// We have to calculate the pixel size in users units to draw the image.
|
// We have to calculate the pixel size in users units to draw the image.
|
||||||
// m_worldUnitLength is a factor used for converting IU to inches
|
// m_worldUnitLength is a factor used for converting IU to inches
|
||||||
double scale = 1.0 / ( aBitmap.GetPPI() * m_worldUnitLength );
|
double scale = 1.0 / ( aBitmap.GetPPI() * m_worldUnitLength );
|
||||||
@ -537,7 +539,7 @@ void CAIRO_GAL_BASE::DrawBitmap( const BITMAP_BASE& aBitmap )
|
|||||||
|
|
||||||
cairo_surface_mark_dirty( image );
|
cairo_surface_mark_dirty( image );
|
||||||
cairo_set_source_surface( m_currentContext, image, 0, 0 );
|
cairo_set_source_surface( m_currentContext, image, 0, 0 );
|
||||||
cairo_paint( m_currentContext );
|
cairo_paint_with_alpha( m_currentContext, alphaBlend );
|
||||||
|
|
||||||
// store the image handle so it can be destroyed later
|
// store the image handle so it can be destroyed later
|
||||||
m_imageSurfaces.push_back( image );
|
m_imageSurfaces.push_back( image );
|
||||||
|
@ -1232,8 +1232,10 @@ void OPENGL_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aContro
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OPENGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap )
|
void OPENGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend )
|
||||||
{
|
{
|
||||||
|
GLfloat alpha = std::clamp( alphaBlend, 0.0, 1.0 );
|
||||||
|
|
||||||
// We have to calculate the pixel size in users units to draw the image.
|
// We have to calculate the pixel size in users units to draw the image.
|
||||||
// m_worldUnitLength is a factor used for converting IU to inches
|
// m_worldUnitLength is a factor used for converting IU to inches
|
||||||
double scale = 1.0 / ( aBitmap.GetPPI() * m_worldUnitLength );
|
double scale = 1.0 / ( aBitmap.GetPPI() * m_worldUnitLength );
|
||||||
@ -1259,16 +1261,16 @@ void OPENGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap )
|
|||||||
glBindTexture( GL_TEXTURE_2D, texture_id );
|
glBindTexture( GL_TEXTURE_2D, texture_id );
|
||||||
|
|
||||||
glBegin( GL_QUADS );
|
glBegin( GL_QUADS );
|
||||||
glColor4f( 1.0, 1.0, 1.0, 1.0 );
|
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||||
glTexCoord2f( 0.0, 0.0 );
|
glTexCoord2f( 0.0, 0.0 );
|
||||||
glVertex3f( v0.x, v0.y, m_layerDepth );
|
glVertex3f( v0.x, v0.y, m_layerDepth );
|
||||||
glColor4f( 1.0, 1.0, 1.0, 1.0 );
|
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||||
glTexCoord2f( 1.0, 0.0 );
|
glTexCoord2f( 1.0, 0.0 );
|
||||||
glVertex3f( v1.x, v0.y, m_layerDepth );
|
glVertex3f( v1.x, v0.y, m_layerDepth );
|
||||||
glColor4f( 1.0, 1.0, 1.0, 1.0 );
|
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||||
glTexCoord2f( 1.0, 1.0 );
|
glTexCoord2f( 1.0, 1.0 );
|
||||||
glVertex3f( v1.x, v1.y, m_layerDepth );
|
glVertex3f( v1.x, v1.y, m_layerDepth );
|
||||||
glColor4f( 1.0, 1.0, 1.0, 1.0 );
|
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||||
glTexCoord2f( 0.0, 1.0 );
|
glTexCoord2f( 0.0, 1.0 );
|
||||||
glVertex3f( v0.x, v1.y, m_layerDepth );
|
glVertex3f( v0.x, v1.y, m_layerDepth );
|
||||||
glEnd();
|
glEnd();
|
||||||
|
@ -74,6 +74,7 @@ convexhull
|
|||||||
copper_line_width
|
copper_line_width
|
||||||
copper_text_dims
|
copper_text_dims
|
||||||
courtyard_line_width
|
courtyard_line_width
|
||||||
|
data
|
||||||
date
|
date
|
||||||
defaults
|
defaults
|
||||||
descr
|
descr
|
||||||
@ -148,6 +149,7 @@ hide
|
|||||||
hole_to_hole_min
|
hole_to_hole_min
|
||||||
host
|
host
|
||||||
id
|
id
|
||||||
|
image
|
||||||
island
|
island
|
||||||
island_removal_mode
|
island_removal_mode
|
||||||
island_area_min
|
island_area_min
|
||||||
|
@ -157,6 +157,7 @@ PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( PROJECT* aProject, const wxStrin
|
|||||||
m_params.emplace_back( new PARAM<double>( "board.opacity.vias", &m_ViaOpacity, 1.0 ) );
|
m_params.emplace_back( new PARAM<double>( "board.opacity.vias", &m_ViaOpacity, 1.0 ) );
|
||||||
m_params.emplace_back( new PARAM<double>( "board.opacity.pads", &m_PadOpacity, 1.0 ) );
|
m_params.emplace_back( new PARAM<double>( "board.opacity.pads", &m_PadOpacity, 1.0 ) );
|
||||||
m_params.emplace_back( new PARAM<double>( "board.opacity.zones", &m_ZoneOpacity, 0.6 ) );
|
m_params.emplace_back( new PARAM<double>( "board.opacity.zones", &m_ZoneOpacity, 0.6 ) );
|
||||||
|
m_params.emplace_back( new PARAM<double>( "board.opacity.background_images", &m_BgImageOpacity, 0.6 ) );
|
||||||
|
|
||||||
m_params.emplace_back( new PARAM_LIST<wxString>( "board.hidden_nets", &m_HiddenNets, {} ) );
|
m_params.emplace_back( new PARAM_LIST<wxString>( "board.hidden_nets", &m_HiddenNets, {} ) );
|
||||||
|
|
||||||
|
@ -88,6 +88,7 @@ enum KICAD_T
|
|||||||
PCB_FOOTPRINT_T, ///< class FOOTPRINT, a footprint
|
PCB_FOOTPRINT_T, ///< class FOOTPRINT, a footprint
|
||||||
PCB_PAD_T, ///< class PAD, a pad in a footprint
|
PCB_PAD_T, ///< class PAD, a pad in a footprint
|
||||||
PCB_SHAPE_T, ///< class PCB_SHAPE, a segment not on copper layers
|
PCB_SHAPE_T, ///< class PCB_SHAPE, a segment not on copper layers
|
||||||
|
PCB_BITMAP_T, ///< class PCB_BITMAP, bitmap on a layer
|
||||||
PCB_TEXT_T, ///< class PCB_TEXT, text on a layer
|
PCB_TEXT_T, ///< class PCB_TEXT, text on a layer
|
||||||
PCB_TEXTBOX_T, ///< class PCB_TEXTBOX, wrapped text on a layer
|
PCB_TEXTBOX_T, ///< class PCB_TEXTBOX, wrapped text on a layer
|
||||||
PCB_FP_TEXT_T, ///< class FP_TEXT, text in a footprint
|
PCB_FP_TEXT_T, ///< class FP_TEXT, text in a footprint
|
||||||
@ -111,7 +112,7 @@ enum KICAD_T
|
|||||||
PCB_DIM_ORTHOGONAL_T, ///< class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
|
PCB_DIM_ORTHOGONAL_T, ///< class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
|
||||||
PCB_TARGET_T, ///< class PCB_TARGET, a target (graphic item)
|
PCB_TARGET_T, ///< class PCB_TARGET, a target (graphic item)
|
||||||
PCB_ZONE_T, ///< class ZONE, a copper pour area
|
PCB_ZONE_T, ///< class ZONE, a copper pour area
|
||||||
PCB_ITEM_LIST_T , ///< class BOARD_ITEM_LIST, a list of board items
|
PCB_ITEM_LIST_T, ///< class BOARD_ITEM_LIST, a list of board items
|
||||||
PCB_NETINFO_T, ///< class NETINFO_ITEM, a description of a net
|
PCB_NETINFO_T, ///< class NETINFO_ITEM, a description of a net
|
||||||
PCB_GROUP_T, ///< class PCB_GROUP, a set of BOARD_ITEMs
|
PCB_GROUP_T, ///< class PCB_GROUP, a set of BOARD_ITEMs
|
||||||
|
|
||||||
@ -406,6 +407,7 @@ constexpr bool IsPcbnewType( const KICAD_T aType )
|
|||||||
case PCB_FOOTPRINT_T:
|
case PCB_FOOTPRINT_T:
|
||||||
case PCB_PAD_T:
|
case PCB_PAD_T:
|
||||||
case PCB_SHAPE_T:
|
case PCB_SHAPE_T:
|
||||||
|
case PCB_BITMAP_T:
|
||||||
case PCB_TEXT_T:
|
case PCB_TEXT_T:
|
||||||
case PCB_TEXTBOX_T:
|
case PCB_TEXTBOX_T:
|
||||||
case PCB_FP_TEXT_T:
|
case PCB_FP_TEXT_T:
|
||||||
|
@ -118,7 +118,7 @@ public:
|
|||||||
double aFilterValue = 0.0 ) override;
|
double aFilterValue = 0.0 ) override;
|
||||||
|
|
||||||
/// @copydoc GAL::DrawBitmap()
|
/// @copydoc GAL::DrawBitmap()
|
||||||
void DrawBitmap( const BITMAP_BASE& aBitmap ) override;
|
void DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend = 1.0 ) override;
|
||||||
|
|
||||||
// --------------
|
// --------------
|
||||||
// Screen methods
|
// Screen methods
|
||||||
|
@ -206,7 +206,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Draw a bitmap image.
|
* Draw a bitmap image.
|
||||||
*/
|
*/
|
||||||
virtual void DrawBitmap( const BITMAP_BASE& aBitmap ) {};
|
virtual void DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend = 1.0 ) {};
|
||||||
|
|
||||||
// --------------
|
// --------------
|
||||||
// Screen methods
|
// Screen methods
|
||||||
|
@ -157,7 +157,7 @@ public:
|
|||||||
double aFilterValue = 0.0 ) override;
|
double aFilterValue = 0.0 ) override;
|
||||||
|
|
||||||
/// @copydoc GAL::DrawBitmap()
|
/// @copydoc GAL::DrawBitmap()
|
||||||
void DrawBitmap( const BITMAP_BASE& aBitmap ) override;
|
void DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend = 1.0 ) override;
|
||||||
|
|
||||||
/// @copydoc GAL::BitmapText()
|
/// @copydoc GAL::BitmapText()
|
||||||
void BitmapText( const wxString& aText, const VECTOR2I& aPosition,
|
void BitmapText( const wxString& aText, const VECTOR2I& aPosition,
|
||||||
|
@ -40,6 +40,7 @@ public:
|
|||||||
m_ViaOpacity = 1.0;
|
m_ViaOpacity = 1.0;
|
||||||
m_PadOpacity = 1.0;
|
m_PadOpacity = 1.0;
|
||||||
m_ZoneOpacity = 1.0;
|
m_ZoneOpacity = 1.0;
|
||||||
|
m_BgImageOpacity = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @see ZONE_DISPLAY_MODE - stored in the project
|
/// @see ZONE_DISPLAY_MODE - stored in the project
|
||||||
@ -57,6 +58,7 @@ public:
|
|||||||
double m_ViaOpacity; ///< Opacity override for all types of via
|
double m_ViaOpacity; ///< Opacity override for all types of via
|
||||||
double m_PadOpacity; ///< Opacity override for SMD pads and PTHs
|
double m_PadOpacity; ///< Opacity override for SMD pads and PTHs
|
||||||
double m_ZoneOpacity; ///< Opacity override for filled zone areas
|
double m_ZoneOpacity; ///< Opacity override for filled zone areas
|
||||||
|
double m_BgImageOpacity; ///< Opacity override for background images
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PCBSTRUCT_H_
|
#endif // PCBSTRUCT_H_
|
||||||
|
@ -123,6 +123,7 @@ public:
|
|||||||
double m_ViaOpacity; ///< Opacity override for all types of via
|
double m_ViaOpacity; ///< Opacity override for all types of via
|
||||||
double m_PadOpacity; ///< Opacity override for SMD pads and PTH
|
double m_PadOpacity; ///< Opacity override for SMD pads and PTH
|
||||||
double m_ZoneOpacity; ///< Opacity override for filled zones
|
double m_ZoneOpacity; ///< Opacity override for filled zones
|
||||||
|
double m_BgImageOpacity; ///< Opacity override for filled zones
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of netnames that have been manually hidden in the board editor.
|
* A list of netnames that have been manually hidden in the board editor.
|
||||||
|
@ -478,6 +478,7 @@ add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pcbnew_wrap.cxx
|
|||||||
DEPENDS python/swig/netinfo.i
|
DEPENDS python/swig/netinfo.i
|
||||||
DEPENDS python/swig/pad.i
|
DEPENDS python/swig/pad.i
|
||||||
DEPENDS python/swig/pcb_group.i
|
DEPENDS python/swig/pcb_group.i
|
||||||
|
DEPENDS python/swig/pcb_bitmap.i
|
||||||
DEPENDS python/swig/pcb_text.i
|
DEPENDS python/swig/pcb_text.i
|
||||||
DEPENDS python/swig/pcb_group.i
|
DEPENDS python/swig/pcb_group.i
|
||||||
DEPENDS python/swig/plugins.i
|
DEPENDS python/swig/plugins.i
|
||||||
|
@ -112,6 +112,7 @@ void ARRAY_CREATOR::Invoke()
|
|||||||
{
|
{
|
||||||
case PCB_FOOTPRINT_T:
|
case PCB_FOOTPRINT_T:
|
||||||
case PCB_SHAPE_T:
|
case PCB_SHAPE_T:
|
||||||
|
case PCB_BITMAP_T:
|
||||||
case PCB_TEXT_T:
|
case PCB_TEXT_T:
|
||||||
case PCB_TEXTBOX_T:
|
case PCB_TEXTBOX_T:
|
||||||
case PCB_TRACE_T:
|
case PCB_TRACE_T:
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include <pcb_group.h>
|
#include <pcb_group.h>
|
||||||
#include <pcb_target.h>
|
#include <pcb_target.h>
|
||||||
#include <pcb_shape.h>
|
#include <pcb_shape.h>
|
||||||
|
#include <pcb_bitmap.h>
|
||||||
#include <pcb_text.h>
|
#include <pcb_text.h>
|
||||||
#include <pcb_textbox.h>
|
#include <pcb_textbox.h>
|
||||||
#include <pgm_base.h>
|
#include <pgm_base.h>
|
||||||
@ -307,6 +308,7 @@ void BOARD::Move( const VECTOR2I& aMoveVector ) // overload
|
|||||||
// @todo : anything like this elsewhere? maybe put into GENERAL_COLLECTOR class.
|
// @todo : anything like this elsewhere? maybe put into GENERAL_COLLECTOR class.
|
||||||
static const KICAD_T top_level_board_stuff[] = {
|
static const KICAD_T top_level_board_stuff[] = {
|
||||||
PCB_MARKER_T,
|
PCB_MARKER_T,
|
||||||
|
PCB_BITMAP_T,
|
||||||
PCB_TEXT_T,
|
PCB_TEXT_T,
|
||||||
PCB_TEXTBOX_T,
|
PCB_TEXTBOX_T,
|
||||||
PCB_SHAPE_T,
|
PCB_SHAPE_T,
|
||||||
@ -739,6 +741,7 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode, bool aSkipConnectivity
|
|||||||
case PCB_DIM_ORTHOGONAL_T:
|
case PCB_DIM_ORTHOGONAL_T:
|
||||||
case PCB_DIM_LEADER_T:
|
case PCB_DIM_LEADER_T:
|
||||||
case PCB_SHAPE_T:
|
case PCB_SHAPE_T:
|
||||||
|
case PCB_BITMAP_T:
|
||||||
case PCB_TEXT_T:
|
case PCB_TEXT_T:
|
||||||
case PCB_TEXTBOX_T:
|
case PCB_TEXTBOX_T:
|
||||||
case PCB_TARGET_T:
|
case PCB_TARGET_T:
|
||||||
@ -851,6 +854,7 @@ void BOARD::Remove( BOARD_ITEM* aBoardItem, REMOVE_MODE aRemoveMode )
|
|||||||
case PCB_DIM_ORTHOGONAL_T:
|
case PCB_DIM_ORTHOGONAL_T:
|
||||||
case PCB_DIM_LEADER_T:
|
case PCB_DIM_LEADER_T:
|
||||||
case PCB_SHAPE_T:
|
case PCB_SHAPE_T:
|
||||||
|
case PCB_BITMAP_T:
|
||||||
case PCB_TEXT_T:
|
case PCB_TEXT_T:
|
||||||
case PCB_TEXTBOX_T:
|
case PCB_TEXTBOX_T:
|
||||||
case PCB_TARGET_T:
|
case PCB_TARGET_T:
|
||||||
@ -1334,6 +1338,7 @@ SEARCH_RESULT BOARD::Visit( INSPECTOR inspector, void* testData, const KICAD_T s
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PCB_SHAPE_T:
|
case PCB_SHAPE_T:
|
||||||
|
case PCB_BITMAP_T:
|
||||||
case PCB_TEXT_T:
|
case PCB_TEXT_T:
|
||||||
case PCB_TEXTBOX_T:
|
case PCB_TEXTBOX_T:
|
||||||
case PCB_DIM_ALIGNED_T:
|
case PCB_DIM_ALIGNED_T:
|
||||||
@ -1350,6 +1355,7 @@ SEARCH_RESULT BOARD::Visit( INSPECTOR inspector, void* testData, const KICAD_T s
|
|||||||
switch( stype = *++p )
|
switch( stype = *++p )
|
||||||
{
|
{
|
||||||
case PCB_SHAPE_T:
|
case PCB_SHAPE_T:
|
||||||
|
case PCB_BITMAP_T:
|
||||||
case PCB_TEXT_T:
|
case PCB_TEXT_T:
|
||||||
case PCB_TEXTBOX_T:
|
case PCB_TEXTBOX_T:
|
||||||
case PCB_DIM_ALIGNED_T:
|
case PCB_DIM_ALIGNED_T:
|
||||||
|
@ -341,6 +341,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
|||||||
|
|
||||||
// Board items
|
// Board items
|
||||||
case PCB_SHAPE_T: // a shape (normally not on copper layers)
|
case PCB_SHAPE_T: // a shape (normally not on copper layers)
|
||||||
|
case PCB_BITMAP_T: // a bitmap on a user layer
|
||||||
case PCB_TEXT_T: // a text on a layer
|
case PCB_TEXT_T: // a text on a layer
|
||||||
case PCB_TEXTBOX_T: // a wrapped text on a layer
|
case PCB_TEXTBOX_T: // a wrapped text on a layer
|
||||||
case PCB_TRACE_T: // a track segment (segment on a copper layer)
|
case PCB_TRACE_T: // a track segment (segment on a copper layer)
|
||||||
|
@ -49,6 +49,7 @@ const KICAD_T GENERAL_COLLECTOR::AllBoardItems[] = {
|
|||||||
// *** all items in a same list (shown here) must be contiguous ****
|
// *** all items in a same list (shown here) must be contiguous ****
|
||||||
PCB_MARKER_T, // in m_markers
|
PCB_MARKER_T, // in m_markers
|
||||||
PCB_TEXT_T, // in m_drawings
|
PCB_TEXT_T, // in m_drawings
|
||||||
|
PCB_BITMAP_T, // in m_drawings
|
||||||
PCB_TEXTBOX_T, // in m_drawings
|
PCB_TEXTBOX_T, // in m_drawings
|
||||||
PCB_SHAPE_T, // in m_drawings
|
PCB_SHAPE_T, // in m_drawings
|
||||||
PCB_DIM_ALIGNED_T, // in m_drawings
|
PCB_DIM_ALIGNED_T, // in m_drawings
|
||||||
@ -72,6 +73,7 @@ const KICAD_T GENERAL_COLLECTOR::AllBoardItems[] = {
|
|||||||
|
|
||||||
const KICAD_T GENERAL_COLLECTOR::BoardLevelItems[] = {
|
const KICAD_T GENERAL_COLLECTOR::BoardLevelItems[] = {
|
||||||
PCB_MARKER_T,
|
PCB_MARKER_T,
|
||||||
|
PCB_BITMAP_T,
|
||||||
PCB_TEXT_T,
|
PCB_TEXT_T,
|
||||||
PCB_TEXTBOX_T,
|
PCB_TEXTBOX_T,
|
||||||
PCB_SHAPE_T,
|
PCB_SHAPE_T,
|
||||||
@ -118,6 +120,7 @@ const KICAD_T GENERAL_COLLECTOR::FootprintItems[] = {
|
|||||||
PCB_PAD_T,
|
PCB_PAD_T,
|
||||||
PCB_FP_ZONE_T,
|
PCB_FP_ZONE_T,
|
||||||
PCB_GROUP_T,
|
PCB_GROUP_T,
|
||||||
|
PCB_BITMAP_T,
|
||||||
EOT
|
EOT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -119,6 +119,10 @@ void PCB_EDIT_FRAME::OnEditItemRequest( BOARD_ITEM* aItem )
|
|||||||
{
|
{
|
||||||
switch( aItem->Type() )
|
switch( aItem->Type() )
|
||||||
{
|
{
|
||||||
|
case PCB_BITMAP_T:
|
||||||
|
ShowBitmapPropertiesDialog( aItem);
|
||||||
|
break;
|
||||||
|
|
||||||
case PCB_TEXT_T:
|
case PCB_TEXT_T:
|
||||||
case PCB_FP_TEXT_T:
|
case PCB_FP_TEXT_T:
|
||||||
ShowTextPropertiesDialog( aItem );
|
ShowTextPropertiesDialog( aItem );
|
||||||
|
@ -532,6 +532,7 @@ void FOOTPRINT::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode, bool aSkipConnectiv
|
|||||||
case PCB_FP_DIM_ORTHOGONAL_T:
|
case PCB_FP_DIM_ORTHOGONAL_T:
|
||||||
case PCB_FP_SHAPE_T:
|
case PCB_FP_SHAPE_T:
|
||||||
case PCB_FP_TEXTBOX_T:
|
case PCB_FP_TEXTBOX_T:
|
||||||
|
case PCB_BITMAP_T:
|
||||||
if( aMode == ADD_MODE::APPEND )
|
if( aMode == ADD_MODE::APPEND )
|
||||||
m_drawings.push_back( aBoardItem );
|
m_drawings.push_back( aBoardItem );
|
||||||
else
|
else
|
||||||
@ -786,7 +787,10 @@ const EDA_RECT FOOTPRINT::GetBoundingBox( bool aIncludeText, bool aIncludeInvisi
|
|||||||
|
|
||||||
for( BOARD_ITEM* item : m_drawings )
|
for( BOARD_ITEM* item : m_drawings )
|
||||||
{
|
{
|
||||||
if( !isFPEdit && m_privateLayers.test( item->GetLayer() ) )
|
// We want the bitmap bounding box just in the footprint editor
|
||||||
|
// so it will start with the correct initial zoom
|
||||||
|
if( !isFPEdit
|
||||||
|
&& ( m_privateLayers.test( item->GetLayer() ) || item->Type() != PCB_BITMAP_T ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( item->Type() != PCB_FP_TEXT_T )
|
if( item->Type() != PCB_FP_TEXT_T )
|
||||||
@ -893,7 +897,7 @@ SHAPE_POLY_SET FOOTPRINT::GetBoundingHull() const
|
|||||||
if( !isFPEdit && m_privateLayers.test( item->GetLayer() ) )
|
if( !isFPEdit && m_privateLayers.test( item->GetLayer() ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( item->Type() != PCB_FP_TEXT_T )
|
if( item->Type() != PCB_FP_TEXT_T && item->Type() != PCB_BITMAP_T )
|
||||||
{
|
{
|
||||||
item->TransformShapeWithClearanceToPolygon( rawPolys, UNDEFINED_LAYER, 0, ARC_LOW_DEF,
|
item->TransformShapeWithClearanceToPolygon( rawPolys, UNDEFINED_LAYER, 0, ARC_LOW_DEF,
|
||||||
ERROR_OUTSIDE );
|
ERROR_OUTSIDE );
|
||||||
@ -1096,10 +1100,13 @@ bool FOOTPRINT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy )
|
|||||||
{
|
{
|
||||||
// Text items are selectable on their own, and are therefore excluded from this
|
// Text items are selectable on their own, and are therefore excluded from this
|
||||||
// test. TextBox items are NOT selectable on their own, and so MUST be included
|
// test. TextBox items are NOT selectable on their own, and so MUST be included
|
||||||
// here.
|
// here. Bitmaps aren't selectable since they aren't displayed.
|
||||||
if( item->Type() != PCB_FP_TEXT_T && item->HitTest( arect, false, 0 ) )
|
if( item->Type() != PCB_FP_TEXT_T && item->Type() != PCB_FP_TEXT_T
|
||||||
|
&& item->HitTest( arect, false, 0 ) )
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Groups are not hit-tested; only their members
|
// Groups are not hit-tested; only their members
|
||||||
|
|
||||||
@ -1689,6 +1696,7 @@ void FOOTPRINT::SetPosition( const VECTOR2I& aPos )
|
|||||||
case PCB_FP_DIM_ORTHOGONAL_T:
|
case PCB_FP_DIM_ORTHOGONAL_T:
|
||||||
case PCB_FP_DIM_RADIAL_T:
|
case PCB_FP_DIM_RADIAL_T:
|
||||||
case PCB_FP_DIM_LEADER_T:
|
case PCB_FP_DIM_LEADER_T:
|
||||||
|
case PCB_BITMAP_T:
|
||||||
item->Move( delta );
|
item->Move( delta );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1181,6 +1181,7 @@ void FOOTPRINT_EDIT_FRAME::setupUIConditions()
|
|||||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawArc );
|
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawArc );
|
||||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawPolygon );
|
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawPolygon );
|
||||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawRuleArea );
|
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawRuleArea );
|
||||||
|
CURRENT_EDIT_TOOL( PCB_ACTIONS::placeImage );
|
||||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::placeText );
|
CURRENT_EDIT_TOOL( PCB_ACTIONS::placeText );
|
||||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawTextBox );
|
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawTextBox );
|
||||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawAlignedDimension );
|
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawAlignedDimension );
|
||||||
|
@ -185,6 +185,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
|
|||||||
placeMenu->Add( PCB_ACTIONS::drawRectangle );
|
placeMenu->Add( PCB_ACTIONS::drawRectangle );
|
||||||
placeMenu->Add( PCB_ACTIONS::drawCircle );
|
placeMenu->Add( PCB_ACTIONS::drawCircle );
|
||||||
placeMenu->Add( PCB_ACTIONS::drawPolygon );
|
placeMenu->Add( PCB_ACTIONS::drawPolygon );
|
||||||
|
placeMenu->Add( PCB_ACTIONS::placeImage );
|
||||||
placeMenu->Add( PCB_ACTIONS::placeText );
|
placeMenu->Add( PCB_ACTIONS::placeText );
|
||||||
placeMenu->Add( PCB_ACTIONS::drawTextBox );
|
placeMenu->Add( PCB_ACTIONS::drawTextBox );
|
||||||
|
|
||||||
|
@ -326,6 +326,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
|
|||||||
placeMenu->Add( PCB_ACTIONS::drawRectangle );
|
placeMenu->Add( PCB_ACTIONS::drawRectangle );
|
||||||
placeMenu->Add( PCB_ACTIONS::drawCircle );
|
placeMenu->Add( PCB_ACTIONS::drawCircle );
|
||||||
placeMenu->Add( PCB_ACTIONS::drawPolygon );
|
placeMenu->Add( PCB_ACTIONS::drawPolygon );
|
||||||
|
placeMenu->Add( PCB_ACTIONS::placeImage );
|
||||||
placeMenu->Add( PCB_ACTIONS::placeText );
|
placeMenu->Add( PCB_ACTIONS::placeText );
|
||||||
placeMenu->Add( PCB_ACTIONS::drawTextBox );
|
placeMenu->Add( PCB_ACTIONS::drawTextBox );
|
||||||
|
|
||||||
|
@ -172,6 +172,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
//void SetRotationAngle( EDA_ANGLE aRotationAngle );
|
//void SetRotationAngle( EDA_ANGLE aRotationAngle );
|
||||||
|
|
||||||
|
void ShowBitmapPropertiesDialog( BOARD_ITEM* aBitmap );
|
||||||
void ShowTextPropertiesDialog( BOARD_ITEM* aText );
|
void ShowTextPropertiesDialog( BOARD_ITEM* aText );
|
||||||
int ShowTextBoxPropertiesDialog( BOARD_ITEM* aText );
|
int ShowTextBoxPropertiesDialog( BOARD_ITEM* aText );
|
||||||
void ShowGraphicItemPropertiesDialog( BOARD_ITEM* aItem );
|
void ShowGraphicItemPropertiesDialog( BOARD_ITEM* aItem );
|
||||||
|
211
pcbnew/pcb_bitmap.cpp
Normal file
211
pcbnew/pcb_bitmap.cpp
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 jean-pierre.charras
|
||||||
|
* Copyright (C) 2022 Mike Williams
|
||||||
|
* Copyright (C) 2011-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file pcb_bitmap.cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pcb_draw_panel_gal.h>
|
||||||
|
#include <plotters/plotter.h>
|
||||||
|
#include <settings/color_settings.h>
|
||||||
|
#include <bitmaps.h>
|
||||||
|
#include <base_units.h>
|
||||||
|
#include <common.h>
|
||||||
|
#include <eda_draw_frame.h>
|
||||||
|
#include <core/mirror.h>
|
||||||
|
#include <pcb_bitmap.h>
|
||||||
|
#include <trigo.h>
|
||||||
|
#include <geometry/shape_rect.h>
|
||||||
|
#include <convert_to_biu.h>
|
||||||
|
|
||||||
|
#include <wx/mstream.h>
|
||||||
|
|
||||||
|
|
||||||
|
PCB_BITMAP::PCB_BITMAP( BOARD_ITEM* aParent, const VECTOR2I& pos ) :
|
||||||
|
BOARD_ITEM( aParent, PCB_BITMAP_T )
|
||||||
|
{
|
||||||
|
m_pos = pos;
|
||||||
|
m_layer = PCB_LAYER_ID::Dwgs_User; // used only to draw/plot a rectangle,
|
||||||
|
// when a bitmap cannot be drawn or plotted
|
||||||
|
m_image = new BITMAP_BASE();
|
||||||
|
m_image->SetPixelSizeIu( (float) Mils2iu( 1000 ) / m_image->GetPPI() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PCB_BITMAP::PCB_BITMAP( const PCB_BITMAP& aPCBBitmap ) : BOARD_ITEM( aPCBBitmap )
|
||||||
|
{
|
||||||
|
m_pos = aPCBBitmap.m_pos;
|
||||||
|
m_layer = aPCBBitmap.m_layer;
|
||||||
|
m_image = new BITMAP_BASE( *aPCBBitmap.m_image );
|
||||||
|
m_image->SetPixelSizeIu( (float) Mils2iu( 1000 ) / m_image->GetPPI() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PCB_BITMAP& PCB_BITMAP::operator=( const BOARD_ITEM& aItem )
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( Type() == aItem.Type(), *this,
|
||||||
|
wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " )
|
||||||
|
+ GetClass() );
|
||||||
|
|
||||||
|
if( &aItem != this )
|
||||||
|
{
|
||||||
|
BOARD_ITEM::operator=( aItem );
|
||||||
|
|
||||||
|
PCB_BITMAP* bitmap = (PCB_BITMAP*) &aItem;
|
||||||
|
|
||||||
|
delete m_image;
|
||||||
|
m_image = new BITMAP_BASE( *bitmap->m_image );
|
||||||
|
m_pos = bitmap->m_pos;
|
||||||
|
m_image->SetPixelSizeIu( Mils2iu( 1000 ) / m_image->GetPPI() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PCB_BITMAP::ReadImageFile( const wxString& aFullFilename )
|
||||||
|
{
|
||||||
|
return m_image->ReadImageFile( aFullFilename );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EDA_ITEM* PCB_BITMAP::Clone() const
|
||||||
|
{
|
||||||
|
return new PCB_BITMAP( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PCB_BITMAP::SwapData( BOARD_ITEM* aItem )
|
||||||
|
{
|
||||||
|
wxCHECK_RET( aItem->Type() == PCB_BITMAP_T,
|
||||||
|
wxString::Format( wxT( "PCB_BITMAP object cannot swap data with %s object." ),
|
||||||
|
aItem->GetClass() ) );
|
||||||
|
|
||||||
|
PCB_BITMAP* item = (PCB_BITMAP*) aItem;
|
||||||
|
std::swap( m_pos, item->m_pos );
|
||||||
|
std::swap( m_image, item->m_image );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const EDA_RECT PCB_BITMAP::GetBoundingBox() const
|
||||||
|
{
|
||||||
|
// Bitmaps are center origin, EDA_RECTs need top-left origin
|
||||||
|
VECTOR2I size = m_image->GetSize();
|
||||||
|
VECTOR2I topLeft = { m_pos.x - size.x / 2, m_pos.y - size.y / 2 };
|
||||||
|
|
||||||
|
return EDA_RECT( topLeft, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::shared_ptr<SHAPE> PCB_BITMAP::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
|
||||||
|
{
|
||||||
|
EDA_RECT box = GetBoundingBox();
|
||||||
|
return std::shared_ptr<SHAPE_RECT>(
|
||||||
|
new SHAPE_RECT( box.GetCenter(), box.GetWidth(), box.GetHeight() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const VECTOR2I PCB_BITMAP::GetSize() const
|
||||||
|
{
|
||||||
|
return m_image->GetSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PCB_BITMAP::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
|
||||||
|
{
|
||||||
|
if( aFlipLeftRight )
|
||||||
|
{
|
||||||
|
MIRROR( m_pos.x, aCentre.x );
|
||||||
|
m_image->Mirror( false );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MIRROR( m_pos.y, aCentre.y );
|
||||||
|
m_image->Mirror( true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PCB_BITMAP::Rotate( const VECTOR2I& aCenter, const EDA_ANGLE& aAngle )
|
||||||
|
{
|
||||||
|
RotatePoint( m_pos, aCenter, aAngle );
|
||||||
|
m_image->Rotate( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined( DEBUG )
|
||||||
|
void PCB_BITMAP::Show( int nestLevel, std::ostream& os ) const
|
||||||
|
{
|
||||||
|
// XML output:
|
||||||
|
wxString s = GetClass();
|
||||||
|
|
||||||
|
NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << m_pos << "/>\n";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool PCB_BITMAP::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
|
||||||
|
{
|
||||||
|
EDA_RECT rect = GetBoundingBox();
|
||||||
|
|
||||||
|
rect.Inflate( aAccuracy );
|
||||||
|
|
||||||
|
return rect.Contains( aPosition );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PCB_BITMAP::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
|
||||||
|
{
|
||||||
|
EDA_RECT rect = aRect;
|
||||||
|
|
||||||
|
rect.Inflate( aAccuracy );
|
||||||
|
|
||||||
|
if( aContained )
|
||||||
|
return rect.Contains( GetBoundingBox() );
|
||||||
|
|
||||||
|
return rect.Intersects( GetBoundingBox() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BITMAPS PCB_BITMAP::GetMenuImage() const
|
||||||
|
{
|
||||||
|
return BITMAPS::image;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PCB_BITMAP::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
|
||||||
|
{
|
||||||
|
aList.emplace_back( _( "Bitmap" ), wxEmptyString );
|
||||||
|
|
||||||
|
aList.emplace_back( _( "Width" ), MessageTextFromValue( aFrame->GetUserUnits(), GetSize().x ) );
|
||||||
|
aList.emplace_back( _( "Height" ),
|
||||||
|
MessageTextFromValue( aFrame->GetUserUnits(), GetSize().y ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PCB_BITMAP::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||||
|
{
|
||||||
|
aCount = 1;
|
||||||
|
aLayers[0] = LAYER_DRAW_BITMAPS;
|
||||||
|
}
|
133
pcbnew/pcb_bitmap.h
Normal file
133
pcbnew/pcb_bitmap.h
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 jean-pierre.charras
|
||||||
|
* Copyright (C) 2022 Mike Williams
|
||||||
|
* Copyright (C) 2011-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file pcb_bitmap.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PCB_BITMAP_H_
|
||||||
|
#define _PCB_BITMAP_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include <board_item.h>
|
||||||
|
#include <bitmap_base.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object to handle a bitmap image that can be inserted in a PCB.
|
||||||
|
*/
|
||||||
|
class PCB_BITMAP : public BOARD_ITEM
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PCB_BITMAP( BOARD_ITEM* aParent, const VECTOR2I& pos = VECTOR2I( 0, 0 ) );
|
||||||
|
|
||||||
|
PCB_BITMAP( const PCB_BITMAP& aPcbBitmap );
|
||||||
|
|
||||||
|
~PCB_BITMAP() { delete m_image; }
|
||||||
|
|
||||||
|
PCB_BITMAP& operator=( const BOARD_ITEM& aItem );
|
||||||
|
|
||||||
|
BITMAP_BASE* GetImage() const
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( m_image != nullptr, nullptr, "Invalid PCB_BITMAP init, m_image is NULL." );
|
||||||
|
return m_image;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the image "zoom" value.
|
||||||
|
* scale = 1.0 = original size of bitmap.
|
||||||
|
* scale < 1.0 = the bitmap is drawn smaller than its original size.
|
||||||
|
* scale > 1.0 = the bitmap is drawn bigger than its original size.
|
||||||
|
*/
|
||||||
|
double GetImageScale() const { return m_image->GetScale(); }
|
||||||
|
|
||||||
|
void SetImageScale( double aScale ) { m_image->SetScale( aScale ); }
|
||||||
|
|
||||||
|
static inline bool ClassOf( const EDA_ITEM* aItem )
|
||||||
|
{
|
||||||
|
return aItem && PCB_BITMAP_T == aItem->Type();
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString GetClass() const override { return wxT( "PCB_BITMAP" ); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the actual size (in user units, not in pixels) of the image.
|
||||||
|
*/
|
||||||
|
const VECTOR2I GetSize() const;
|
||||||
|
|
||||||
|
const EDA_RECT GetBoundingBox() const override;
|
||||||
|
|
||||||
|
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
|
||||||
|
FLASHING aFlash = FLASHING::DEFAULT ) const override;
|
||||||
|
|
||||||
|
void SwapData( BOARD_ITEM* aItem ) override;
|
||||||
|
|
||||||
|
//void Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset ) override;
|
||||||
|
|
||||||
|
/// @copydoc VIEW_ITEM::ViewGetLayers()
|
||||||
|
virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read and store an image file.
|
||||||
|
*
|
||||||
|
* Initialize the bitmap used to draw this item format.
|
||||||
|
*
|
||||||
|
* @param aFullFilename is the full filename of the image file to read.
|
||||||
|
* @return true if success reading else false.
|
||||||
|
*/
|
||||||
|
bool ReadImageFile( const wxString& aFullFilename );
|
||||||
|
|
||||||
|
void Move( const VECTOR2I& aMoveVector ) override { m_pos += aMoveVector; }
|
||||||
|
|
||||||
|
void Flip( const VECTOR2I& aCentre, bool aFlipLeftRight ) override;
|
||||||
|
void Rotate( const VECTOR2I& aCenter, const EDA_ANGLE& aAngle ) override;
|
||||||
|
|
||||||
|
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override
|
||||||
|
{
|
||||||
|
return wxString( _( "Image" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
BITMAPS GetMenuImage() const override;
|
||||||
|
|
||||||
|
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
|
||||||
|
|
||||||
|
VECTOR2I GetPosition() const override { return m_pos; }
|
||||||
|
void SetPosition( const VECTOR2I& aPosition ) override { m_pos = aPosition; }
|
||||||
|
|
||||||
|
bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
|
||||||
|
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
|
||||||
|
|
||||||
|
EDA_ITEM* Clone() const override;
|
||||||
|
|
||||||
|
#if defined( DEBUG )
|
||||||
|
void Show( int nestLevel, std::ostream& os ) const override;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
VECTOR2I m_pos; // XY coordinates of center of the bitmap
|
||||||
|
BITMAP_BASE* m_image; // the BITMAP_BASE item
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _PCB_BITMAP_H_
|
@ -560,6 +560,8 @@ void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_view->SetLayerTarget( LAYER_DRAW_BITMAPS, KIGFX::TARGET_NONCACHED );
|
||||||
|
|
||||||
m_view->SetLayerTarget( LAYER_ANCHOR, KIGFX::TARGET_NONCACHED );
|
m_view->SetLayerTarget( LAYER_ANCHOR, KIGFX::TARGET_NONCACHED );
|
||||||
m_view->SetLayerDisplayOnly( LAYER_ANCHOR );
|
m_view->SetLayerDisplayOnly( LAYER_ANCHOR );
|
||||||
|
|
||||||
|
@ -828,6 +828,7 @@ void PCB_EDIT_FRAME::setupUIConditions()
|
|||||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawCircle );
|
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawCircle );
|
||||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawArc );
|
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawArc );
|
||||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawPolygon );
|
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawPolygon );
|
||||||
|
CURRENT_EDIT_TOOL( PCB_ACTIONS::placeImage );
|
||||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::placeText );
|
CURRENT_EDIT_TOOL( PCB_ACTIONS::placeText );
|
||||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawTextBox );
|
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawTextBox );
|
||||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawAlignedDimension );
|
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawAlignedDimension );
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include <pcb_shape.h>
|
#include <pcb_shape.h>
|
||||||
#include <string_utils.h>
|
#include <string_utils.h>
|
||||||
#include <zone.h>
|
#include <zone.h>
|
||||||
|
#include <pcb_bitmap.h>
|
||||||
#include <pcb_text.h>
|
#include <pcb_text.h>
|
||||||
#include <pcb_textbox.h>
|
#include <pcb_textbox.h>
|
||||||
#include <pcb_marker.h>
|
#include <pcb_marker.h>
|
||||||
@ -76,6 +77,7 @@ PCB_RENDER_SETTINGS::PCB_RENDER_SETTINGS()
|
|||||||
m_viaOpacity = 1.0;
|
m_viaOpacity = 1.0;
|
||||||
m_padOpacity = 1.0;
|
m_padOpacity = 1.0;
|
||||||
m_zoneOpacity = 1.0;
|
m_zoneOpacity = 1.0;
|
||||||
|
m_bgImageOpacity = 1.0;
|
||||||
|
|
||||||
m_ForcePadSketchModeOff = false;
|
m_ForcePadSketchModeOff = false;
|
||||||
m_ForcePadSketchModeOn = false;
|
m_ForcePadSketchModeOn = false;
|
||||||
@ -147,6 +149,7 @@ void PCB_RENDER_SETTINGS::LoadDisplayOptions( const PCB_DISPLAY_OPTIONS& aOption
|
|||||||
m_viaOpacity = aOptions.m_ViaOpacity;
|
m_viaOpacity = aOptions.m_ViaOpacity;
|
||||||
m_padOpacity = aOptions.m_PadOpacity;
|
m_padOpacity = aOptions.m_PadOpacity;
|
||||||
m_zoneOpacity = aOptions.m_ZoneOpacity;
|
m_zoneOpacity = aOptions.m_ZoneOpacity;
|
||||||
|
m_bgImageOpacity = aOptions.m_BgImageOpacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -341,6 +344,8 @@ COLOR4D PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) cons
|
|||||||
color.a *= m_padOpacity;
|
color.a *= m_padOpacity;
|
||||||
else if( item->Type() == PCB_ZONE_T || item->Type() == PCB_FP_ZONE_T )
|
else if( item->Type() == PCB_ZONE_T || item->Type() == PCB_FP_ZONE_T )
|
||||||
color.a *= m_zoneOpacity;
|
color.a *= m_zoneOpacity;
|
||||||
|
else if( item->Type() == PCB_BITMAP_T )
|
||||||
|
color.a *= m_bgImageOpacity;
|
||||||
|
|
||||||
// No special modifiers enabled
|
// No special modifiers enabled
|
||||||
return color;
|
return color;
|
||||||
@ -414,7 +419,10 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
|
|||||||
{
|
{
|
||||||
FOOTPRINT* parentFP = static_cast<FOOTPRINT*>( item->GetParentFootprint() );
|
FOOTPRINT* parentFP = static_cast<FOOTPRINT*>( item->GetParentFootprint() );
|
||||||
|
|
||||||
if( item->GetLayerSet().count() > 1 )
|
// Never draw footprint bitmaps on board
|
||||||
|
if( item->Type() == PCB_BITMAP_T )
|
||||||
|
return false;
|
||||||
|
else if( item->GetLayerSet().count() > 1 )
|
||||||
{
|
{
|
||||||
// For multi-layer objects, exclude only those layers that are private
|
// For multi-layer objects, exclude only those layers that are private
|
||||||
if( IsPcbLayer( aLayer ) && parentFP->GetPrivateLayers().test( aLayer ) )
|
if( IsPcbLayer( aLayer ) && parentFP->GetPrivateLayers().test( aLayer ) )
|
||||||
@ -461,6 +469,10 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
|
|||||||
draw( static_cast<const PCB_SHAPE*>( item ), aLayer );
|
draw( static_cast<const PCB_SHAPE*>( item ), aLayer );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PCB_BITMAP_T:
|
||||||
|
draw( static_cast<const PCB_BITMAP*>( item ), aLayer );
|
||||||
|
break;
|
||||||
|
|
||||||
case PCB_TEXT_T:
|
case PCB_TEXT_T:
|
||||||
draw( static_cast<const PCB_TEXT*>( item ), aLayer );
|
draw( static_cast<const PCB_TEXT*>( item ), aLayer );
|
||||||
break;
|
break;
|
||||||
@ -1633,6 +1645,45 @@ void PCB_PAINTER::strokeText( const wxString& aText, const VECTOR2I& aPosition,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PCB_PAINTER::draw( const PCB_BITMAP* aBitmap, int aLayer )
|
||||||
|
{
|
||||||
|
m_gal->Save();
|
||||||
|
m_gal->Translate( aBitmap->GetPosition() );
|
||||||
|
|
||||||
|
// When the image scale factor is not 1.0, we need to modify the actual as the image scale
|
||||||
|
// factor is similar to a local zoom
|
||||||
|
double img_scale = aBitmap->GetImageScale();
|
||||||
|
|
||||||
|
if( img_scale != 1.0 )
|
||||||
|
m_gal->Scale( VECTOR2D( img_scale, img_scale ) );
|
||||||
|
|
||||||
|
m_gal->DrawBitmap( *aBitmap->GetImage(), m_pcbSettings.m_bgImageOpacity );
|
||||||
|
|
||||||
|
if( aBitmap->IsSelected() || aBitmap->IsBrightened() )
|
||||||
|
{
|
||||||
|
COLOR4D color = m_pcbSettings.GetColor( aBitmap, LAYER_ANCHOR );
|
||||||
|
m_gal->SetIsStroke( true );
|
||||||
|
m_gal->SetStrokeColor( color );
|
||||||
|
m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth * 2.0f );
|
||||||
|
m_gal->SetIsFill( false );
|
||||||
|
|
||||||
|
// Draws a bounding box.
|
||||||
|
VECTOR2D bm_size( aBitmap->GetSize() );
|
||||||
|
// bm_size is the actual image size in UI.
|
||||||
|
// but m_gal scale was previously set to img_scale
|
||||||
|
// so recalculate size relative to this image size.
|
||||||
|
bm_size.x /= img_scale;
|
||||||
|
bm_size.y /= img_scale;
|
||||||
|
VECTOR2D origin( -bm_size.x / 2.0, -bm_size.y / 2.0 );
|
||||||
|
VECTOR2D end = origin + bm_size;
|
||||||
|
|
||||||
|
m_gal->DrawRectangle( origin, end );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_gal->Restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PCB_PAINTER::draw( const PCB_TEXT* aText, int aLayer )
|
void PCB_PAINTER::draw( const PCB_TEXT* aText, int aLayer )
|
||||||
{
|
{
|
||||||
wxString resolvedText( aText->GetShownText() );
|
wxString resolvedText( aText->GetShownText() );
|
||||||
|
@ -46,6 +46,7 @@ class PCB_SHAPE;
|
|||||||
class PCB_GROUP;
|
class PCB_GROUP;
|
||||||
class FOOTPRINT;
|
class FOOTPRINT;
|
||||||
class ZONE;
|
class ZONE;
|
||||||
|
class PCB_BITMAP;
|
||||||
class PCB_TEXT;
|
class PCB_TEXT;
|
||||||
class PCB_TEXTBOX;
|
class PCB_TEXTBOX;
|
||||||
class FP_TEXT;
|
class FP_TEXT;
|
||||||
@ -142,6 +143,7 @@ protected:
|
|||||||
double m_viaOpacity; ///< Opacity override for all types of via
|
double m_viaOpacity; ///< Opacity override for all types of via
|
||||||
double m_padOpacity; ///< Opacity override for SMD pads and PTHs
|
double m_padOpacity; ///< Opacity override for SMD pads and PTHs
|
||||||
double m_zoneOpacity; ///< Opacity override for filled zones
|
double m_zoneOpacity; ///< Opacity override for filled zones
|
||||||
|
double m_bgImageOpacity; ///< Opacity override for background images
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -169,6 +171,7 @@ protected:
|
|||||||
void draw( const PCB_VIA* aVia, int aLayer );
|
void draw( const PCB_VIA* aVia, int aLayer );
|
||||||
void draw( const PAD* aPad, int aLayer );
|
void draw( const PAD* aPad, int aLayer );
|
||||||
void draw( const PCB_SHAPE* aSegment, int aLayer );
|
void draw( const PCB_SHAPE* aSegment, int aLayer );
|
||||||
|
void draw( const PCB_BITMAP* aBitmap, int aLayer );
|
||||||
void draw( const PCB_TEXT* aText, int aLayer );
|
void draw( const PCB_TEXT* aText, int aLayer );
|
||||||
void draw( const PCB_TEXTBOX* aText, int aLayer );
|
void draw( const PCB_TEXTBOX* aText, int aLayer );
|
||||||
void draw( const FP_TEXT* aText, int aLayer );
|
void draw( const FP_TEXT* aText, int aLayer );
|
||||||
|
@ -106,6 +106,7 @@ bool PCB_EDIT_FRAME::LoadProjectSettings()
|
|||||||
opts.m_PadOpacity = localSettings.m_PadOpacity;
|
opts.m_PadOpacity = localSettings.m_PadOpacity;
|
||||||
opts.m_ZoneOpacity = localSettings.m_ZoneOpacity;
|
opts.m_ZoneOpacity = localSettings.m_ZoneOpacity;
|
||||||
opts.m_ZoneDisplayMode = localSettings.m_ZoneDisplayMode;
|
opts.m_ZoneDisplayMode = localSettings.m_ZoneDisplayMode;
|
||||||
|
opts.m_BgImageOpacity = localSettings.m_BgImageOpacity;
|
||||||
|
|
||||||
// No refresh here: callers of LoadProjectSettings refresh later
|
// No refresh here: callers of LoadProjectSettings refresh later
|
||||||
SetDisplayOptions( opts, false );
|
SetDisplayOptions( opts, false );
|
||||||
@ -159,6 +160,7 @@ void PCB_EDIT_FRAME::SaveProjectSettings()
|
|||||||
localSettings.m_PadOpacity = displayOpts.m_PadOpacity;
|
localSettings.m_PadOpacity = displayOpts.m_PadOpacity;
|
||||||
localSettings.m_ZoneOpacity = displayOpts.m_ZoneOpacity;
|
localSettings.m_ZoneOpacity = displayOpts.m_ZoneOpacity;
|
||||||
localSettings.m_ZoneDisplayMode = displayOpts.m_ZoneDisplayMode;
|
localSettings.m_ZoneDisplayMode = displayOpts.m_ZoneDisplayMode;
|
||||||
|
localSettings.m_BgImageOpacity = displayOpts.m_BgImageOpacity;
|
||||||
|
|
||||||
// Save Design settings
|
// Save Design settings
|
||||||
const BOARD_DESIGN_SETTINGS& bds = GetDesignSettings();
|
const BOARD_DESIGN_SETTINGS& bds = GetDesignSettings();
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include <fp_textbox.h>
|
#include <fp_textbox.h>
|
||||||
#include <pcb_dimension.h>
|
#include <pcb_dimension.h>
|
||||||
#include <pcb_shape.h>
|
#include <pcb_shape.h>
|
||||||
|
#include <pcb_bitmap.h>
|
||||||
#include <pcb_group.h>
|
#include <pcb_group.h>
|
||||||
#include <pcb_target.h>
|
#include <pcb_target.h>
|
||||||
#include <pcb_track.h>
|
#include <pcb_track.h>
|
||||||
@ -63,6 +64,12 @@
|
|||||||
#include <progress_reporter.h>
|
#include <progress_reporter.h>
|
||||||
#include <board_stackup_manager/stackup_predefined_prms.h>
|
#include <board_stackup_manager/stackup_predefined_prms.h>
|
||||||
|
|
||||||
|
// For some reason wxWidgets is built with wxUSE_BASE64 unset so expose the wxWidgets
|
||||||
|
// base64 code. Needed for PCB_BITMAP
|
||||||
|
#define wxUSE_BASE64 1
|
||||||
|
#include <wx/base64.h>
|
||||||
|
#include <wx/mstream.h>
|
||||||
|
|
||||||
using namespace PCB_KEYS_T;
|
using namespace PCB_KEYS_T;
|
||||||
|
|
||||||
|
|
||||||
@ -851,6 +858,12 @@ BOARD* PCB_PARSER::parseBOARD_unchecked()
|
|||||||
bulkAddedItems.push_back( item );
|
bulkAddedItems.push_back( item );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_image:
|
||||||
|
item = parsePCB_BITMAP( m_board );
|
||||||
|
m_board->Add( item, ADD_MODE::BULK_APPEND, true );
|
||||||
|
bulkAddedItems.push_back( item );
|
||||||
|
break;
|
||||||
|
|
||||||
case T_gr_text:
|
case T_gr_text:
|
||||||
item = parsePCB_TEXT();
|
item = parsePCB_TEXT();
|
||||||
m_board->Add( item, ADD_MODE::BULK_APPEND, true );
|
m_board->Add( item, ADD_MODE::BULK_APPEND, true );
|
||||||
@ -2836,6 +2849,80 @@ PCB_SHAPE* PCB_PARSER::parsePCB_SHAPE()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PCB_BITMAP* PCB_PARSER::parsePCB_BITMAP( BOARD_ITEM* aParent )
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( CurTok() == T_image, nullptr,
|
||||||
|
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as an image." ) );
|
||||||
|
|
||||||
|
T token;
|
||||||
|
std::unique_ptr<PCB_BITMAP> bitmap = std::make_unique<PCB_BITMAP>( aParent );
|
||||||
|
|
||||||
|
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||||
|
{
|
||||||
|
if( token != T_LEFT )
|
||||||
|
Expecting( T_LEFT );
|
||||||
|
|
||||||
|
token = NextTok();
|
||||||
|
|
||||||
|
switch( token )
|
||||||
|
{
|
||||||
|
case T_at:
|
||||||
|
{
|
||||||
|
VECTOR2I pos;
|
||||||
|
pos.x = parseBoardUnits( "X coordinate" );
|
||||||
|
pos.y = parseBoardUnits( "Y coordinate" );
|
||||||
|
bitmap->SetPosition( pos );
|
||||||
|
NeedRIGHT();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case T_scale:
|
||||||
|
bitmap->GetImage()->SetScale( parseDouble( "image scale factor" ) );
|
||||||
|
|
||||||
|
if( !std::isnormal( bitmap->GetImage()->GetScale() ) )
|
||||||
|
bitmap->GetImage()->SetScale( 1.0 );
|
||||||
|
|
||||||
|
NeedRIGHT();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_data:
|
||||||
|
{
|
||||||
|
token = NextTok();
|
||||||
|
|
||||||
|
wxString data;
|
||||||
|
|
||||||
|
// Reserve 128K because most image files are going to be larger than the default
|
||||||
|
// 1K that wxString reserves.
|
||||||
|
data.reserve( 1 << 17 );
|
||||||
|
|
||||||
|
while( token != T_RIGHT )
|
||||||
|
{
|
||||||
|
if( !IsSymbol( token ) )
|
||||||
|
Expecting( "base64 image data" );
|
||||||
|
|
||||||
|
data += FromUTF8();
|
||||||
|
token = NextTok();
|
||||||
|
}
|
||||||
|
|
||||||
|
wxMemoryBuffer buffer = wxBase64Decode( data );
|
||||||
|
wxMemoryOutputStream stream( buffer.GetData(), buffer.GetBufSize() );
|
||||||
|
wxImage* image = new wxImage();
|
||||||
|
wxMemoryInputStream istream( stream );
|
||||||
|
image->LoadFile( istream, wxBITMAP_TYPE_PNG );
|
||||||
|
bitmap->GetImage()->SetImage( image );
|
||||||
|
bitmap->GetImage()->SetBitmap( new wxBitmap( *image ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
Expecting( "at, scale, data" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bitmap.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PCB_TEXT* PCB_PARSER::parsePCB_TEXT()
|
PCB_TEXT* PCB_PARSER::parsePCB_TEXT()
|
||||||
{
|
{
|
||||||
wxCHECK_MSG( CurTok() == T_gr_text, nullptr,
|
wxCHECK_MSG( CurTok() == T_gr_text, nullptr,
|
||||||
@ -3784,6 +3871,13 @@ FOOTPRINT* PCB_PARSER::parseFOOTPRINT_unchecked( wxArrayString* aInitialComments
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case T_image:
|
||||||
|
{
|
||||||
|
PCB_BITMAP* image = parsePCB_BITMAP( footprint.get() );
|
||||||
|
footprint->Add( image, ADD_MODE::APPEND, true );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case T_dimension:
|
case T_dimension:
|
||||||
{
|
{
|
||||||
PCB_DIMENSION_BASE* dimension = parseDIMENSION( footprint.get(), true );
|
PCB_DIMENSION_BASE* dimension = parseDIMENSION( footprint.get(), true );
|
||||||
|
@ -49,6 +49,7 @@ class PAD;
|
|||||||
class BOARD_DESIGN_SETTINGS;
|
class BOARD_DESIGN_SETTINGS;
|
||||||
class PCB_DIMENSION_BASE;
|
class PCB_DIMENSION_BASE;
|
||||||
class PCB_SHAPE;
|
class PCB_SHAPE;
|
||||||
|
class PCB_BITMAP;
|
||||||
class EDA_TEXT;
|
class EDA_TEXT;
|
||||||
class FP_SHAPE;
|
class FP_SHAPE;
|
||||||
class FP_TEXT;
|
class FP_TEXT;
|
||||||
@ -176,6 +177,7 @@ private:
|
|||||||
|
|
||||||
PCB_SHAPE* parsePCB_SHAPE();
|
PCB_SHAPE* parsePCB_SHAPE();
|
||||||
PCB_TEXT* parsePCB_TEXT();
|
PCB_TEXT* parsePCB_TEXT();
|
||||||
|
PCB_BITMAP* parsePCB_BITMAP( BOARD_ITEM* aParent );
|
||||||
PCB_TEXTBOX* parsePCB_TEXTBOX();
|
PCB_TEXTBOX* parsePCB_TEXTBOX();
|
||||||
PCB_DIMENSION_BASE* parseDIMENSION( BOARD_ITEM* aParent, bool aInFP );
|
PCB_DIMENSION_BASE* parseDIMENSION( BOARD_ITEM* aParent, bool aInFP );
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include <pad.h>
|
#include <pad.h>
|
||||||
#include <pcb_group.h>
|
#include <pcb_group.h>
|
||||||
#include <pcb_shape.h>
|
#include <pcb_shape.h>
|
||||||
|
#include <pcb_bitmap.h>
|
||||||
#include <pcb_target.h>
|
#include <pcb_target.h>
|
||||||
#include <pcb_text.h>
|
#include <pcb_text.h>
|
||||||
#include <pcb_textbox.h>
|
#include <pcb_textbox.h>
|
||||||
@ -57,6 +58,13 @@
|
|||||||
#include <zone.h>
|
#include <zone.h>
|
||||||
#include <zones.h>
|
#include <zones.h>
|
||||||
|
|
||||||
|
// For some reason wxWidgets is built with wxUSE_BASE64 unset so expose the wxWidgets
|
||||||
|
// base64 code. Needed for PCB_BITMAP
|
||||||
|
#define wxUSE_BASE64 1
|
||||||
|
#include <wx/base64.h>
|
||||||
|
#include <wx/mstream.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace PCB_KEYS_T;
|
using namespace PCB_KEYS_T;
|
||||||
|
|
||||||
|
|
||||||
@ -418,6 +426,10 @@ void PCB_PLUGIN::Format( const BOARD_ITEM* aItem, int aNestLevel ) const
|
|||||||
format( static_cast<const PCB_SHAPE*>( aItem ), aNestLevel );
|
format( static_cast<const PCB_SHAPE*>( aItem ), aNestLevel );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PCB_BITMAP_T:
|
||||||
|
format( static_cast<const PCB_BITMAP*>( aItem ), aNestLevel );
|
||||||
|
break;
|
||||||
|
|
||||||
case PCB_FP_SHAPE_T:
|
case PCB_FP_SHAPE_T:
|
||||||
format( static_cast<const FP_SHAPE*>( aItem ), aNestLevel );
|
format( static_cast<const FP_SHAPE*>( aItem ), aNestLevel );
|
||||||
break;
|
break;
|
||||||
@ -996,6 +1008,52 @@ void PCB_PLUGIN::format( const PCB_SHAPE* aShape, int aNestLevel ) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PCB_PLUGIN::format( const PCB_BITMAP* aBitmap, int aNestLevel ) const
|
||||||
|
{
|
||||||
|
wxCHECK_RET( aBitmap != nullptr && m_out != nullptr, "" );
|
||||||
|
|
||||||
|
const wxImage* image = aBitmap->GetImage()->GetImageData();
|
||||||
|
|
||||||
|
wxCHECK_RET( image != nullptr, "wxImage* is NULL" );
|
||||||
|
|
||||||
|
m_out->Print( aNestLevel, "(image (at %s %s)",
|
||||||
|
FormatInternalUnits( aBitmap->GetPosition().x ).c_str(),
|
||||||
|
FormatInternalUnits( aBitmap->GetPosition().y ).c_str() );
|
||||||
|
|
||||||
|
if( aBitmap->GetImage()->GetScale() != 1.0 )
|
||||||
|
m_out->Print( 0, " (scale %g)", aBitmap->GetImage()->GetScale() );
|
||||||
|
|
||||||
|
m_out->Print( 0, "\n" );
|
||||||
|
|
||||||
|
m_out->Print( aNestLevel + 1, "(data" );
|
||||||
|
|
||||||
|
wxMemoryOutputStream stream;
|
||||||
|
|
||||||
|
image->SaveFile( stream, wxBITMAP_TYPE_PNG );
|
||||||
|
|
||||||
|
// Write binary data in hexadecimal form (ASCII)
|
||||||
|
wxStreamBuffer* buffer = stream.GetOutputStreamBuffer();
|
||||||
|
wxString out = wxBase64Encode( buffer->GetBufferStart(), buffer->GetBufferSize() );
|
||||||
|
|
||||||
|
// Apparently the MIME standard character width for base64 encoding is 76 (unconfirmed)
|
||||||
|
// so use it in a vein attempt to be standard like.
|
||||||
|
#define MIME_BASE64_LENGTH 76
|
||||||
|
|
||||||
|
size_t first = 0;
|
||||||
|
|
||||||
|
while( first < out.Length() )
|
||||||
|
{
|
||||||
|
m_out->Print( 0, "\n" );
|
||||||
|
m_out->Print( aNestLevel + 2, "%s", TO_UTF8( out( first, MIME_BASE64_LENGTH ) ) );
|
||||||
|
first += MIME_BASE64_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_out->Print( 0, "\n" );
|
||||||
|
m_out->Print( aNestLevel + 1, ")\n" ); // Closes data token.
|
||||||
|
m_out->Print( aNestLevel, ")\n" ); // Closes image token.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PCB_PLUGIN::format( const FP_SHAPE* aFPShape, int aNestLevel ) const
|
void PCB_PLUGIN::format( const FP_SHAPE* aFPShape, int aNestLevel ) const
|
||||||
{
|
{
|
||||||
std::string locked = aFPShape->IsLocked() ? " locked" : "";
|
std::string locked = aFPShape->IsLocked() ? " locked" : "";
|
||||||
|
@ -39,6 +39,7 @@ class BOARD_DESIGN_SETTINGS;
|
|||||||
class PCB_DIMENSION_BASE;
|
class PCB_DIMENSION_BASE;
|
||||||
class FP_SHAPE;
|
class FP_SHAPE;
|
||||||
class PCB_SHAPE;
|
class PCB_SHAPE;
|
||||||
|
class PCB_BITMAP;
|
||||||
class PCB_TARGET;
|
class PCB_TARGET;
|
||||||
class PAD;
|
class PAD;
|
||||||
class FP_TEXT;
|
class FP_TEXT;
|
||||||
@ -122,7 +123,8 @@ class SHAPE_LINE_CHAIN;
|
|||||||
//#define SEXPR_BOARD_FILE_VERSION 20220331 // Plot on all layers selection setting
|
//#define SEXPR_BOARD_FILE_VERSION 20220331 // Plot on all layers selection setting
|
||||||
//#define SEXPR_BOARD_FILE_VERSION 20220417 // Automatic dimension precisions
|
//#define SEXPR_BOARD_FILE_VERSION 20220417 // Automatic dimension precisions
|
||||||
//#define SEXPR_BOARD_FILE_VERSION 20220427 // Exclude Edge.Cuts & Margin from fp private layers
|
//#define SEXPR_BOARD_FILE_VERSION 20220427 // Exclude Edge.Cuts & Margin from fp private layers
|
||||||
#define SEXPR_BOARD_FILE_VERSION 20220609 // Add teardrop keywords to identify teardrop zones
|
//#define SEXPR_BOARD_FILE_VERSION 20220609 // Add teardrop keywords to identify teardrop zones
|
||||||
|
#define SEXPR_BOARD_FILE_VERSION 20220621 // Add Image support
|
||||||
|
|
||||||
#define BOARD_FILE_HOST_VERSION 20200825 ///< Earlier files than this include the host tag
|
#define BOARD_FILE_HOST_VERSION 20200825 ///< Earlier files than this include the host tag
|
||||||
#define LEGACY_ARC_FORMATTING 20210925 ///< These were the last to use old arc formatting
|
#define LEGACY_ARC_FORMATTING 20210925 ///< These were the last to use old arc formatting
|
||||||
@ -281,6 +283,8 @@ private:
|
|||||||
|
|
||||||
void format( const FP_SHAPE* aFPShape, int aNestLevel = 0 ) const;
|
void format( const FP_SHAPE* aFPShape, int aNestLevel = 0 ) const;
|
||||||
|
|
||||||
|
void format( const PCB_BITMAP* aBitmap, int aNestLevel = 0 ) const;
|
||||||
|
|
||||||
void format( const PCB_GROUP* aGroup, int aNestLevel = 0 ) const;
|
void format( const PCB_GROUP* aGroup, int aNestLevel = 0 ) const;
|
||||||
|
|
||||||
void format( const PCB_SHAPE* aSegment, int aNestLevel = 0 ) const;
|
void format( const PCB_SHAPE* aSegment, int aNestLevel = 0 ) const;
|
||||||
|
7
pcbnew/python/swig/pcb_bitmap.i
Normal file
7
pcbnew/python/swig/pcb_bitmap.i
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
%include pcb_bitmap.h
|
||||||
|
%{
|
||||||
|
#include <pcb_bitmap.h>
|
||||||
|
%}
|
||||||
|
|
@ -185,6 +185,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateVToolbar()
|
|||||||
m_drawToolBar->Add( PCB_ACTIONS::drawRectangle, ACTION_TOOLBAR::TOGGLE );
|
m_drawToolBar->Add( PCB_ACTIONS::drawRectangle, ACTION_TOOLBAR::TOGGLE );
|
||||||
m_drawToolBar->Add( PCB_ACTIONS::drawCircle, ACTION_TOOLBAR::TOGGLE );
|
m_drawToolBar->Add( PCB_ACTIONS::drawCircle, ACTION_TOOLBAR::TOGGLE );
|
||||||
m_drawToolBar->Add( PCB_ACTIONS::drawPolygon, ACTION_TOOLBAR::TOGGLE );
|
m_drawToolBar->Add( PCB_ACTIONS::drawPolygon, ACTION_TOOLBAR::TOGGLE );
|
||||||
|
m_drawToolBar->Add( PCB_ACTIONS::placeImage, ACTION_TOOLBAR::TOGGLE );
|
||||||
m_drawToolBar->Add( PCB_ACTIONS::placeText, ACTION_TOOLBAR::TOGGLE );
|
m_drawToolBar->Add( PCB_ACTIONS::placeText, ACTION_TOOLBAR::TOGGLE );
|
||||||
m_drawToolBar->Add( PCB_ACTIONS::drawTextBox, ACTION_TOOLBAR::TOGGLE );
|
m_drawToolBar->Add( PCB_ACTIONS::drawTextBox, ACTION_TOOLBAR::TOGGLE );
|
||||||
m_drawToolBar->AddGroup( dimensionGroup, ACTION_TOOLBAR::TOGGLE );
|
m_drawToolBar->AddGroup( dimensionGroup, ACTION_TOOLBAR::TOGGLE );
|
||||||
|
@ -458,6 +458,7 @@ void PCB_EDIT_FRAME::ReCreateVToolbar()
|
|||||||
m_drawToolBar->Add( PCB_ACTIONS::drawRectangle, ACTION_TOOLBAR::TOGGLE );
|
m_drawToolBar->Add( PCB_ACTIONS::drawRectangle, ACTION_TOOLBAR::TOGGLE );
|
||||||
m_drawToolBar->Add( PCB_ACTIONS::drawCircle, ACTION_TOOLBAR::TOGGLE );
|
m_drawToolBar->Add( PCB_ACTIONS::drawCircle, ACTION_TOOLBAR::TOGGLE );
|
||||||
m_drawToolBar->Add( PCB_ACTIONS::drawPolygon, ACTION_TOOLBAR::TOGGLE );
|
m_drawToolBar->Add( PCB_ACTIONS::drawPolygon, ACTION_TOOLBAR::TOGGLE );
|
||||||
|
m_drawToolBar->Add( PCB_ACTIONS::placeImage, ACTION_TOOLBAR::TOGGLE );
|
||||||
m_drawToolBar->Add( PCB_ACTIONS::placeText, ACTION_TOOLBAR::TOGGLE );
|
m_drawToolBar->Add( PCB_ACTIONS::placeText, ACTION_TOOLBAR::TOGGLE );
|
||||||
m_drawToolBar->Add( PCB_ACTIONS::drawTextBox, ACTION_TOOLBAR::TOGGLE );
|
m_drawToolBar->Add( PCB_ACTIONS::drawTextBox, ACTION_TOOLBAR::TOGGLE );
|
||||||
m_drawToolBar->AddGroup( dimensionGroup, ACTION_TOOLBAR::TOGGLE );
|
m_drawToolBar->AddGroup( dimensionGroup, ACTION_TOOLBAR::TOGGLE );
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include <view/view.h>
|
#include <view/view.h>
|
||||||
#include <widgets/appearance_controls.h>
|
#include <widgets/appearance_controls.h>
|
||||||
#include <widgets/infobar.h>
|
#include <widgets/infobar.h>
|
||||||
|
#include <wx/filedlg.h>
|
||||||
|
|
||||||
#include <bitmaps.h>
|
#include <bitmaps.h>
|
||||||
#include <board.h>
|
#include <board.h>
|
||||||
@ -61,6 +62,7 @@
|
|||||||
#include <painter.h>
|
#include <painter.h>
|
||||||
#include <pcb_edit_frame.h>
|
#include <pcb_edit_frame.h>
|
||||||
#include <pcb_group.h>
|
#include <pcb_group.h>
|
||||||
|
#include <pcb_bitmap.h>
|
||||||
#include <pcb_text.h>
|
#include <pcb_text.h>
|
||||||
#include <pcb_textbox.h>
|
#include <pcb_textbox.h>
|
||||||
#include <pcb_dimension.h>
|
#include <pcb_dimension.h>
|
||||||
@ -524,6 +526,237 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent )
|
||||||
|
{
|
||||||
|
if( m_inDrawingTool )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
REENTRANCY_GUARD guard( &m_inDrawingTool );
|
||||||
|
|
||||||
|
PCB_BITMAP* image = aEvent.Parameter<PCB_BITMAP*>();
|
||||||
|
bool immediateMode = image != nullptr;
|
||||||
|
PCB_GRID_HELPER grid( m_toolMgr, m_frame->GetMagneticItemsSettings() );
|
||||||
|
bool ignorePrimePosition = false;
|
||||||
|
COMMON_SETTINGS* common_settings = Pgm().GetCommonSettings();
|
||||||
|
|
||||||
|
VECTOR2I cursorPos = getViewControls()->GetCursorPosition();
|
||||||
|
auto selectionTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
|
||||||
|
BOARD_COMMIT commit( m_frame );
|
||||||
|
|
||||||
|
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||||
|
|
||||||
|
// Add all the drawable symbols to preview
|
||||||
|
if( image )
|
||||||
|
{
|
||||||
|
image->SetPosition( cursorPos );
|
||||||
|
m_view->ClearPreview();
|
||||||
|
m_view->AddToPreview( image->Clone() );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string tool = aEvent.GetCommandStr().get();
|
||||||
|
m_frame->PushTool( tool );
|
||||||
|
auto setCursor =
|
||||||
|
[&]()
|
||||||
|
{
|
||||||
|
if( image )
|
||||||
|
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::MOVING );
|
||||||
|
else
|
||||||
|
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
|
||||||
|
};
|
||||||
|
|
||||||
|
auto cleanup =
|
||||||
|
[&] ()
|
||||||
|
{
|
||||||
|
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||||
|
m_view->ClearPreview();
|
||||||
|
delete image;
|
||||||
|
image = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
Activate();
|
||||||
|
|
||||||
|
// Must be done after Activate() so that it gets set into the correct context
|
||||||
|
getViewControls()->ShowCursor( true );
|
||||||
|
|
||||||
|
// Set initial cursor
|
||||||
|
setCursor();
|
||||||
|
|
||||||
|
// Prime the pump
|
||||||
|
if( image )
|
||||||
|
{
|
||||||
|
m_toolMgr->RunAction( ACTIONS::refreshPreview );
|
||||||
|
}
|
||||||
|
else if( aEvent.HasPosition() )
|
||||||
|
{
|
||||||
|
m_toolMgr->PrimeTool( aEvent.Position() );
|
||||||
|
}
|
||||||
|
else if( common_settings->m_Input.immediate_actions && !aEvent.IsReactivate() )
|
||||||
|
{
|
||||||
|
m_toolMgr->PrimeTool( { 0, 0 } );
|
||||||
|
ignorePrimePosition = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main loop: keep receiving events
|
||||||
|
while( TOOL_EVENT* evt = Wait() )
|
||||||
|
{
|
||||||
|
setCursor();
|
||||||
|
cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() );
|
||||||
|
|
||||||
|
if( evt->IsCancelInteractive() )
|
||||||
|
{
|
||||||
|
if( image )
|
||||||
|
{
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_frame->PopTool( tool );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( immediateMode )
|
||||||
|
{
|
||||||
|
m_frame->PopTool( tool );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( evt->IsActivate() )
|
||||||
|
{
|
||||||
|
if( image && evt->IsMoveTool() )
|
||||||
|
{
|
||||||
|
// We're already moving our own item; ignore the move tool
|
||||||
|
evt->SetPassEvent( false );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( image )
|
||||||
|
{
|
||||||
|
m_frame->ShowInfoBarMsg( _( "Press <ESC> to cancel image creation." ) );
|
||||||
|
evt->SetPassEvent( false );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( evt->IsMoveTool() )
|
||||||
|
{
|
||||||
|
// Leave ourselves on the stack so we come back after the move
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_frame->PopTool( tool );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) )
|
||||||
|
{
|
||||||
|
if( !image )
|
||||||
|
{
|
||||||
|
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||||
|
|
||||||
|
wxFileDialog dlg( m_frame, _( "Choose Image" ), wxEmptyString, wxEmptyString,
|
||||||
|
_( "Image Files" ) + wxS( " " ) + wxImage::GetImageExtWildcard(),
|
||||||
|
wxFD_OPEN );
|
||||||
|
|
||||||
|
if( dlg.ShowModal() != wxID_OK )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If we started with a hotkey which has a position then warp back to that.
|
||||||
|
// Otherwise update to the current mouse position pinned inside the autoscroll
|
||||||
|
// boundaries.
|
||||||
|
if( evt->IsPrime() && !ignorePrimePosition )
|
||||||
|
{
|
||||||
|
cursorPos = grid.Align( evt->Position() );
|
||||||
|
getViewControls()->WarpMouseCursor( cursorPos, true );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
getViewControls()->PinCursorInsideNonAutoscrollArea( true );
|
||||||
|
cursorPos = getViewControls()->GetMousePosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
cursorPos = getViewControls()->GetMousePosition( true );
|
||||||
|
|
||||||
|
wxString fullFilename = dlg.GetPath();
|
||||||
|
|
||||||
|
if( wxFileExists( fullFilename ) )
|
||||||
|
image = new PCB_BITMAP( m_frame->GetModel(), cursorPos );
|
||||||
|
|
||||||
|
if( !image || !image->ReadImageFile( fullFilename ) )
|
||||||
|
{
|
||||||
|
wxMessageBox( _( "Could not load image from '%s'." ), fullFilename );
|
||||||
|
delete image;
|
||||||
|
image = nullptr;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
image->SetFlags( IS_NEW | IS_MOVING );
|
||||||
|
image->SetLayer( m_frame->GetActiveLayer() );
|
||||||
|
|
||||||
|
m_view->ClearPreview();
|
||||||
|
m_view->AddToPreview( image->Clone() );
|
||||||
|
m_view->RecacheAllItems(); // Bitmaps are cached in Opengl
|
||||||
|
selectionTool->AddItemToSel( image, false );
|
||||||
|
|
||||||
|
getViewControls()->SetCursorPosition( cursorPos, false );
|
||||||
|
setCursor();
|
||||||
|
m_view->ShowPreview( true );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
commit.Add( image );
|
||||||
|
commit.Push( _( "Place an image" ) );
|
||||||
|
|
||||||
|
m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, image );
|
||||||
|
|
||||||
|
image = nullptr;
|
||||||
|
m_toolMgr->RunAction( ACTIONS::activatePointEditor );
|
||||||
|
|
||||||
|
m_view->ClearPreview();
|
||||||
|
|
||||||
|
if( immediateMode )
|
||||||
|
{
|
||||||
|
m_frame->PopTool( tool );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( evt->IsClick( BUT_RIGHT ) )
|
||||||
|
{
|
||||||
|
// Warp after context menu only if dragging...
|
||||||
|
if( !image )
|
||||||
|
m_toolMgr->VetoContextMenuMouseWarp();
|
||||||
|
|
||||||
|
m_menu.ShowContextMenu( selectionTool->GetSelection() );
|
||||||
|
}
|
||||||
|
else if( image && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
|
||||||
|
{
|
||||||
|
image->SetPosition( cursorPos );
|
||||||
|
m_view->ClearPreview();
|
||||||
|
m_view->AddToPreview( image->Clone() );
|
||||||
|
m_view->RecacheAllItems(); // Bitmaps are cached in Opengl
|
||||||
|
}
|
||||||
|
else if( image && evt->IsAction( &ACTIONS::doDelete ) )
|
||||||
|
{
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
evt->SetPassEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable autopanning and cursor capture only when there is an image to be placed
|
||||||
|
getViewControls()->SetAutoPan( image != nullptr );
|
||||||
|
getViewControls()->CaptureCursor( image != nullptr );
|
||||||
|
}
|
||||||
|
|
||||||
|
getViewControls()->SetAutoPan( false );
|
||||||
|
getViewControls()->CaptureCursor( false );
|
||||||
|
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
if( m_isFootprintEditor && !m_frame->GetModel() )
|
if( m_isFootprintEditor && !m_frame->GetModel() )
|
||||||
@ -3004,6 +3237,7 @@ void DRAWING_TOOL::setTransitions()
|
|||||||
Go( &DRAWING_TOOL::DrawZone, PCB_ACTIONS::drawZoneCutout.MakeEvent() );
|
Go( &DRAWING_TOOL::DrawZone, PCB_ACTIONS::drawZoneCutout.MakeEvent() );
|
||||||
Go( &DRAWING_TOOL::DrawZone, PCB_ACTIONS::drawSimilarZone.MakeEvent() );
|
Go( &DRAWING_TOOL::DrawZone, PCB_ACTIONS::drawSimilarZone.MakeEvent() );
|
||||||
Go( &DRAWING_TOOL::DrawVia, PCB_ACTIONS::drawVia.MakeEvent() );
|
Go( &DRAWING_TOOL::DrawVia, PCB_ACTIONS::drawVia.MakeEvent() );
|
||||||
|
Go( &DRAWING_TOOL::PlaceImage, PCB_ACTIONS::placeImage.MakeEvent() );
|
||||||
Go( &DRAWING_TOOL::PlaceText, PCB_ACTIONS::placeText.MakeEvent() );
|
Go( &DRAWING_TOOL::PlaceText, PCB_ACTIONS::placeText.MakeEvent() );
|
||||||
Go( &DRAWING_TOOL::DrawRectangle, PCB_ACTIONS::drawTextBox.MakeEvent() );
|
Go( &DRAWING_TOOL::DrawRectangle, PCB_ACTIONS::drawTextBox.MakeEvent() );
|
||||||
Go( &DRAWING_TOOL::PlaceImportedGraphics, PCB_ACTIONS::placeImportedGraphics.MakeEvent() );
|
Go( &DRAWING_TOOL::PlaceImportedGraphics, PCB_ACTIONS::placeImportedGraphics.MakeEvent() );
|
||||||
|
@ -67,6 +67,7 @@ public:
|
|||||||
RECTANGLE,
|
RECTANGLE,
|
||||||
CIRCLE,
|
CIRCLE,
|
||||||
ARC,
|
ARC,
|
||||||
|
IMAGE,
|
||||||
TEXT,
|
TEXT,
|
||||||
ANCHOR,
|
ANCHOR,
|
||||||
DXF,
|
DXF,
|
||||||
@ -135,6 +136,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
int DrawArc( const TOOL_EVENT& aEvent );
|
int DrawArc( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a dialog that allows one to select and image then decide where to place the
|
||||||
|
* image in the editor.
|
||||||
|
*/
|
||||||
|
int PlaceImage( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a dialog that allows one to input text and its settings and then lets the user
|
* Display a dialog that allows one to input text and its settings and then lets the user
|
||||||
* decide where to place the text in editor.
|
* decide where to place the text in editor.
|
||||||
|
@ -1757,6 +1757,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
|
|||||||
case PCB_FOOTPRINT_T:
|
case PCB_FOOTPRINT_T:
|
||||||
case PCB_TEXT_T:
|
case PCB_TEXT_T:
|
||||||
case PCB_TEXTBOX_T:
|
case PCB_TEXTBOX_T:
|
||||||
|
case PCB_BITMAP_T:
|
||||||
case PCB_SHAPE_T:
|
case PCB_SHAPE_T:
|
||||||
case PCB_TRACE_T:
|
case PCB_TRACE_T:
|
||||||
case PCB_ARC_T:
|
case PCB_ARC_T:
|
||||||
|
@ -117,6 +117,11 @@ TOOL_ACTION PCB_ACTIONS::placeStackup( "pcbnew.InteractiveDrawing.placeStackup",
|
|||||||
_( "Add a board stackup table on a graphic layer" ),
|
_( "Add a board stackup table on a graphic layer" ),
|
||||||
BITMAPS::INVALID_BITMAP, AF_ACTIVATE );
|
BITMAPS::INVALID_BITMAP, AF_ACTIVATE );
|
||||||
|
|
||||||
|
TOOL_ACTION PCB_ACTIONS::placeImage( "pcbnew.InteractiveDrawing.placeImage",
|
||||||
|
AS_GLOBAL, 0, "",
|
||||||
|
_( "Add Image" ), _( "Add bitmap image" ),
|
||||||
|
BITMAPS::image, AF_ACTIVATE );
|
||||||
|
|
||||||
TOOL_ACTION PCB_ACTIONS::placeText( "pcbnew.InteractiveDrawing.text",
|
TOOL_ACTION PCB_ACTIONS::placeText( "pcbnew.InteractiveDrawing.text",
|
||||||
AS_GLOBAL,
|
AS_GLOBAL,
|
||||||
MD_SHIFT + MD_CTRL + 'T', LEGACY_HK_NAME( "Add Text" ),
|
MD_SHIFT + MD_CTRL + 'T', LEGACY_HK_NAME( "Add Text" ),
|
||||||
|
@ -146,6 +146,7 @@ public:
|
|||||||
static TOOL_ACTION drawRectangle;
|
static TOOL_ACTION drawRectangle;
|
||||||
static TOOL_ACTION drawCircle;
|
static TOOL_ACTION drawCircle;
|
||||||
static TOOL_ACTION drawArc;
|
static TOOL_ACTION drawArc;
|
||||||
|
static TOOL_ACTION placeImage;
|
||||||
static TOOL_ACTION placeText;
|
static TOOL_ACTION placeText;
|
||||||
static TOOL_ACTION drawTextBox;
|
static TOOL_ACTION drawTextBox;
|
||||||
static TOOL_ACTION drawAlignedDimension;
|
static TOOL_ACTION drawAlignedDimension;
|
||||||
|
@ -41,6 +41,7 @@ using namespace std::placeholders;
|
|||||||
#include <pcb_edit_frame.h>
|
#include <pcb_edit_frame.h>
|
||||||
#include <fp_shape.h>
|
#include <fp_shape.h>
|
||||||
#include <fp_textbox.h>
|
#include <fp_textbox.h>
|
||||||
|
#include <pcb_bitmap.h>
|
||||||
#include <pcb_dimension.h>
|
#include <pcb_dimension.h>
|
||||||
#include <pcb_textbox.h>
|
#include <pcb_textbox.h>
|
||||||
#include <pad.h>
|
#include <pad.h>
|
||||||
@ -191,6 +192,20 @@ std::shared_ptr<EDIT_POINTS> PCB_POINT_EDITOR::makePoints( EDA_ITEM* aItem )
|
|||||||
// Generate list of edit points basing on the item type
|
// Generate list of edit points basing on the item type
|
||||||
switch( aItem->Type() )
|
switch( aItem->Type() )
|
||||||
{
|
{
|
||||||
|
case PCB_BITMAP_T:
|
||||||
|
{
|
||||||
|
PCB_BITMAP* bitmap = (PCB_BITMAP*) aItem;
|
||||||
|
VECTOR2I topLeft = bitmap->GetPosition() - bitmap->GetSize() / 2;
|
||||||
|
VECTOR2I botRight = bitmap->GetPosition() + bitmap->GetSize() / 2;
|
||||||
|
|
||||||
|
points->AddPoint( topLeft );
|
||||||
|
points->AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
|
||||||
|
points->AddPoint( botRight );
|
||||||
|
points->AddPoint( VECTOR2I( topLeft.x, botRight.y ) );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case PCB_TEXTBOX_T:
|
case PCB_TEXTBOX_T:
|
||||||
case PCB_FP_TEXTBOX_T:
|
case PCB_FP_TEXTBOX_T:
|
||||||
case PCB_SHAPE_T:
|
case PCB_SHAPE_T:
|
||||||
@ -1076,6 +1091,29 @@ void PCB_POINT_EDITOR::updateItem() const
|
|||||||
|
|
||||||
switch( item->Type() )
|
switch( item->Type() )
|
||||||
{
|
{
|
||||||
|
case PCB_BITMAP_T:
|
||||||
|
{
|
||||||
|
PCB_BITMAP* bitmap = (PCB_BITMAP*) item;
|
||||||
|
VECTOR2I topLeft = m_editPoints->Point( RECT_TOP_LEFT ).GetPosition();
|
||||||
|
VECTOR2I topRight = m_editPoints->Point( RECT_TOP_RIGHT ).GetPosition();
|
||||||
|
VECTOR2I botLeft = m_editPoints->Point( RECT_BOT_LEFT ).GetPosition();
|
||||||
|
VECTOR2I botRight = m_editPoints->Point( RECT_BOT_RIGHT ).GetPosition();
|
||||||
|
|
||||||
|
pinEditedCorner( topLeft, topRight, botLeft, botRight );
|
||||||
|
|
||||||
|
double oldWidth = bitmap->GetSize().x;
|
||||||
|
double newWidth = std::max( topRight.x - topLeft.x, Mils2iu( 50 ) );
|
||||||
|
double widthRatio = newWidth / oldWidth;
|
||||||
|
|
||||||
|
double oldHeight = bitmap->GetSize().y;
|
||||||
|
double newHeight = std::max( botLeft.y - topLeft.y, Mils2iu( 50 ) );
|
||||||
|
double heightRatio = newHeight / oldHeight;
|
||||||
|
|
||||||
|
bitmap->SetImageScale( bitmap->GetImageScale() * std::min( widthRatio, heightRatio ) );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case PCB_TEXTBOX_T:
|
case PCB_TEXTBOX_T:
|
||||||
case PCB_FP_TEXTBOX_T:
|
case PCB_FP_TEXTBOX_T:
|
||||||
case PCB_SHAPE_T:
|
case PCB_SHAPE_T:
|
||||||
@ -1646,6 +1684,20 @@ void PCB_POINT_EDITOR::updatePoints()
|
|||||||
|
|
||||||
switch( item->Type() )
|
switch( item->Type() )
|
||||||
{
|
{
|
||||||
|
case PCB_BITMAP_T:
|
||||||
|
{
|
||||||
|
PCB_BITMAP* bitmap = (PCB_BITMAP*) item;
|
||||||
|
VECTOR2I topLeft = bitmap->GetPosition() - bitmap->GetSize() / 2;
|
||||||
|
VECTOR2I botRight = bitmap->GetPosition() + bitmap->GetSize() / 2;
|
||||||
|
|
||||||
|
m_editPoints->Point( RECT_TOP_LEFT ).SetPosition( topLeft );
|
||||||
|
m_editPoints->Point( RECT_TOP_RIGHT ).SetPosition( botRight.x, topLeft.y );
|
||||||
|
m_editPoints->Point( RECT_BOT_LEFT ).SetPosition( topLeft.x, botRight.y );
|
||||||
|
m_editPoints->Point( RECT_BOT_RIGHT ).SetPosition( botRight );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case PCB_TEXTBOX_T:
|
case PCB_TEXTBOX_T:
|
||||||
case PCB_FP_TEXTBOX_T:
|
case PCB_FP_TEXTBOX_T:
|
||||||
{
|
{
|
||||||
|
@ -33,6 +33,7 @@ using namespace std::placeholders;
|
|||||||
#include <board_design_settings.h>
|
#include <board_design_settings.h>
|
||||||
#include <board_item.h>
|
#include <board_item.h>
|
||||||
#include <clipper.hpp>
|
#include <clipper.hpp>
|
||||||
|
#include <pcb_bitmap.h>
|
||||||
#include <pcb_track.h>
|
#include <pcb_track.h>
|
||||||
#include <footprint.h>
|
#include <footprint.h>
|
||||||
#include <pad.h>
|
#include <pad.h>
|
||||||
@ -2720,6 +2721,11 @@ void PCB_SELECTION_TOOL::GuessSelectionCandidates( GENERAL_COLLECTOR& aCollector
|
|||||||
// segments underneath them -- so artificially reduce their size from πr² to 1.5r².
|
// segments underneath them -- so artificially reduce their size from πr² to 1.5r².
|
||||||
area = SEG::Square( static_cast<PCB_VIA*>( item )->GetDrill() / 2 ) * 1.5;
|
area = SEG::Square( static_cast<PCB_VIA*>( item )->GetDrill() / 2 ) * 1.5;
|
||||||
}
|
}
|
||||||
|
else if( item->Type() == PCB_BITMAP_T )
|
||||||
|
{
|
||||||
|
VECTOR2I size = static_cast<const PCB_BITMAP*>( item )->GetSize();
|
||||||
|
area = size.x * size.y;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -336,6 +336,7 @@ const APPEARANCE_CONTROLS::APPEARANCE_SETTING APPEARANCE_CONTROLS::s_objectSetti
|
|||||||
RR( _HKI( "Vias" ), LAYER_VIAS, _HKI( "Show all vias" ), true ),
|
RR( _HKI( "Vias" ), LAYER_VIAS, _HKI( "Show all vias" ), true ),
|
||||||
RR( _HKI( "Pads" ), LAYER_PADS, _HKI( "Show all pads" ), true ),
|
RR( _HKI( "Pads" ), LAYER_PADS, _HKI( "Show all pads" ), true ),
|
||||||
RR( _HKI( "Zones" ), LAYER_ZONES, _HKI( "Show copper zones" ), true ),
|
RR( _HKI( "Zones" ), LAYER_ZONES, _HKI( "Show copper zones" ), true ),
|
||||||
|
RR( _HKI( "Background Images" ), LAYER_DRAW_BITMAPS, _HKI( "Show user background images" ), true ),
|
||||||
RR(),
|
RR(),
|
||||||
RR( _HKI( "Footprints Front" ), LAYER_MOD_FR, _HKI( "Show footprints that are on board's front" ) ),
|
RR( _HKI( "Footprints Front" ), LAYER_MOD_FR, _HKI( "Show footprints that are on board's front" ) ),
|
||||||
RR( _HKI( "Footprints Back" ), LAYER_MOD_BK, _HKI( "Show footprints that are on board's back" ) ),
|
RR( _HKI( "Footprints Back" ), LAYER_MOD_BK, _HKI( "Show footprints that are on board's back" ) ),
|
||||||
@ -371,6 +372,7 @@ static std::set<int> s_allowedInFpEditor =
|
|||||||
LAYER_MOD_REFERENCES,
|
LAYER_MOD_REFERENCES,
|
||||||
LAYER_MOD_TEXT,
|
LAYER_MOD_TEXT,
|
||||||
LAYER_MOD_TEXT_INVISIBLE,
|
LAYER_MOD_TEXT_INVISIBLE,
|
||||||
|
LAYER_DRAW_BITMAPS,
|
||||||
LAYER_GRID
|
LAYER_GRID
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2204,12 +2206,14 @@ void APPEARANCE_CONTROLS::syncObjectSettings()
|
|||||||
wxASSERT( m_objectSettingsMap.count( LAYER_TRACKS )
|
wxASSERT( m_objectSettingsMap.count( LAYER_TRACKS )
|
||||||
&& m_objectSettingsMap.count( LAYER_VIAS )
|
&& m_objectSettingsMap.count( LAYER_VIAS )
|
||||||
&& m_objectSettingsMap.count( LAYER_PADS )
|
&& m_objectSettingsMap.count( LAYER_PADS )
|
||||||
&& m_objectSettingsMap.count( LAYER_ZONES ) );
|
&& m_objectSettingsMap.count( LAYER_ZONES )
|
||||||
|
&& m_objectSettingsMap.count( LAYER_DRAW_BITMAPS ) );
|
||||||
|
|
||||||
m_objectSettingsMap[LAYER_TRACKS]->ctl_opacity->SetValue( opts.m_TrackOpacity * 100 );
|
m_objectSettingsMap[LAYER_TRACKS]->ctl_opacity->SetValue( opts.m_TrackOpacity * 100 );
|
||||||
m_objectSettingsMap[LAYER_VIAS]->ctl_opacity->SetValue( opts.m_ViaOpacity * 100 );
|
m_objectSettingsMap[LAYER_VIAS]->ctl_opacity->SetValue( opts.m_ViaOpacity * 100 );
|
||||||
m_objectSettingsMap[LAYER_PADS]->ctl_opacity->SetValue( opts.m_PadOpacity * 100 );
|
m_objectSettingsMap[LAYER_PADS]->ctl_opacity->SetValue( opts.m_PadOpacity * 100 );
|
||||||
m_objectSettingsMap[LAYER_ZONES]->ctl_opacity->SetValue( opts.m_ZoneOpacity * 100 );
|
m_objectSettingsMap[LAYER_ZONES]->ctl_opacity->SetValue( opts.m_ZoneOpacity * 100 );
|
||||||
|
m_objectSettingsMap[LAYER_DRAW_BITMAPS]->ctl_opacity->SetValue( opts.m_BgImageOpacity * 100 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2842,6 +2846,7 @@ void APPEARANCE_CONTROLS::onObjectOpacitySlider( int aLayer, float aOpacity )
|
|||||||
case static_cast<int>( LAYER_VIAS ): options.m_ViaOpacity = aOpacity; break;
|
case static_cast<int>( LAYER_VIAS ): options.m_ViaOpacity = aOpacity; break;
|
||||||
case static_cast<int>( LAYER_PADS ): options.m_PadOpacity = aOpacity; break;
|
case static_cast<int>( LAYER_PADS ): options.m_PadOpacity = aOpacity; break;
|
||||||
case static_cast<int>( LAYER_ZONES ): options.m_ZoneOpacity = aOpacity; break;
|
case static_cast<int>( LAYER_ZONES ): options.m_ZoneOpacity = aOpacity; break;
|
||||||
|
case static_cast<int>( LAYER_DRAW_BITMAPS ): options.m_BgImageOpacity = aOpacity; break;
|
||||||
default: return;
|
default: return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user