KiCad PCB EDA Suite
Loading...
Searching...
No Matches
gfx_import_utils.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2023 Alex Shvartzkop <[email protected]>
5 * Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include "gfx_import_utils.h"
26
27#include <stdint.h>
28#include <lib_symbol.h>
29#include <sch_shape.h>
32
33
34std::unordered_map<uint32_t, SHAPE_POLY_SET> ConvertImageToPolygons( wxImage img,
35 VECTOR2D pixelScale )
36{
37 bool hasAlpha = img.HasAlpha();
38
39 // Quantize the image
40 for( int y = 0; y < img.GetHeight(); y++ )
41 {
42 for( int x = 0; x < img.GetWidth(); x++ )
43 {
44 int r = img.GetRed( x, y );
45 int g = img.GetGreen( x, y );
46 int b = img.GetBlue( x, y );
47 int a = hasAlpha ? img.GetAlpha( x, y ) : 255;
48
49 int roundBits = 5; // 32
50 r = std::min( r >> roundBits << roundBits, 0xFF );
51 g = std::min( g >> roundBits << roundBits, 0xFF );
52 b = std::min( b >> roundBits << roundBits, 0xFF );
53 a = std::min( a >> roundBits << roundBits, 0xFF );
54
55 img.SetRGB( x, y, r, g, b );
56
57 if( hasAlpha )
58 img.SetAlpha( x, y, a );
59 }
60 }
61
62 std::unordered_map<uint32_t, SHAPE_POLY_SET> colorPolys;
63
64 // Create polygon sets
65 for( int y = 0; y < img.GetHeight(); y++ )
66 {
67 for( int x = 0; x < img.GetWidth(); x++ )
68 {
69 uint32_t r = img.GetRed( x, y );
70 uint32_t g = img.GetGreen( x, y );
71 uint32_t b = img.GetBlue( x, y );
72 uint32_t a = hasAlpha ? img.GetAlpha( x, y ) : 255;
73
74 if( a > 0 )
75 {
76 uint32_t color = r | ( g << 8 ) | ( b << 16 ) | ( a << 24 );
77
78 SHAPE_POLY_SET& colorPoly = colorPolys[color];
79
80 SHAPE_LINE_CHAIN chain;
81 chain.Append( x * pixelScale.x, y * pixelScale.y, true );
82 chain.Append( ( x + 1 ) * pixelScale.x, y * pixelScale.y, true );
83 chain.Append( ( x + 1 ) * pixelScale.x, ( y + 1 ) * pixelScale.y, true );
84 chain.Append( x * pixelScale.x, ( y + 1 ) * pixelScale.y, true );
85 chain.SetClosed( true );
86
87 colorPoly.AddOutline( chain );
88 }
89 }
90 }
91
92 for( auto& [color, polySet] : colorPolys )
93 {
94 polySet.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
95
96 for( int i = 0; i < polySet.OutlineCount(); i++ )
97 {
98 SHAPE_POLY_SET::POLYGON& poly = polySet.Polygon( i );
99
100 for( SHAPE_LINE_CHAIN& chain : poly )
101 chain.Simplify();
102 }
103 }
104
105 return colorPolys;
106}
107
108
109void ConvertImageToLibShapes( LIB_SYMBOL* aSymbol, int unit, wxImage img, VECTOR2D pixelScale,
110 VECTOR2D offset )
111{
112 std::unordered_map<uint32_t, SHAPE_POLY_SET> colorPolys =
113 ConvertImageToPolygons( img, pixelScale );
114
115 for( auto& [color, polySet] : colorPolys )
116 {
117 polySet.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
118
119 for( const SHAPE_POLY_SET::POLYGON& poly : polySet.CPolygons() )
120 {
121 auto shape = std::make_unique<SCH_SHAPE>( SHAPE_T::POLY, LAYER_DEVICE );
122
123 shape->SetPolyShape( poly );
124
125 int r = color & 0xFF;
126 int g = ( color >> 8 ) & 0xFF;
127 int b = ( color >> 16 ) & 0xFF;
128 int a = ( color >> 24 ) & 0xFF;
129
130 shape->SetWidth( -1 );
131 shape->SetFillMode( FILL_T::FILLED_WITH_COLOR );
132 shape->SetFillColor( COLOR4D( r / 255.0, g / 255.0, b / 255.0, a / 255.0 ) );
133
134 shape->SetUnit( unit );
135
136 shape->Move( offset );
137
138 aSymbol->AddDrawItem( shape.release() );
139 }
140 }
141}
142
143
144void ConvertSVGToLibShapes( LIB_SYMBOL* aSymbol, int unit, const wxMemoryBuffer& aImageData,
145 VECTOR2D pixelScale, VECTOR2D offset )
146{
147 SVG_IMPORT_PLUGIN svgImportPlugin;
148 GRAPHICS_IMPORTER_LIB_SYMBOL libeditImporter( aSymbol, unit );
149
150 libeditImporter.SetScale( pixelScale );
151 libeditImporter.SetImportOffsetMM(
152 VECTOR2D( schIUScale.IUTomm( offset.x ), schIUScale.IUTomm( offset.y ) ) );
153
154 svgImportPlugin.SetImporter( &libeditImporter );
155 svgImportPlugin.LoadFromMemory( aImageData );
156
157 svgImportPlugin.Import();
158}
int color
Definition: DXF_plotter.cpp:58
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
void SetImportOffsetMM(const VECTOR2D &aOffset)
Set the offset in millimeters to add to coordinates when importing graphic items.
void SetScale(const VECTOR2D &aScale)
Set the scale factor affecting the imported shapes.
virtual void SetImporter(GRAPHICS_IMPORTER *aImporter)
Set the receiver of the imported shapes.
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
Define a library symbol object.
Definition: lib_symbol.h:78
void AddDrawItem(SCH_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
Definition: lib_symbol.cpp:796
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
Represent a set of closed polygons.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
std::vector< SHAPE_LINE_CHAIN > POLYGON
represents a single polygon outline with holes.
bool Import() override
Actually imports the file.
bool LoadFromMemory(const wxMemoryBuffer &aMemBuffer) override
Set memory buffer with content for import.
@ FILLED_WITH_COLOR
void ConvertImageToLibShapes(LIB_SYMBOL *aSymbol, int unit, wxImage img, VECTOR2D pixelScale, VECTOR2D offset)
std::unordered_map< uint32_t, SHAPE_POLY_SET > ConvertImageToPolygons(wxImage img, VECTOR2D pixelScale)
void ConvertSVGToLibShapes(LIB_SYMBOL *aSymbol, int unit, const wxMemoryBuffer &aImageData, VECTOR2D pixelScale, VECTOR2D offset)
@ LAYER_DEVICE
Definition: layer_ids.h:370
constexpr double IUTomm(int iu) const
Definition: base_units.h:86
VECTOR2< double > VECTOR2D
Definition: vector2d.h:690