diff --git a/common/import_gfx/dxf_import_plugin.cpp b/common/import_gfx/dxf_import_plugin.cpp index 6701d32955..a34817c3d9 100644 --- a/common/import_gfx/dxf_import_plugin.cpp +++ b/common/import_gfx/dxf_import_plugin.cpp @@ -178,6 +178,16 @@ double DXF_IMPORT_PLUGIN::GetImageHeight() const } +BOX2D DXF_IMPORT_PLUGIN::GetImageBBox() const +{ + BOX2D bbox; + bbox.SetOrigin( m_minX, m_minY ); + bbox.SetEnd( m_maxX, m_maxY ); + + return bbox; +} + + void DXF_IMPORT_PLUGIN::SetImporter( GRAPHICS_IMPORTER* aImporter ) { GRAPHICS_IMPORT_PLUGIN::SetImporter( aImporter ); diff --git a/common/import_gfx/dxf_import_plugin.h b/common/import_gfx/dxf_import_plugin.h index e26ea6830d..9a520d5fda 100644 --- a/common/import_gfx/dxf_import_plugin.h +++ b/common/import_gfx/dxf_import_plugin.h @@ -236,6 +236,7 @@ public: double GetImageWidth() const override; double GetImageHeight() const override; + BOX2D GetImageBBox() const override; void updateImageLimits( const VECTOR2D& aPoint ); diff --git a/common/import_gfx/graphics_import_plugin.h b/common/import_gfx/graphics_import_plugin.h index 103c6b7be3..c6189505db 100644 --- a/common/import_gfx/graphics_import_plugin.h +++ b/common/import_gfx/graphics_import_plugin.h @@ -27,6 +27,7 @@ #ifndef GRAPHICS_IMPORT_PLUGIN_H #define GRAPHICS_IMPORT_PLUGIN_H +#include <math/box2.h> #include <wildcards_and_files_ext.h> #include <wx/arrstr.h> @@ -112,6 +113,13 @@ public: */ virtual double GetImageWidth() const = 0; + /** + * Return image bounding box from original imported file. + * + * @return Image bounding box. + */ + virtual BOX2D GetImageBBox() const = 0; + /** * Actually imports the file. * diff --git a/common/import_gfx/graphics_importer.cpp b/common/import_gfx/graphics_importer.cpp index 6158b1dff8..5b2230796e 100644 --- a/common/import_gfx/graphics_importer.cpp +++ b/common/import_gfx/graphics_importer.cpp @@ -2,6 +2,8 @@ * This program source code file is part of KICAD, a free EDA CAD application. * * Copyright (C) 2016 CERN + * Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors. + * * @author Maciej Suminski <maciej.suminski@cern.ch> * * This program is free software; you can redistribute it and/or @@ -30,13 +32,13 @@ GRAPHICS_IMPORTER::GRAPHICS_IMPORTER() { m_millimeterToIu = 1.0; m_lineWidth = DEFAULT_LINE_WIDTH_DFX; - m_scale = 1.0; + m_scale = VECTOR2D( 1.0, 1.0 ); m_originalWidth = 0.0; m_originalHeight = 0.0; } -bool GRAPHICS_IMPORTER::Load( const wxString &aFileName ) +bool GRAPHICS_IMPORTER::Load( const wxString& aFileName ) { m_items.clear(); @@ -48,10 +50,19 @@ bool GRAPHICS_IMPORTER::Load( const wxString &aFileName ) m_plugin->SetImporter( this ); - return m_plugin->Load( aFileName ); + bool ret = m_plugin->Load( aFileName ); + + if( ret ) + { + m_originalWidth = m_plugin->GetImageWidth(); + m_originalHeight = m_plugin->GetImageHeight(); + } + + return ret; } -bool GRAPHICS_IMPORTER::Import( double aScale ) + +bool GRAPHICS_IMPORTER::Import( const VECTOR2D& aScale ) { if( !m_plugin ) { diff --git a/common/import_gfx/graphics_importer.h b/common/import_gfx/graphics_importer.h index 640ae48771..a4236dbbff 100644 --- a/common/import_gfx/graphics_importer.h +++ b/common/import_gfx/graphics_importer.h @@ -2,7 +2,7 @@ * This program source code file is part of KICAD, a free EDA CAD application. * * Copyright (C) 2016 CERN - * Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors. * * @author Maciej Suminski <maciej.suminski@cern.ch> * @@ -32,6 +32,7 @@ #include <eda_text.h> #include <math/vector2d.h> +#include <gal/color4d.h> #include <list> #include <memory> @@ -81,9 +82,9 @@ public: * It is important to have the file loaded before importing. * * @param aScale allow import graphic items with a non 1:1 import ratio - * aScale = 1.0 to import graphics with their actual size. + * VECTOR2D( 1.0, 1.0 ) to import graphics with their actual size. */ - bool Import( double aScale = 1.0 ); + bool Import( const VECTOR2D& aScale = VECTOR2D( 1.0, 1.0 ) ); /** * Collect warning and error messages after loading/importing. @@ -134,7 +135,7 @@ public: /** * @return the scale factor affecting the imported shapes. */ - double GetScale() const + VECTOR2D GetScale() const { return m_scale; } @@ -160,7 +161,7 @@ public: * * This allows conversion between imported shapes units and millimeters. */ - void SetScale( double aScale ) + void SetScale( const VECTOR2D& aScale ) { m_scale = aScale; } @@ -176,7 +177,7 @@ public: /** * @return the overall scale factor to convert the imported shapes dimension to mm. */ - double ImportScalingFactor() const + VECTOR2D ImportScalingFactor() const { return m_scale * m_millimeterToIu; } @@ -208,8 +209,10 @@ public: * @param aOrigin is the segment origin point expressed in mm. * @param aEnd is the segment end point expressed in mm. * @param aWidth is the segment thickness in mm. Use -1 for default line thickness + * @param aColor is the shape color */ - virtual void AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd, double aWidth ) = 0; + virtual void AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd, double aWidth, + const COLOR4D& aColor ) = 0; /** * Create an object representing a circle. @@ -217,9 +220,10 @@ public: * @param aCenter is the circle center point expressed in mm. * @param aRadius is the circle radius expressed in mm. * @param aWidth is the segment thickness in mm. Use -1 for default line thickness + * @param aColor is the shape color */ - virtual void AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth, - bool aFilled ) = 0; + virtual void AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth, bool aFilled, + const COLOR4D& aColor ) = 0; /** * Create an object representing an arc. @@ -229,11 +233,13 @@ public: * Its length is the arc radius. * @param aAngle is the arc angle. * @param aWidth is the segment thickness in mm. Use -1 for default line thickness + * @param aColor is the shape color */ virtual void AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, const EDA_ANGLE& aAngle, - double aWidth ) = 0; + double aWidth, const COLOR4D& aColor ) = 0; - virtual void AddPolygon( const std::vector< VECTOR2D >& aVertices, double aWidth ) = 0; + virtual void AddPolygon( const std::vector<VECTOR2D>& aVertices, double aWidth, + const COLOR4D& aColor ) = 0; /** * Create an object representing a text. @@ -246,10 +252,12 @@ public: * @param aHJustify is the text horizontal justification. * @param aVJustify is the text vertical justification. * @param aWidth is the segment thickness in mm. Use -1 for default line thickness + * @param aColor is the shape color */ virtual void AddText( const VECTOR2D& aOrigin, const wxString& aText, double aHeight, double aWidth, double aThickness, double aOrientation, - GR_TEXT_H_ALIGN_T aHJustify, GR_TEXT_V_ALIGN_T aVJustify ) = 0; + GR_TEXT_H_ALIGN_T aHJustify, GR_TEXT_V_ALIGN_T aVJustify, + const COLOR4D& aColor ) = 0; /** * Create an object representing an arc. @@ -259,10 +267,11 @@ public: * @param aBezierControl2 is the second Bezier control point expressed in mm. * @param aEnd is the curve end point expressed in mm. * @param aWidth is the segment thickness in mm. Use -1 for default line thickness + * @param aColor is the shape color */ virtual void AddSpline( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1, - const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, - double aWidth ) = 0; + const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, double aWidth, + const COLOR4D& aColor ) = 0; protected: ///< Add an item to the imported shapes list. @@ -297,7 +306,7 @@ private: * 1.0 does not change the size of imported items * scale < 1.0 reduce the size of imported items */ - double m_scale; + VECTOR2D m_scale; ///< Default line thickness for the imported graphics double m_lineWidth; diff --git a/common/import_gfx/graphics_importer_buffer.cpp b/common/import_gfx/graphics_importer_buffer.cpp index 3084436ecb..36d9ab47d6 100644 --- a/common/import_gfx/graphics_importer_buffer.cpp +++ b/common/import_gfx/graphics_importer_buffer.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KICAD, a free EDA CAD application. * * Copyright (C) 2017 CERN - * Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2021-2023 KiCad Developers, see AUTHORS.txt for contributors. * @author Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * * This program is free software; you can redistribute it and/or @@ -38,28 +38,32 @@ static std::unique_ptr<T> make_shape( const Args&... aArguments ) return std::make_unique<T>( aArguments... ); } -void GRAPHICS_IMPORTER_BUFFER::AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd, double aWidth ) +void GRAPHICS_IMPORTER_BUFFER::AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd, double aWidth, + const COLOR4D& aColor ) { - m_shapes.push_back( make_shape< IMPORTED_LINE >( aStart, aEnd, aWidth ) ); + m_shapes.push_back( make_shape< IMPORTED_LINE >( aStart, aEnd, aWidth, aColor ) ); } -void GRAPHICS_IMPORTER_BUFFER::AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth, bool aFilled ) +void GRAPHICS_IMPORTER_BUFFER::AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth, + bool aFilled, const COLOR4D& aColor ) { - m_shapes.push_back( make_shape<IMPORTED_CIRCLE>( aCenter, aRadius, aWidth, aFilled ) ); + m_shapes.push_back( make_shape<IMPORTED_CIRCLE>( aCenter, aRadius, aWidth, aFilled, aColor ) ); } void GRAPHICS_IMPORTER_BUFFER::AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, - const EDA_ANGLE& aAngle, double aWidth ) + const EDA_ANGLE& aAngle, double aWidth, + const COLOR4D& aColor ) { - m_shapes.push_back( make_shape<IMPORTED_ARC>( aCenter, aStart, aAngle, aWidth ) ); + m_shapes.push_back( make_shape<IMPORTED_ARC>( aCenter, aStart, aAngle, aWidth, aColor ) ); } -void GRAPHICS_IMPORTER_BUFFER::AddPolygon( const std::vector< VECTOR2D >& aVertices, double aWidth ) +void GRAPHICS_IMPORTER_BUFFER::AddPolygon( const std::vector<VECTOR2D>& aVertices, double aWidth, + const COLOR4D& aColor ) { - m_shapes.push_back( make_shape<IMPORTED_POLYGON>( aVertices, aWidth ) ); + m_shapes.push_back( make_shape<IMPORTED_POLYGON>( aVertices, aWidth, aColor ) ); m_shapes.back()->SetParentShapeIndex( m_shapeFillRules.size() - 1 ); } @@ -67,17 +71,18 @@ void GRAPHICS_IMPORTER_BUFFER::AddPolygon( const std::vector< VECTOR2D >& aVerti void GRAPHICS_IMPORTER_BUFFER::AddText( const VECTOR2D& aOrigin, const wxString& aText, double aHeight, double aWidth, double aThickness, double aOrientation, GR_TEXT_H_ALIGN_T aHJustify, - GR_TEXT_V_ALIGN_T aVJustify ) + GR_TEXT_V_ALIGN_T aVJustify, const COLOR4D& aColor ) { m_shapes.push_back( make_shape< IMPORTED_TEXT >( aOrigin, aText, aHeight, aWidth, - aThickness, aOrientation, aHJustify, aVJustify ) ); + aThickness, aOrientation, aHJustify, aVJustify, aColor ) ); } void GRAPHICS_IMPORTER_BUFFER::AddSpline( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1, - const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd , double aWidth ) + const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, + double aWidth, const COLOR4D& aColor ) { - m_shapes.push_back( make_shape<IMPORTED_SPLINE>( aStart, aBezierControl1, aBezierControl2, aEnd, aWidth ) ); + m_shapes.push_back( make_shape<IMPORTED_SPLINE>( aStart, aBezierControl1, aBezierControl2, aEnd, aWidth, aColor ) ); } @@ -96,8 +101,8 @@ void GRAPHICS_IMPORTER_BUFFER::ImportTo( GRAPHICS_IMPORTER& aImporter ) // converts a single SVG-style polygon (multiple outlines, hole detection based on orientation, custom fill rule) to a format that can be digested by KiCad (single outline, fractured) static void convertPolygon( std::list<std::unique_ptr<IMPORTED_SHAPE>>& aShapes, std::vector<IMPORTED_POLYGON*>& aPaths, - GRAPHICS_IMPORTER::POLY_FILL_RULE aFillRule, - double aWidth ) + GRAPHICS_IMPORTER::POLY_FILL_RULE aFillRule, double aWidth, + const COLOR4D& aColor ) { double minX = std::numeric_limits<double>::max(); double minY = minX; @@ -165,15 +170,16 @@ static void convertPolygon( std::list<std::unique_ptr<IMPORTED_SHAPE>>& aShapes, pts.emplace_back( VECTOR2D( xp, yp ) ); } - aShapes.push_back( std::make_unique<IMPORTED_POLYGON>( pts, aWidth ) ); + aShapes.push_back( std::make_unique<IMPORTED_POLYGON>( pts, aWidth, aColor ) ); } } void GRAPHICS_IMPORTER_BUFFER::PostprocessNestedPolygons() { - int curShapeIdx = -1; - double lastWidth = 0; + int curShapeIdx = -1; + double lastWidth = 0; + COLOR4D lastColor = COLOR4D::UNSPECIFIED; std::list<std::unique_ptr<IMPORTED_SHAPE>> newShapes; std::vector<IMPORTED_POLYGON*> polypaths; @@ -192,17 +198,19 @@ void GRAPHICS_IMPORTER_BUFFER::PostprocessNestedPolygons() if( index != curShapeIdx && curShapeIdx >= 0 ) { - convertPolygon( newShapes, polypaths, m_shapeFillRules[curShapeIdx], lastWidth ); + convertPolygon( newShapes, polypaths, m_shapeFillRules[curShapeIdx], lastWidth, + lastColor ); polypaths.clear(); } curShapeIdx = index; lastWidth = poly->GetWidth(); + lastColor = poly->GetColor(); polypaths.push_back( poly ); } if( curShapeIdx >= 0 ) - convertPolygon( newShapes, polypaths, m_shapeFillRules[curShapeIdx], lastWidth ); + convertPolygon( newShapes, polypaths, m_shapeFillRules[curShapeIdx], lastWidth, lastColor ); m_shapes.swap( newShapes ); } diff --git a/common/import_gfx/graphics_importer_buffer.h b/common/import_gfx/graphics_importer_buffer.h index 52c2cb372d..26889e7acf 100644 --- a/common/import_gfx/graphics_importer_buffer.h +++ b/common/import_gfx/graphics_importer_buffer.h @@ -2,7 +2,7 @@ * This program source code file is part of KICAD, a free EDA CAD application. * * Copyright (C) 2017 CERN - * Copyright (C) 2018-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2018-2023 KiCad Developers, see AUTHORS.txt for contributors. * * @author Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com> * @@ -53,16 +53,16 @@ protected: class IMPORTED_LINE : public IMPORTED_SHAPE { public: - IMPORTED_LINE( const VECTOR2D& aStart, const VECTOR2D& aEnd, double aWidth ) : + IMPORTED_LINE( const VECTOR2D& aStart, const VECTOR2D& aEnd, double aWidth, + const COLOR4D& aColor ) : m_start( aStart ), - m_end( aEnd ), - m_width( aWidth ) + m_end( aEnd ), m_width( aWidth ), m_color( aColor ) { } void ImportTo( GRAPHICS_IMPORTER& aImporter ) const override { - aImporter.AddLine( m_start, m_end, m_width ); + aImporter.AddLine( m_start, m_end, m_width, m_color ); } virtual std::unique_ptr<IMPORTED_SHAPE> clone() const override @@ -80,23 +80,23 @@ private: VECTOR2D m_start; VECTOR2D m_end; double m_width; + COLOR4D m_color; }; class IMPORTED_CIRCLE : public IMPORTED_SHAPE { public: - IMPORTED_CIRCLE( const VECTOR2D& aCenter, double aRadius, double aWidth, bool aFilled ) : + IMPORTED_CIRCLE( const VECTOR2D& aCenter, double aRadius, double aWidth, bool aFilled, + const COLOR4D& aColor ) : m_center( aCenter ), - m_radius( aRadius ), - m_width( aWidth ), - m_filled( aFilled ) + m_radius( aRadius ), m_width( aWidth ), m_filled( aFilled ), m_color( aColor ) { } void ImportTo( GRAPHICS_IMPORTER& aImporter ) const override { - aImporter.AddCircle( m_center, m_radius, m_width, m_filled ); + aImporter.AddCircle( m_center, m_radius, m_width, m_filled, m_color ); } virtual std::unique_ptr<IMPORTED_SHAPE> clone() const override @@ -120,6 +120,7 @@ private: double m_radius; double m_width; bool m_filled; + COLOR4D m_color; }; @@ -127,17 +128,15 @@ class IMPORTED_ARC : public IMPORTED_SHAPE { public: IMPORTED_ARC( const VECTOR2D& aCenter, const VECTOR2D& aStart, const EDA_ANGLE& aAngle, - double aWidth ) : + double aWidth, const COLOR4D& aColor ) : m_center( aCenter ), - m_start( aStart ), - m_angle( aAngle ), - m_width( aWidth ) + m_start( aStart ), m_angle( aAngle ), m_width( aWidth ), m_color( aColor ) { } void ImportTo( GRAPHICS_IMPORTER& aImporter ) const override { - aImporter.AddArc( m_center, m_start, m_angle, m_width ); + aImporter.AddArc( m_center, m_start, m_angle, m_width, m_color ); } virtual std::unique_ptr<IMPORTED_SHAPE> clone() const override @@ -156,21 +155,23 @@ private: VECTOR2D m_start; EDA_ANGLE m_angle; double m_width; + COLOR4D m_color; }; class IMPORTED_POLYGON : public IMPORTED_SHAPE { public: - IMPORTED_POLYGON( const std::vector< VECTOR2D >& aVertices, double aWidth ) : + IMPORTED_POLYGON( const std::vector<VECTOR2D>& aVertices, double aWidth, + const COLOR4D& aColor ) : m_vertices( aVertices ), - m_width( aWidth ) + m_width( aWidth ), m_color( aColor ) { } void ImportTo( GRAPHICS_IMPORTER& aImporter ) const override { - aImporter.AddPolygon( m_vertices, m_width ); + aImporter.AddPolygon( m_vertices, m_width, m_color ); } virtual std::unique_ptr<IMPORTED_SHAPE> clone() const override @@ -190,9 +191,12 @@ public: double GetWidth() const { return m_width; } + const COLOR4D& GetColor() const { return m_color; } + private: std::vector<VECTOR2D> m_vertices; double m_width; + COLOR4D m_color; }; @@ -201,22 +205,18 @@ class IMPORTED_TEXT : public IMPORTED_SHAPE public: IMPORTED_TEXT( const VECTOR2D& aOrigin, const wxString& aText, double aHeight, double aWidth, double aThickness, double aOrientation, GR_TEXT_H_ALIGN_T aHJustify, - GR_TEXT_V_ALIGN_T aVJustify ) : - m_origin( aOrigin ), - m_text( aText ), - m_height( aHeight ), - m_width( aWidth ), - m_thickness( aThickness ), - m_orientation( aOrientation ), - m_hJustify( aHJustify ), - m_vJustify( aVJustify ) + GR_TEXT_V_ALIGN_T aVJustify, const COLOR4D& aColor ) : + m_origin( aOrigin ), + m_text( aText ), m_height( aHeight ), m_width( aWidth ), m_thickness( aThickness ), + m_orientation( aOrientation ), m_hJustify( aHJustify ), m_vJustify( aVJustify ), + m_color( aColor ) { } void ImportTo( GRAPHICS_IMPORTER& aImporter ) const override { - aImporter.AddText( m_origin, m_text, m_height, m_width, - m_thickness, m_orientation, m_hJustify, m_vJustify ); + aImporter.AddText( m_origin, m_text, m_height, m_width, m_thickness, m_orientation, + m_hJustify, m_vJustify, m_color ); } virtual std::unique_ptr<IMPORTED_SHAPE> clone() const override @@ -238,6 +238,7 @@ private: double m_orientation; GR_TEXT_H_ALIGN_T m_hJustify; GR_TEXT_V_ALIGN_T m_vJustify; + COLOR4D m_color; }; @@ -245,18 +246,17 @@ class IMPORTED_SPLINE : public IMPORTED_SHAPE { public: IMPORTED_SPLINE( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1, - const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, double aWidth ) : - m_start( aStart ), - m_bezierControl1( aBezierControl1 ), - m_bezierControl2( aBezierControl2 ), - m_end( aEnd ), - m_width( aWidth ) + const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, double aWidth, + const COLOR4D& aColor ) : + m_start( aStart ), + m_bezierControl1( aBezierControl1 ), m_bezierControl2( aBezierControl2 ), m_end( aEnd ), + m_width( aWidth ), m_color( aColor ) { } void ImportTo( GRAPHICS_IMPORTER& aImporter ) const override { - aImporter.AddSpline( m_start, m_bezierControl1, m_bezierControl2, m_end, m_width ); + aImporter.AddSpline( m_start, m_bezierControl1, m_bezierControl2, m_end, m_width, m_color ); } virtual std::unique_ptr<IMPORTED_SHAPE> clone() const override @@ -278,27 +278,33 @@ private: VECTOR2D m_bezierControl2; VECTOR2D m_end; double m_width; + COLOR4D m_color; }; class GRAPHICS_IMPORTER_BUFFER : public GRAPHICS_IMPORTER { public: - void AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd, double aWidth ) override; + void AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd, double aWidth, + const COLOR4D& aColor = COLOR4D::UNSPECIFIED ) override; - void AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth, bool aFilled ) override; + void AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth, bool aFilled, + const COLOR4D& aColor = COLOR4D::UNSPECIFIED ) override; void AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, const EDA_ANGLE& aAngle, - double aWidth ) override; + double aWidth, const COLOR4D& aColor = COLOR4D::UNSPECIFIED ) override; - void AddPolygon( const std::vector< VECTOR2D >& aVertices, double aWidth ) override; + void AddPolygon( const std::vector<VECTOR2D>& aVertices, double aWidth, + const COLOR4D& aColor = COLOR4D::UNSPECIFIED ) override; void AddText( const VECTOR2D& aOrigin, const wxString& aText, double aHeight, double aWidth, double aThickness, double aOrientation, GR_TEXT_H_ALIGN_T aHJustify, - GR_TEXT_V_ALIGN_T aVJustify ) override; + GR_TEXT_V_ALIGN_T aVJustify, + const COLOR4D& aColor = COLOR4D::UNSPECIFIED ) override; void AddSpline( const VECTOR2D& aStart, const VECTOR2D& BezierControl1, - const VECTOR2D& BezierControl2, const VECTOR2D& aEnd , double aWidth ) override; + const VECTOR2D& BezierControl2, const VECTOR2D& aEnd, double aWidth, + const COLOR4D& aColor = COLOR4D::UNSPECIFIED ) override; void ImportTo( GRAPHICS_IMPORTER& aImporter ); void AddShape( std::unique_ptr<IMPORTED_SHAPE>& aShape ); diff --git a/common/import_gfx/svg_import_plugin.cpp b/common/import_gfx/svg_import_plugin.cpp index 2540d4dca1..0a71b9deca 100644 --- a/common/import_gfx/svg_import_plugin.cpp +++ b/common/import_gfx/svg_import_plugin.cpp @@ -29,8 +29,6 @@ #include <algorithm> #include <cmath> -#include <math/vector2d.h> - #include <eda_item.h> #include "graphics_importer.h" @@ -101,9 +99,24 @@ bool SVG_IMPORT_PLUGIN::Import() for( NSVGshape* shape = m_parsedImage->shapes; shape != nullptr; shape = shape->next ) { - double lineWidth = shape->strokeWidth; + double lineWidth = shape->stroke.type != NSVG_PAINT_NONE ? shape->strokeWidth : -1; bool filled = shape->fill.type != NSVG_PAINT_NONE && alpha( shape->fill.color ) > 0; + COLOR4D color = COLOR4D::UNSPECIFIED; + + if( shape->fill.type == NSVG_PAINT_COLOR ) + { + unsigned int icolor = shape->fill.color; + + color.r = std::clamp( ( icolor >> 0 ) & 0xFF, 0u, 255u ) / 255.0; + color.g = std::clamp( ( icolor >> 8 ) & 0xFF, 0u, 255u ) / 255.0; + color.b = std::clamp( ( icolor >> 16 ) & 0xFF, 0u, 255u ) / 255.0; + color.a = std::clamp( ( icolor >> 24 ) & 0xFF, 0u, 255u ) / 255.0; + + if( color == COLOR4D::BLACK ) // nanosvg probably didn't read it properly, use default + color = COLOR4D::UNSPECIFIED; + } + GRAPHICS_IMPORTER::POLY_FILL_RULE rule = GRAPHICS_IMPORTER::PF_NONZERO; switch( shape->fillRule ) @@ -119,7 +132,7 @@ bool SVG_IMPORT_PLUGIN::Import() { bool closed = path->closed || filled || rule == GRAPHICS_IMPORTER::PF_EVEN_ODD; - DrawPath( path->pts, path->npts, closed, filled, lineWidth ); + DrawPath( path->pts, path->npts, closed, filled, lineWidth, color ); } } @@ -139,7 +152,7 @@ double SVG_IMPORT_PLUGIN::GetImageHeight() const return 0.0; } - return m_parsedImage->height; + return m_parsedImage->height / SVG_DPI * inches2mm; } @@ -151,12 +164,37 @@ double SVG_IMPORT_PLUGIN::GetImageWidth() const return 0.0; } - return m_parsedImage->width; + return m_parsedImage->width / SVG_DPI * inches2mm; +} + + +BOX2D SVG_IMPORT_PLUGIN::GetImageBBox() const +{ + BOX2D bbox; + + if( !m_parsedImage || !m_parsedImage->shapes ) + { + wxASSERT_MSG( false, wxT( "Image must have been loaded before getting bbox" ) ); + return bbox; + } + + for( NSVGshape* shape = m_parsedImage->shapes; shape != nullptr; shape = shape->next ) + { + BOX2D shapeBbox; + float( &bounds )[4] = shape->bounds; + + shapeBbox.SetOrigin( bounds[0], bounds[1] ); + shapeBbox.SetEnd( bounds[2], bounds[3] ); + + bbox.Merge( shapeBbox ); + } + + return bbox; } void SVG_IMPORT_PLUGIN::DrawPath( const float* aPoints, int aNumPoints, bool aPoly, bool aFilled, - double aLineWidth ) + double aLineWidth, const COLOR4D& aColor ) { std::vector< VECTOR2D > collectedPathPoints; @@ -164,9 +202,9 @@ void SVG_IMPORT_PLUGIN::DrawPath( const float* aPoints, int aNumPoints, bool aPo DrawCubicBezierPath( aPoints, aNumPoints, collectedPathPoints ); if( aPoly && aFilled ) - DrawPolygon( collectedPathPoints, aLineWidth ); + DrawPolygon( collectedPathPoints, aLineWidth, aColor ); else - DrawLineSegments( collectedPathPoints, aLineWidth ); + DrawLineSegments( collectedPathPoints, aLineWidth, aColor ); } @@ -201,18 +239,20 @@ void SVG_IMPORT_PLUGIN::DrawCubicBezierCurve( const float* aPoints, } -void SVG_IMPORT_PLUGIN::DrawPolygon( const std::vector< VECTOR2D >& aPoints, double aWidth ) +void SVG_IMPORT_PLUGIN::DrawPolygon( const std::vector<VECTOR2D>& aPoints, double aWidth, + const COLOR4D& aColor ) { - m_internalImporter.AddPolygon( aPoints, aWidth ); + m_internalImporter.AddPolygon( aPoints, aWidth, aColor ); } -void SVG_IMPORT_PLUGIN::DrawLineSegments( const std::vector< VECTOR2D >& aPoints, double aWidth ) +void SVG_IMPORT_PLUGIN::DrawLineSegments( const std::vector<VECTOR2D>& aPoints, double aWidth, + const COLOR4D& aColor ) { unsigned int numLineStartPoints = aPoints.size() - 1; for( unsigned int pointIndex = 0; pointIndex < numLineStartPoints; ++pointIndex ) - m_internalImporter.AddLine( aPoints[ pointIndex ], aPoints[ pointIndex + 1 ], aWidth ); + m_internalImporter.AddLine( aPoints[ pointIndex ], aPoints[ pointIndex + 1 ], aWidth, aColor ); } diff --git a/common/import_gfx/svg_import_plugin.h b/common/import_gfx/svg_import_plugin.h index 06d9ddbc90..698e5d18f5 100644 --- a/common/import_gfx/svg_import_plugin.h +++ b/common/import_gfx/svg_import_plugin.h @@ -28,7 +28,6 @@ #include "graphics_import_plugin.h" #include "graphics_importer_buffer.h" -#include <math/vector2d.h> #include <wildcards_and_files_ext.h> #include <vector> @@ -68,18 +67,21 @@ public: virtual double GetImageHeight() const override; virtual double GetImageWidth() const override; + virtual BOX2D GetImageBBox() const override; private: - void DrawPath( const float* aPoints, int aNumPoints, bool aClosedPath, bool aFilled, double aLineWidth ); + void DrawPath( const float* aPoints, int aNumPoints, bool aClosedPath, bool aFilled, + double aLineWidth, const COLOR4D& aColor ); void DrawCubicBezierPath( const float* aPoints, int aNumPoints, - std::vector< VECTOR2D >& aGeneratedPoints ); + std::vector<VECTOR2D>& aGeneratedPoints ); - void DrawCubicBezierCurve( const float* aPoints, - std::vector< VECTOR2D >& aGeneratedPoints ); + void DrawCubicBezierCurve( const float* aPoints, std::vector<VECTOR2D>& aGeneratedPoints ); - void DrawPolygon( const std::vector< VECTOR2D >& aPoints, double aWidth ); - void DrawLineSegments( const std::vector< VECTOR2D >& aPoints, double aWidth ); + void DrawPolygon( const std::vector<VECTOR2D>& aPoints, double aWidth, const COLOR4D& aColor ); + + void DrawLineSegments( const std::vector<VECTOR2D>& aPoints, double aWidth, + const COLOR4D& aColor ); struct NSVGimage* m_parsedImage; diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 187e7c089f..2151da0a10 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -268,6 +268,10 @@ set ( EESCHEMA_LIBEDIT_SRCS symbol_editor/toolbars_symbol_editor.cpp ) +set( EESCHEMA_IMPORT_GFX + import_gfx/graphics_importer_lib_symbol.cpp + ) + set( EESCHEMA_SRCS ${EESCHEMA_DLGS} ${EESCHEMA_LIBEDIT_SRCS} @@ -276,6 +280,7 @@ set( EESCHEMA_SRCS ${EESCHEMA_SCH_PLUGINS_LTSPICE} ${EESCHEMA_SIM_SRCS} ${EESCHEMA_WIDGETS} + ${EESCHEMA_IMPORT_GFX} annotate.cpp autoplace_fields.cpp bom_plugins.cpp diff --git a/eeschema/import_gfx/graphics_importer_lib_symbol.cpp b/eeschema/import_gfx/graphics_importer_lib_symbol.cpp new file mode 100644 index 0000000000..d3a6f399ce --- /dev/null +++ b/eeschema/import_gfx/graphics_importer_lib_symbol.cpp @@ -0,0 +1,217 @@ +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2016 CERN + * @author Maciej Suminski <maciej.suminski@cern.ch> + * Copyright (C) 2018-2023 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 + */ + +#include "graphics_importer_lib_symbol.h" + +#include <lib_symbol.h> +#include <lib_shape.h> +#include <lib_text.h> +#include <memory> +#include <tuple> + + +GRAPHICS_IMPORTER_LIB_SYMBOL::GRAPHICS_IMPORTER_LIB_SYMBOL( LIB_SYMBOL* aSymbol, int aUnit ) : + m_symbol( aSymbol ), m_unit( aUnit ) +{ + m_millimeterToIu = schIUScale.mmToIU( 1.0 ); +} + + +VECTOR2I GRAPHICS_IMPORTER_LIB_SYMBOL::MapCoordinate( const VECTOR2D& aCoordinate ) +{ + VECTOR2D coord = aCoordinate; + coord *= GetScale(); + coord += GetImportOffsetMM(); + coord *= GetMillimeterToIuFactor(); + + return VECTOR2I( KiROUND( coord.x ), KiROUND( coord.y ) ); +} + + +int GRAPHICS_IMPORTER_LIB_SYMBOL::MapLineWidth( double aLineWidth ) +{ + VECTOR2D factor = ImportScalingFactor(); + double scale = ( factor.x + factor.y ) * 0.5; + + if( aLineWidth <= 0.0 ) + return int( GetLineWidthMM() * scale ); + + // aLineWidth is in mm: + return int( aLineWidth * scale ); +} + + +void GRAPHICS_IMPORTER_LIB_SYMBOL::AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd, + double aWidth, const COLOR4D& aColor ) +{ + std::unique_ptr<LIB_SHAPE> line = std::make_unique<LIB_SHAPE>( m_symbol, SHAPE_T::SEGMENT ); + line->SetUnit( m_unit ); + line->SetFillColor( aColor ); + line->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) ); + line->SetStart( MapCoordinate( aOrigin ) ); + line->SetEnd( MapCoordinate( aEnd ) ); + + // Skip 0 len lines: + if( line->GetStart() == line->GetEnd() ) + return; + + addItem( std::move( line ) ); +} + + +void GRAPHICS_IMPORTER_LIB_SYMBOL::AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth, + bool aFilled, const COLOR4D& aColor ) +{ + std::unique_ptr<LIB_SHAPE> circle = std::make_unique<LIB_SHAPE>( m_symbol, SHAPE_T::CIRCLE ); + circle->SetUnit( m_unit ); + circle->SetFillColor( aColor ); + circle->SetFilled( aFilled ); + circle->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) ); + circle->SetStart( MapCoordinate( aCenter )); + circle->SetEnd( MapCoordinate( VECTOR2D( aCenter.x + aRadius, aCenter.y ) ) ); + + addItem( std::move( circle ) ); +} + + +void GRAPHICS_IMPORTER_LIB_SYMBOL::AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, + const EDA_ANGLE& aAngle, double aWidth, + const COLOR4D& aColor ) +{ + std::unique_ptr<LIB_SHAPE> arc = std::make_unique<LIB_SHAPE>( m_symbol, SHAPE_T::ARC ); + arc->SetUnit( m_unit ); + arc->SetFillColor( aColor ); + + /** + * We need to perform the rotation/conversion here while still using floating point values + * to avoid rounding errors when operating in integer space in KiCad + */ + VECTOR2D end = aStart; + VECTOR2D mid = aStart; + + RotatePoint( end, aCenter, -aAngle ); + RotatePoint( mid, aCenter, -aAngle / 2.0 ); + + arc->SetArcGeometry( MapCoordinate( aStart ), MapCoordinate( mid ), MapCoordinate( end ) ); + + // Ensure the arc can be handled by KiCad. Arcs with a too big radius cannot. + // The criteria used here is radius < MAX_INT / 2. + // this is not perfect, but we do not know the exact final position of the arc, so + // we cannot test the coordinate values, because the arc can be moved before being placed. + VECTOR2D center = CalcArcCenter( arc->GetStart(), arc->GetEnd(), aAngle ); + double radius = ( center - arc->GetStart() ).EuclideanNorm(); + constexpr double rd_max_value = std::numeric_limits<VECTOR2I::coord_type>::max() / 2.0; + + if( radius >= rd_max_value ) + { + // Arc cannot be handled: convert it to a segment + AddLine( aStart, end, aWidth, aColor ); + return; + } + + arc->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) ); + + addItem( std::move( arc ) ); +} + + +void GRAPHICS_IMPORTER_LIB_SYMBOL::AddPolygon( const std::vector<VECTOR2D>& aVertices, double aWidth, + const COLOR4D& aColor ) +{ + std::vector<VECTOR2I> convertedPoints; + convertedPoints.reserve( aVertices.size() ); + + for( const VECTOR2D& precisePoint : aVertices ) + convertedPoints.emplace_back( MapCoordinate( precisePoint ) ); + + if( convertedPoints.empty() ) + return; + + std::unique_ptr<LIB_SHAPE> polygon = std::make_unique<LIB_SHAPE>( m_symbol, SHAPE_T::POLY ); + polygon->SetUnit( m_unit ); + polygon->SetFilled( true ); + polygon->SetFillMode( aColor != COLOR4D::UNSPECIFIED ? FILL_T::FILLED_WITH_COLOR + : FILL_T::FILLED_SHAPE ); + polygon->SetFillColor( aColor ); + polygon->SetPolyPoints( convertedPoints ); + polygon->AddPoint( convertedPoints[0] ); // Need to close last point for libedit + + polygon->SetStroke( + STROKE_PARAMS( aWidth != -1 ? MapLineWidth( aWidth ) : -1, PLOT_DASH_TYPE::SOLID ) ); + + addItem( std::move( polygon ) ); +} + + +void GRAPHICS_IMPORTER_LIB_SYMBOL::AddText( const VECTOR2D& aOrigin, const wxString& aText, + double aHeight, double aWidth, double aThickness, + double aOrientation, GR_TEXT_H_ALIGN_T aHJustify, + GR_TEXT_V_ALIGN_T aVJustify, const COLOR4D& aColor ) +{ + std::unique_ptr<LIB_TEXT> textItem = std::make_unique<LIB_TEXT>( m_symbol ); + textItem->SetUnit( m_unit ); + textItem->SetTextColor( aColor ); + textItem->SetTextThickness( MapLineWidth( aThickness ) ); + textItem->SetTextPos( MapCoordinate( aOrigin ) ); + textItem->SetTextAngle( EDA_ANGLE( aOrientation, DEGREES_T ) ); + textItem->SetTextWidth( aWidth * ImportScalingFactor().x ); + textItem->SetTextHeight( aHeight * ImportScalingFactor().y ); + textItem->SetVertJustify( aVJustify ); + textItem->SetHorizJustify( aHJustify ); + textItem->SetText( aText ); + + addItem( std::move( textItem ) ); +} + + +void GRAPHICS_IMPORTER_LIB_SYMBOL::AddSpline( const VECTOR2D& aStart, const VECTOR2D& BezierControl1, + const VECTOR2D& BezierControl2, const VECTOR2D& aEnd, + double aWidth, const COLOR4D& aColor ) +{ + std::unique_ptr<LIB_SHAPE> spline = std::make_unique<LIB_SHAPE>( m_symbol, SHAPE_T::BEZIER ); + spline->SetUnit( m_unit ); + spline->SetFillColor( aColor ); + spline->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) ); + spline->SetStart( MapCoordinate( aStart ) ); + spline->SetBezierC1( MapCoordinate( BezierControl1 )); + spline->SetBezierC2( MapCoordinate( BezierControl2 )); + spline->SetEnd( MapCoordinate( aEnd ) ); + spline->RebuildBezierToSegmentsPointsList( aWidth ); + + // If the spline is degenerated (i.e. a segment) add it as segment or discard it if + // null (i.e. very small) length + if( spline->GetBezierPoints().size() <= 2 ) + { + spline->SetShape( SHAPE_T::SEGMENT ); + int dist = VECTOR2I(spline->GetStart()- spline->GetEnd()).EuclideanNorm(); + + // segment smaller than MIN_SEG_LEN_ACCEPTABLE_NM nanometers are skipped. + #define MIN_SEG_LEN_ACCEPTABLE_NM 20 + if( dist < MIN_SEG_LEN_ACCEPTABLE_NM ) + return; + } + + addItem( std::move( spline ) ); +} diff --git a/eeschema/import_gfx/graphics_importer_lib_symbol.h b/eeschema/import_gfx/graphics_importer_lib_symbol.h new file mode 100644 index 0000000000..fa24f830a5 --- /dev/null +++ b/eeschema/import_gfx/graphics_importer_lib_symbol.h @@ -0,0 +1,83 @@ +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2016 CERN + * Copyright (C) 2018-2023 KiCad Developers, see AUTHORS.txt for contributors. + * + * @author Maciej Suminski <maciej.suminski@cern.ch> + * + * 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 + */ + +#ifndef GRAPHICS_IMPORTER_EESCHEMA_H +#define GRAPHICS_IMPORTER_EESCHEMA_H + +#include <import_gfx/graphics_importer.h> + +#include <layer_ids.h> + +class LIB_SYMBOL; +class LIB_SHAPE; +class LIB_TEXT; + +class GRAPHICS_IMPORTER_LIB_SYMBOL : public GRAPHICS_IMPORTER +{ +public: + GRAPHICS_IMPORTER_LIB_SYMBOL( LIB_SYMBOL* aSymbol, int aUnit ); + + void AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd, double aWidth, + const COLOR4D& aColor ) override; + + void AddCircle( const VECTOR2D& aOrigin, double aRadius, double aWidth, bool aFilled, + const COLOR4D& aColor ) override; + + void AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, const EDA_ANGLE& aAngle, + double aWidth, const COLOR4D& aColor ) override; + + void AddPolygon( const std::vector<VECTOR2D>& aVertices, double aWidth, + const COLOR4D& aColor ) override; + + void AddText( const VECTOR2D& aOrigin, const wxString& aText, double aHeight, double aWidth, + double aThickness, double aOrientation, GR_TEXT_H_ALIGN_T aHJustify, + GR_TEXT_V_ALIGN_T aVJustify, const COLOR4D& aColor ) override; + + void AddSpline( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1, + const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, double aWidth, + const COLOR4D& aColor ) override; + + /** + * Convert an imported coordinate to a board coordinate, according to the internal units, + * user scale and offset + * + * @param aCoordinate is the imported coordinate in mm. + */ + VECTOR2I MapCoordinate( const VECTOR2D& aCoordinate ); + + /** + * If aLineWidth < 0, the default line thickness value is returned. + * + * @param aLineWidth is the line thickness in mm to convert. + * @return a line thickness in a board Iu value, according to the internal units. + */ + int MapLineWidth( double aLineWidth ); + + LIB_SYMBOL* m_symbol; + int m_unit; +}; + +#endif /* GRAPHICS_IMPORTER_EESCHEMA */ diff --git a/pcbnew/import_gfx/dialog_import_gfx.cpp b/pcbnew/import_gfx/dialog_import_gfx.cpp index 85f588fedf..ff77ef2b56 100644 --- a/pcbnew/import_gfx/dialog_import_gfx.cpp +++ b/pcbnew/import_gfx/dialog_import_gfx.cpp @@ -259,7 +259,7 @@ bool DIALOG_IMPORT_GFX::TransferDataFromWindow() LOCALE_IO dummy; // Ensure floats can be read. if( m_importer->Load( m_textCtrlFileName->GetValue() ) ) - m_importer->Import( scale ); + m_importer->Import( VECTOR2D( scale, scale ) ); // Get warning messages: wxString warnings = m_importer->GetMessages(); diff --git a/pcbnew/import_gfx/graphics_importer_pcbnew.cpp b/pcbnew/import_gfx/graphics_importer_pcbnew.cpp index 319f823cfb..6862219839 100644 --- a/pcbnew/import_gfx/graphics_importer_pcbnew.cpp +++ b/pcbnew/import_gfx/graphics_importer_pcbnew.cpp @@ -42,23 +42,30 @@ GRAPHICS_IMPORTER_PCBNEW::GRAPHICS_IMPORTER_PCBNEW() VECTOR2I GRAPHICS_IMPORTER_PCBNEW::MapCoordinate( const VECTOR2D& aCoordinate ) { - VECTOR2D coord = ( aCoordinate + GetImportOffsetMM() ) * ImportScalingFactor(); + VECTOR2D coord = aCoordinate; + coord *= GetScale(); + coord += GetImportOffsetMM(); + coord *= GetMillimeterToIuFactor(); + return VECTOR2I( KiROUND( coord.x ), KiROUND( coord.y ) ); } int GRAPHICS_IMPORTER_PCBNEW::MapLineWidth( double aLineWidth ) { + VECTOR2D factor = ImportScalingFactor(); + double scale = ( factor.x + factor.y ) * 0.5; + if( aLineWidth <= 0.0 ) - return int( GetLineWidthMM() * ImportScalingFactor() ); + return int( GetLineWidthMM() * scale ); // aLineWidth is in mm: - return int( aLineWidth * ImportScalingFactor() ); + return int( aLineWidth * scale ); } void GRAPHICS_IMPORTER_PCBNEW::AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd, - double aWidth ) + double aWidth, const COLOR4D& aColor ) { std::unique_ptr<PCB_SHAPE> line( createDrawing() ); line->SetShape( SHAPE_T::SEGMENT ); @@ -76,7 +83,7 @@ void GRAPHICS_IMPORTER_PCBNEW::AddLine( const VECTOR2D& aOrigin, const VECTOR2D& void GRAPHICS_IMPORTER_PCBNEW::AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth, - bool aFilled ) + bool aFilled, const COLOR4D& aColor ) { std::unique_ptr<PCB_SHAPE> circle( createDrawing() ); circle->SetShape( SHAPE_T::CIRCLE ); @@ -91,7 +98,8 @@ void GRAPHICS_IMPORTER_PCBNEW::AddCircle( const VECTOR2D& aCenter, double aRadiu void GRAPHICS_IMPORTER_PCBNEW::AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, - const EDA_ANGLE& aAngle, double aWidth ) + const EDA_ANGLE& aAngle, double aWidth, + const COLOR4D& aColor ) { std::unique_ptr<PCB_SHAPE> arc( createDrawing() ); arc->SetShape( SHAPE_T::ARC ); @@ -120,7 +128,7 @@ void GRAPHICS_IMPORTER_PCBNEW::AddArc( const VECTOR2D& aCenter, const VECTOR2D& if( radius >= rd_max_value ) { // Arc cannot be handled: convert it to a segment - AddLine( aStart, end, aWidth ); + AddLine( aStart, end, aWidth, aColor ); return; } @@ -130,7 +138,8 @@ void GRAPHICS_IMPORTER_PCBNEW::AddArc( const VECTOR2D& aCenter, const VECTOR2D& } -void GRAPHICS_IMPORTER_PCBNEW::AddPolygon( const std::vector<VECTOR2D>& aVertices, double aWidth ) +void GRAPHICS_IMPORTER_PCBNEW::AddPolygon( const std::vector<VECTOR2D>& aVertices, double aWidth, + const COLOR4D& aColor ) { std::vector<VECTOR2I> convertedPoints; convertedPoints.reserve( aVertices.size() ); @@ -158,15 +167,15 @@ void GRAPHICS_IMPORTER_PCBNEW::AddPolygon( const std::vector<VECTOR2D>& aVertice void GRAPHICS_IMPORTER_PCBNEW::AddText( const VECTOR2D& aOrigin, const wxString& aText, double aHeight, double aWidth, double aThickness, double aOrientation, GR_TEXT_H_ALIGN_T aHJustify, - GR_TEXT_V_ALIGN_T aVJustify ) + GR_TEXT_V_ALIGN_T aVJustify, const COLOR4D& aColor ) { std::unique_ptr<PCB_TEXT> textItem = createText(); textItem->SetLayer( GetLayer() ); textItem->SetTextThickness( MapLineWidth( aThickness ) ); textItem->SetTextPos( MapCoordinate( aOrigin ) ); textItem->SetTextAngle( EDA_ANGLE( aOrientation, DEGREES_T ) ); - textItem->SetTextWidth( aWidth * ImportScalingFactor() ); - textItem->SetTextHeight( aHeight * ImportScalingFactor() ); + textItem->SetTextWidth( aWidth * ImportScalingFactor().x ); + textItem->SetTextHeight( aHeight * ImportScalingFactor().y ); textItem->SetVertJustify( aVJustify ); textItem->SetHorizJustify( aHJustify ); textItem->SetText( aText ); @@ -177,7 +186,7 @@ void GRAPHICS_IMPORTER_PCBNEW::AddText( const VECTOR2D& aOrigin, const wxString& void GRAPHICS_IMPORTER_PCBNEW::AddSpline( const VECTOR2D& aStart, const VECTOR2D& BezierControl1, const VECTOR2D& BezierControl2, const VECTOR2D& aEnd, - double aWidth ) + double aWidth, const COLOR4D& aColor ) { std::unique_ptr<PCB_SHAPE> spline( createDrawing() ); spline->SetShape( SHAPE_T::BEZIER ); diff --git a/pcbnew/import_gfx/graphics_importer_pcbnew.h b/pcbnew/import_gfx/graphics_importer_pcbnew.h index d66042be57..258b7f4dd3 100644 --- a/pcbnew/import_gfx/graphics_importer_pcbnew.h +++ b/pcbnew/import_gfx/graphics_importer_pcbnew.h @@ -59,22 +59,25 @@ public: return m_layer; } - void AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd, double aWidth ) override; + void AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd, double aWidth, + const COLOR4D& aColor ) override; - void AddCircle( const VECTOR2D& aOrigin, double aRadius, double aWidth, bool aFilled ) override; + void AddCircle( const VECTOR2D& aOrigin, double aRadius, double aWidth, bool aFilled, + const COLOR4D& aColor ) override; void AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, const EDA_ANGLE& aAngle, - double aWidth ) override; + double aWidth, const COLOR4D& aColor ) override; - void AddPolygon( const std::vector< VECTOR2D >& aVertices, double aWidth ) override; + void AddPolygon( const std::vector<VECTOR2D>& aVertices, double aWidth, + const COLOR4D& aColor ) override; void AddText( const VECTOR2D& aOrigin, const wxString& aText, double aHeight, double aWidth, double aThickness, double aOrientation, GR_TEXT_H_ALIGN_T aHJustify, - GR_TEXT_V_ALIGN_T aVJustify ) override; + GR_TEXT_V_ALIGN_T aVJustify, const COLOR4D& aColor ) override; void AddSpline( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1, - const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, - double aWidth ) override; + const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, double aWidth, + const COLOR4D& aColor ) override; /** * Convert an imported coordinate to a board coordinate, according to the internal units,