Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kicad-source-mirror
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
kicad-source-mirror
Commits
51a84547
Commit
51a84547
authored
Oct 26, 2011
by
jean-pierre charras
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bitmap2component: use BOOST:POLYGON instead of KBool, and minor enhancements.
parent
4cbcf56c
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
145 additions
and
198 deletions
+145
-198
bitmap2cmp_gui.cpp
bitmap2component/bitmap2cmp_gui.cpp
+17
-6
bitmap2component.cpp
bitmap2component/bitmap2component.cpp
+123
-188
potracelib.h
potrace/potracelib.h
+5
-4
No files found.
bitmap2component/bitmap2cmp_gui.cpp
View file @
51a84547
...
@@ -45,6 +45,8 @@
...
@@ -45,6 +45,8 @@
#define KEYWORD_FRAME_SIZEY wxT( "Bmconverter_Size_y" )
#define KEYWORD_FRAME_SIZEY wxT( "Bmconverter_Size_y" )
#define KEYWORD_LAST_INPUT_FILE wxT( "Last_input" )
#define KEYWORD_LAST_INPUT_FILE wxT( "Last_input" )
#define KEYWORD_LAST_OUTPUT_FILE wxT( "Last_output" )
#define KEYWORD_LAST_OUTPUT_FILE wxT( "Last_output" )
#define KEYWORD_BINARY_THRESHOLD wxT( "Threshold" )
#define KEYWORD_BW_NEGATIVE wxT( "Negative_choice" )
extern
int
bitmap2component
(
potrace_bitmap_t
*
aPotrace_bitmap
,
FILE
*
aOutfile
,
int
aFormat
);
extern
int
bitmap2component
(
potrace_bitmap_t
*
aPotrace_bitmap
,
FILE
*
aOutfile
,
int
aFormat
);
...
@@ -88,6 +90,7 @@ private:
...
@@ -88,6 +90,7 @@ private:
BM2CMP_FRAME
::
BM2CMP_FRAME
()
:
BM2CMP_FRAME_BASE
(
NULL
)
BM2CMP_FRAME
::
BM2CMP_FRAME
()
:
BM2CMP_FRAME_BASE
(
NULL
)
{
{
int
tmp
;
m_Config
=
new
wxConfig
();
m_Config
=
new
wxConfig
();
m_Config
->
Read
(
KEYWORD_FRAME_POSX
,
&
m_FramePos
.
x
,
-
1
);
m_Config
->
Read
(
KEYWORD_FRAME_POSX
,
&
m_FramePos
.
x
,
-
1
);
m_Config
->
Read
(
KEYWORD_FRAME_POSY
,
&
m_FramePos
.
y
,
-
1
);
m_Config
->
Read
(
KEYWORD_FRAME_POSY
,
&
m_FramePos
.
y
,
-
1
);
...
@@ -95,6 +98,11 @@ BM2CMP_FRAME::BM2CMP_FRAME() : BM2CMP_FRAME_BASE( NULL )
...
@@ -95,6 +98,11 @@ BM2CMP_FRAME::BM2CMP_FRAME() : BM2CMP_FRAME_BASE( NULL )
m_Config
->
Read
(
KEYWORD_FRAME_SIZEY
,
&
m_FrameSize
.
y
,
-
1
);
m_Config
->
Read
(
KEYWORD_FRAME_SIZEY
,
&
m_FrameSize
.
y
,
-
1
);
m_Config
->
Read
(
KEYWORD_LAST_INPUT_FILE
,
&
m_BitmapFileName
);
m_Config
->
Read
(
KEYWORD_LAST_INPUT_FILE
,
&
m_BitmapFileName
);
m_Config
->
Read
(
KEYWORD_LAST_OUTPUT_FILE
,
&
m_ConvertedFileName
);
m_Config
->
Read
(
KEYWORD_LAST_OUTPUT_FILE
,
&
m_ConvertedFileName
);
if
(
m_Config
->
Read
(
KEYWORD_BINARY_THRESHOLD
,
&
tmp
)
)
m_sliderThreshold
->
SetValue
(
tmp
);
if
(
m_Config
->
Read
(
KEYWORD_BW_NEGATIVE
,
&
tmp
)
)
m_rbOptions
->
SetSelection
(
tmp
?
1
:
0
);
// Give an icon
// Give an icon
wxIcon
icon
;
wxIcon
icon
;
...
@@ -127,6 +135,8 @@ BM2CMP_FRAME::~BM2CMP_FRAME()
...
@@ -127,6 +135,8 @@ BM2CMP_FRAME::~BM2CMP_FRAME()
m_Config
->
Write
(
KEYWORD_FRAME_SIZEY
,
(
long
)
m_FrameSize
.
y
);
m_Config
->
Write
(
KEYWORD_FRAME_SIZEY
,
(
long
)
m_FrameSize
.
y
);
m_Config
->
Write
(
KEYWORD_LAST_INPUT_FILE
,
m_BitmapFileName
);
m_Config
->
Write
(
KEYWORD_LAST_INPUT_FILE
,
m_BitmapFileName
);
m_Config
->
Write
(
KEYWORD_LAST_OUTPUT_FILE
,
m_ConvertedFileName
);
m_Config
->
Write
(
KEYWORD_LAST_OUTPUT_FILE
,
m_ConvertedFileName
);
m_Config
->
Write
(
KEYWORD_BINARY_THRESHOLD
,
m_sliderThreshold
->
GetValue
()
);
m_Config
->
Write
(
KEYWORD_BW_NEGATIVE
,
m_rbOptions
->
GetSelection
()
);
delete
m_Config
;
delete
m_Config
;
...
@@ -390,16 +400,12 @@ void BM2CMP_FRAME::ExportFile( FILE* aOutfile, int aFormat )
...
@@ -390,16 +400,12 @@ void BM2CMP_FRAME::ExportFile( FILE* aOutfile, int aFormat )
}
}
// BM_TO_CMP_APP
// EDA_APP
void
EDA_APP
::
MacOpenFile
(
const
wxString
&
fileName
)
{
}
IMPLEMENT_APP
(
EDA_APP
)
IMPLEMENT_APP
(
EDA_APP
)
///-----------------------------------------------------------------------------
///-----------------------------------------------------------------------------
//
BM_TO_CMP
_APP
//
EDA
_APP
// main program
// main program
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
...
@@ -415,3 +421,8 @@ bool EDA_APP::OnInit()
...
@@ -415,3 +421,8 @@ bool EDA_APP::OnInit()
return
true
;
return
true
;
}
}
void
EDA_APP
::
MacOpenFile
(
const
wxString
&
fileName
)
{
}
bitmap2component/bitmap2component.cpp
View file @
51a84547
...
@@ -21,8 +21,10 @@
...
@@ -21,8 +21,10 @@
* or you may write to the Free Software Foundation, Inc.,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
*/
#include <math.h>
#include "kbool/booleng.h"
// For some unknown reasons, polygon.hpp shoul be included first
#include "boost/polygon/polygon.hpp"
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string.h>
...
@@ -34,13 +36,24 @@
...
@@ -34,13 +36,24 @@
#include "potracelib.h"
#include "potracelib.h"
#include "auxiliary.h"
#include "auxiliary.h"
#ifndef max
#ifndef max
#define max( a, b ) ( ( (a) > (b) ) ? (a) : (b) )
#define max( a, b ) ( ( (a) > (b) ) ? (a) : (b) )
#endif
#endif
#ifndef min
#ifndef min
#define min( a, b ) ( ( (a) < (b) ) ? (a) : (b) )
#define min( a, b ) ( ( (a) < (b) ) ? (a) : (b) )
#endif
#endif
// Define some types used here from boost::polygon
namespace
bpl
=
boost
::
polygon
;
// bpl = boost polygon library
using
namespace
bpl
::
operators
;
// +, -, =, ...
typedef
int
coordinate_type
;
typedef
bpl
::
polygon_data
<
coordinate_type
>
KPolygon
;
// define a basic polygon
typedef
std
::
vector
<
KPolygon
>
KPolygonSet
;
// define a set of polygons
typedef
bpl
::
point_data
<
coordinate_type
>
KPolyPoint
;
// define a corner of a polygon
enum
output_format
{
enum
output_format
{
POSTSCRIPT_FMT
=
1
,
POSTSCRIPT_FMT
=
1
,
...
@@ -48,11 +61,13 @@ enum output_format {
...
@@ -48,11 +61,13 @@ enum output_format {
EESCHEMA_FMT
EESCHEMA_FMT
};
};
/* free a potrace bitmap */
/* free a potrace bitmap */
static
void
bm_free
(
potrace_bitmap_t
*
bm
)
{
static
void
bm_free
(
potrace_bitmap_t
*
bm
)
if
(
bm
!=
NULL
)
{
{
free
(
bm
->
map
);
if
(
bm
!=
NULL
)
{
free
(
bm
->
map
);
}
}
free
(
bm
);
free
(
bm
);
}
}
...
@@ -69,8 +84,7 @@ public:
...
@@ -69,8 +84,7 @@ public:
double
m_ScaleY
;
// the conversion scale
double
m_ScaleY
;
// the conversion scale
potrace_path_t
*
m_Paths
;
// the list of paths, from potrace (list of lines and bezier curves)
potrace_path_t
*
m_Paths
;
// the list of paths, from potrace (list of lines and bezier curves)
FILE
*
m_Outfile
;
FILE
*
m_Outfile
;
public
:
public
:
BITMAPCONV_INFO
();
BITMAPCONV_INFO
();
};
};
static
void
BezierToPolyline
(
std
::
vector
<
potrace_dpoint_t
>&
aCornersBuffer
,
static
void
BezierToPolyline
(
std
::
vector
<
potrace_dpoint_t
>&
aCornersBuffer
,
...
@@ -96,102 +110,7 @@ BITMAPCONV_INFO::BITMAPCONV_INFO()
...
@@ -96,102 +110,7 @@ BITMAPCONV_INFO::BITMAPCONV_INFO()
}
}
/**
int
bitmap2component
(
potrace_bitmap_t
*
aPotrace_bitmap
,
FILE
*
aOutfile
,
int
aFormat
)
* Function ArmBoolEng
* Initialise parameters used in kbool
* @param aBooleng = pointer to the Bool_Engine to initialise
* @param aConvertHoles = mode for holes when a boolean operation is made
* true: in resulting polygon, holes are linked into outer contours by double overlapping segments
* false: in resulting polygons, holes are not linked: they are separate polygons
*/
void
ArmBoolEng
(
Bool_Engine
*
aBooleng
,
bool
aConvertHoles
)
{
// set some global vals to arm the boolean engine
// input points are scaled up with GetDGrid() * GetGrid()
// DGRID is only meant to make fractional parts of input data which
/*
* The input data scaled up with DGrid is related to the accuracy the user has in his input data.
* User data with a minimum accuracy of 0.001, means set the DGrid to 1000.
* The input data may contain data with a minimum accuracy much smaller, but by setting the DGrid
* everything smaller than 1/DGrid is rounded.
*
* DGRID is only meant to make fractional parts of input data which can be
* doubles, part of the integers used in vertexes within the boolean algorithm.
* And therefore DGRID bigger than 1 is not usefull, you would only loose accuracy.
* Within the algorithm all input data is multiplied with DGRID, and the result
* is rounded to an integer.
*/
double
DGRID
=
1000.0
;
// round coordinate X or Y value in calculations to this (initial value = 1000.0 in kbool example)
// kbool uses DGRID to convert float user units to integer
// kbool unit = (int)(user unit * DGRID)
// Note: in kicad, coordinates are already integer so DGRID could be set to 1
// we can choose 1.0,
// but choose DGRID = 1000.0 solves some filling problems
// (perhaps because this allows a better precision in kbool internal calculations
double
MARGE
=
1.0
/
DGRID
;
// snap with in this range points to lines in the intersection routines
// should always be >= 1/DGRID a MARGE >= 10/DGRID is ok
// this is also used to remove small segments and to decide when
// two segments are in line. ( initial value = 0.001 )
// For kicad we choose MARGE = 1/DGRID
double
CORRECTIONFACTOR
=
0.0
;
// correct the polygons by this number: used in BOOL_CORRECTION operation
// this operation shrinks a polygon if CORRECTIONFACTOR < 0
// or stretch it if CORRECTIONFACTOR > 0
// the size change is CORRECTIONFACTOR (holes are correctly handled)
double
CORRECTIONABER
=
1.0
;
// the accuracy for the rounded shapes used in correction
double
ROUNDFACTOR
=
1.5
;
// when will we round the correction shape to a circle
double
SMOOTHABER
=
10.0
;
// accuracy when smoothing a polygon
double
MAXLINEMERGE
=
1000.0
;
// leave as is, segments of this length in smoothen
/*
* Grid makes sure that the integer data used within the algorithm has room for extra intersections
* smaller than the smallest number within the input data.
* The input data scaled up with DGrid is related to the accuracy the user has in his input data.
* Another scaling with Grid is applied on top of it to create space in the integer number for
* even smaller numbers.
*/
int
GRID
=
(
int
)
(
10000
/
DGRID
);
// initial value = 10000 in kbool example
// But we use 10000/DGRID because the scalling is made
// by DGRID on integer pcbnew units and
// the global scalling ( GRID*DGRID) must be < 30000 to avoid
// overflow in calculations (made in long long in kbool)
if
(
GRID
<=
1
)
// Cannot be null!
GRID
=
1
;
aBooleng
->
SetMarge
(
MARGE
);
aBooleng
->
SetGrid
(
GRID
);
aBooleng
->
SetDGrid
(
DGRID
);
aBooleng
->
SetCorrectionFactor
(
CORRECTIONFACTOR
);
aBooleng
->
SetCorrectionAber
(
CORRECTIONABER
);
aBooleng
->
SetSmoothAber
(
SMOOTHABER
);
aBooleng
->
SetMaxlinemerge
(
MAXLINEMERGE
);
aBooleng
->
SetRoundfactor
(
ROUNDFACTOR
);
aBooleng
->
SetWindingRule
(
true
);
// This is the default kbool value
if
(
aConvertHoles
)
{
#if 1 // Can be set to 1 for kbool version >= 2.1, must be set to 0 for previous versions
// SetAllowNonTopHoleLinking() exists only in kbool >= 2.1
aBooleng
->
SetAllowNonTopHoleLinking
(
false
);
// Default = , but i have problems (filling errors) when true
#endif
aBooleng
->
SetLinkHoles
(
true
);
// holes will be connected by double overlapping segments
aBooleng
->
SetOrientationEntryMode
(
false
);
// all polygons are contours, not holes
}
else
{
aBooleng
->
SetLinkHoles
(
false
);
// holes will not be connected by double overlapping segments
aBooleng
->
SetOrientationEntryMode
(
true
);
// holes are entered counter clockwise
}
}
int
bitmap2component
(
potrace_bitmap_t
*
aPotrace_bitmap
,
FILE
*
aOutfile
,
int
aFormat
)
{
{
potrace_param_t
*
param
;
potrace_param_t
*
param
;
potrace_state_t
*
st
;
potrace_state_t
*
st
;
...
@@ -232,7 +151,7 @@ int bitmap2component( potrace_bitmap_t* aPotrace_bitmap, FILE * aOutfile, int aF
...
@@ -232,7 +151,7 @@ int bitmap2component( potrace_bitmap_t* aPotrace_bitmap, FILE * aOutfile, int aF
case
1
:
case
1
:
info
.
m_Format
=
EESCHEMA_FMT
;
info
.
m_Format
=
EESCHEMA_FMT
;
info
.
m_ScaleX
=
1000.0
/
300
;
// the conversion scale
info
.
m_ScaleX
=
1000.0
/
300
;
// the conversion scale
info
.
m_ScaleY
=
-
info
.
m_ScaleX
;
// Y axis is bottom to Top for components in libs
info
.
m_ScaleY
=
-
info
.
m_ScaleX
;
// Y axis is bottom to Top for components in libs
CreateOutputFile
(
info
);
CreateOutputFile
(
info
);
break
;
break
;
...
@@ -282,12 +201,12 @@ static void OuputHeader( BITMAPCONV_INFO& aInfo )
...
@@ -282,12 +201,12 @@ static void OuputHeader( BITMAPCONV_INFO& aInfo )
fprintf
(
aInfo
.
m_Outfile
,
"# pixmap w = %d, h = %d
\n
#
\n
"
,
fprintf
(
aInfo
.
m_Outfile
,
"# pixmap w = %d, h = %d
\n
#
\n
"
,
aInfo
.
m_PixmapWidth
,
aInfo
.
m_PixmapHeight
);
aInfo
.
m_PixmapWidth
,
aInfo
.
m_PixmapHeight
);
fprintf
(
aInfo
.
m_Outfile
,
"$MODULE %s
\n
"
,
CmpName
);
fprintf
(
aInfo
.
m_Outfile
,
"$MODULE %s
\n
"
,
CmpName
);
fprintf
(
aInfo
.
m_Outfile
,
"Po 0 0 0 15 00000000 00000000 ~~
\n
"
);
fprintf
(
aInfo
.
m_Outfile
,
"Po 0 0 0 15 00000000 00000000 ~~
\n
"
);
fprintf
(
aInfo
.
m_Outfile
,
"Li %s
\n
"
,
CmpName
);
fprintf
(
aInfo
.
m_Outfile
,
"Li %s
\n
"
,
CmpName
);
fprintf
(
aInfo
.
m_Outfile
,
"T0 0 %d %d %d 0 %d N I %d
\"
G***
\"\n
"
,
fprintf
(
aInfo
.
m_Outfile
,
"T0 0 %d %d %d 0 %d N I %d
\"
G***
\"\n
"
,
Ypos
,
fieldSize
,
fieldSize
,
fieldSize
/
5
,
FIELD_LAYER
);
Ypos
,
fieldSize
,
fieldSize
,
fieldSize
/
5
,
FIELD_LAYER
);
fprintf
(
aInfo
.
m_Outfile
,
"T1 0 %d %d %d 0 %d N I %d
\"
%s
\"\n
"
,
fprintf
(
aInfo
.
m_Outfile
,
"T1 0 %d %d %d 0 %d N I %d
\"
%s
\"\n
"
,
-
Ypos
,
fieldSize
,
fieldSize
,
fieldSize
/
5
,
FIELD_LAYER
,
CmpName
);
-
Ypos
,
fieldSize
,
fieldSize
,
fieldSize
/
5
,
FIELD_LAYER
,
CmpName
);
break
;
break
;
case
EESCHEMA_FMT
:
case
EESCHEMA_FMT
:
...
@@ -329,25 +248,32 @@ static void OuputEnd( BITMAPCONV_INFO& aInfo )
...
@@ -329,25 +248,32 @@ static void OuputEnd( BITMAPCONV_INFO& aInfo )
}
}
}
}
/**
static
void
OuputOnePolygon
(
BITMAPCONV_INFO
&
aInfo
,
* Function OuputOnePolygon
std
::
vector
<
potrace_dpoint_t
>&
aPolygonBuffer
)
* write one polygon to output file.
* Polygon coordinates are expected scaled by the polugon extraction function
*/
static
void
OuputOnePolygon
(
BITMAPCONV_INFO
&
aInfo
,
KPolygon
&
aPolygon
)
{
{
unsigned
ii
;
unsigned
ii
;
KPolyPoint
currpoint
;
double
offsetX
=
aInfo
.
m_PixmapWidth
/
2
*
aInfo
.
m_ScaleX
;
int
offsetX
=
(
int
)(
aInfo
.
m_PixmapWidth
/
2
*
aInfo
.
m_ScaleX
);
double
offsetY
=
aInfo
.
m_PixmapHeight
/
2
*
aInfo
.
m_ScaleY
;
int
offsetY
=
(
int
)(
aInfo
.
m_PixmapHeight
/
2
*
aInfo
.
m_ScaleY
);
KPolyPoint
startpoint
=
*
aPolygon
.
begin
();
switch
(
aInfo
.
m_Format
)
switch
(
aInfo
.
m_Format
)
{
{
case
POSTSCRIPT_FMT
:
case
POSTSCRIPT_FMT
:
fprintf
(
aInfo
.
m_Outfile
,
"%f %f moveto
\n
"
,
fprintf
(
aInfo
.
m_Outfile
,
"%d %d moveto
\n
"
,
aPolygonBuffer
[
0
].
x
*
aInfo
.
m_ScaleX
,
startpoint
.
x
(),
startpoint
.
y
()
);
aPolygonBuffer
[
0
].
y
*
aInfo
.
m_ScaleY
);
for
(
ii
=
1
;
ii
<
aPolygon
.
size
();
ii
++
)
for
(
ii
=
1
;
ii
<
aPolygonBuffer
.
size
();
ii
++
)
{
fprintf
(
aInfo
.
m_Outfile
,
"%f %f lineto
\n
"
,
currpoint
=
*
(
aPolygon
.
begin
()
+
ii
);
aPolygonBuffer
[
ii
].
x
*
aInfo
.
m_ScaleX
,
fprintf
(
aInfo
.
m_Outfile
,
"%d %d lineto
\n
"
,
aPolygonBuffer
[
ii
].
y
*
aInfo
.
m_ScaleY
);
currpoint
.
x
(),
currpoint
.
y
()
);
}
fprintf
(
aInfo
.
m_Outfile
,
"0 setgray fill
\n
"
);
fprintf
(
aInfo
.
m_Outfile
,
"0 setgray fill
\n
"
);
break
;
break
;
...
@@ -359,30 +285,33 @@ static void OuputOnePolygon( BITMAPCONV_INFO& aInfo,
...
@@ -359,30 +285,33 @@ static void OuputOnePolygon( BITMAPCONV_INFO& aInfo,
int
width
=
1
;
int
width
=
1
;
fprintf
(
aInfo
.
m_Outfile
,
"DP %d %d %d %d %d %d %d
\n
"
,
fprintf
(
aInfo
.
m_Outfile
,
"DP %d %d %d %d %d %d %d
\n
"
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
int
(
aPolygonBuffer
.
size
()
+
1
),
aPolygon
.
size
()
+
1
,
width
,
layer
);
width
,
layer
);
for
(
ii
=
0
;
ii
<
aPolygonBuffer
.
size
();
ii
++
)
for
(
ii
=
0
;
ii
<
aPolygon
.
size
();
ii
++
)
{
currpoint
=
*
(
aPolygon
.
begin
()
+
ii
);
fprintf
(
aInfo
.
m_Outfile
,
"Dl %d %d
\n
"
,
fprintf
(
aInfo
.
m_Outfile
,
"Dl %d %d
\n
"
,
(
int
)
(
aPolygonBuffer
[
ii
].
x
*
aInfo
.
m_ScaleX
-
offsetX
),
currpoint
.
x
()
-
offsetX
,
currpoint
.
y
()
-
offsetY
);
(
int
)
(
aPolygonBuffer
[
ii
].
y
*
aInfo
.
m_ScaleY
-
offsetY
)
);
}
// Close polygon
// Close polygon
fprintf
(
aInfo
.
m_Outfile
,
"Dl %d %d
\n
"
,
fprintf
(
aInfo
.
m_Outfile
,
"Dl %d %d
\n
"
,
(
int
)
(
aPolygonBuffer
[
0
].
x
*
aInfo
.
m_ScaleX
-
offsetX
),
startpoint
.
x
()
-
offsetX
,
startpoint
.
y
()
-
offsetY
);
(
int
)
(
aPolygonBuffer
[
0
].
y
*
aInfo
.
m_ScaleY
-
offsetY
)
);
}
}
break
;
break
;
case
EESCHEMA_FMT
:
case
EESCHEMA_FMT
:
fprintf
(
aInfo
.
m_Outfile
,
"P %d 0 0 1"
,
int
(
aPolygonBuffer
.
size
()
+
1
)
);
fprintf
(
aInfo
.
m_Outfile
,
"P %d 0 0 1"
,
aPolygon
.
size
()
+
1
);
for
(
ii
=
0
;
ii
<
aPolygonBuffer
.
size
();
ii
++
)
for
(
ii
=
0
;
ii
<
aPolygon
.
size
();
ii
++
)
{
currpoint
=
*
(
aPolygon
.
begin
()
+
ii
);
fprintf
(
aInfo
.
m_Outfile
,
" %d %d"
,
fprintf
(
aInfo
.
m_Outfile
,
" %d %d"
,
(
int
)
(
aPolygonBuffer
[
ii
].
x
*
aInfo
.
m_ScaleX
-
offsetX
),
currpoint
.
x
()
-
offsetX
,
currpoint
.
y
()
-
offsetY
);
(
int
)
(
aPolygonBuffer
[
ii
].
y
*
aInfo
.
m_ScaleY
-
offsetY
)
);
}
// Close polygon
// Close polygon
fprintf
(
aInfo
.
m_Outfile
,
" %d %d"
,
fprintf
(
aInfo
.
m_Outfile
,
" %d %d"
,
(
int
)
(
aPolygonBuffer
[
0
].
x
*
aInfo
.
m_ScaleX
-
offsetX
),
startpoint
.
x
()
-
offsetX
,
startpoint
.
y
()
-
offsetY
);
(
int
)
(
aPolygonBuffer
[
0
].
y
*
aInfo
.
m_ScaleY
-
offsetY
)
);
fprintf
(
aInfo
.
m_Outfile
,
" F
\n
"
);
fprintf
(
aInfo
.
m_Outfile
,
" F
\n
"
);
break
;
break
;
...
@@ -392,16 +321,21 @@ static void OuputOnePolygon( BITMAPCONV_INFO& aInfo,
...
@@ -392,16 +321,21 @@ static void OuputOnePolygon( BITMAPCONV_INFO& aInfo,
static
void
CreateOutputFile
(
BITMAPCONV_INFO
&
aInfo
)
static
void
CreateOutputFile
(
BITMAPCONV_INFO
&
aInfo
)
{
{
unsigned
int
i
,
n
;
KPolyPoint
currpoint
;
int
*
tag
;
std
::
vector
<
potrace_dpoint_t
>
cornersBuffer
;
std
::
vector
<
potrace_dpoint_t
>
cornersBuffer
;
// This KPolygonSet polyset_areas is a complex polygon to draw
// and can be complex depending on holes inside this polygon
KPolygonSet
polyset_areas
;
// This KPolygonSet polyset_holes is the set of holes inside polyset_areas
KPolygonSet
polyset_holes
;
potrace_dpoint_t
(
*
c
)[
3
];
potrace_dpoint_t
(
*
c
)[
3
];
OuputHeader
(
aInfo
);
OuputHeader
(
aInfo
);
bool
main_outline
=
true
;
bool
main_outline
=
true
;
Bool_Engine
*
booleng
=
NULL
;
/* draw each as a polygon with no hole.
/* draw each as a polygon with no hole.
* Bezier curves are approximated by a polyline
* Bezier curves are approximated by a polyline
...
@@ -409,17 +343,11 @@ static void CreateOutputFile( BITMAPCONV_INFO& aInfo )
...
@@ -409,17 +343,11 @@ static void CreateOutputFile( BITMAPCONV_INFO& aInfo )
potrace_path_t
*
paths
=
aInfo
.
m_Paths
;
// the list of paths
potrace_path_t
*
paths
=
aInfo
.
m_Paths
;
// the list of paths
while
(
paths
!=
NULL
)
while
(
paths
!=
NULL
)
{
{
n
=
paths
->
curve
.
n
;
int
cnt
=
paths
->
curve
.
n
;
tag
=
paths
->
curve
.
tag
;
int
*
tag
=
paths
->
curve
.
tag
;
c
=
paths
->
curve
.
c
;
c
=
paths
->
curve
.
c
;
potrace_dpoint_t
startpoint
=
c
[
n
-
1
][
2
];
potrace_dpoint_t
startpoint
=
c
[
cnt
-
1
][
2
];
cornersBuffer
.
push_back
(
startpoint
);
for
(
int
i
=
0
;
i
<
cnt
;
i
++
)
if
(
booleng
==
NULL
)
{
booleng
=
new
Bool_Engine
();
ArmBoolEng
(
booleng
,
true
);
}
for
(
i
=
0
;
i
<
n
;
i
++
)
{
{
switch
(
tag
[
i
]
)
switch
(
tag
[
i
]
)
{
{
...
@@ -440,46 +368,53 @@ static void CreateOutputFile( BITMAPCONV_INFO& aInfo )
...
@@ -440,46 +368,53 @@ static void CreateOutputFile( BITMAPCONV_INFO& aInfo )
if
(
main_outline
)
if
(
main_outline
)
{
{
main_outline
=
false
;
main_outline
=
false
;
booleng
->
StartPolygonAdd
(
GROUP_A
);
for
(
i
=
1
;
i
<
cornersBuffer
.
size
();
i
++
)
booleng
->
AddPoint
(
cornersBuffer
[
i
].
x
,
cornersBuffer
[
i
].
y
);
booleng
->
EndPolygonAdd
();
// build the current main polygon
std
::
vector
<
KPolyPoint
>
cornerslist
;
// a simple boost polygon
for
(
unsigned
int
i
=
0
;
i
<
cornersBuffer
.
size
();
i
++
)
{
currpoint
.
x
(
(
coordinate_type
)
(
cornersBuffer
[
i
].
x
*
aInfo
.
m_ScaleX
)
);
currpoint
.
y
(
(
coordinate_type
)
(
cornersBuffer
[
i
].
y
*
aInfo
.
m_ScaleY
)
);
cornerslist
.
push_back
(
currpoint
);
}
KPolygon
poly
;
bpl
::
set_points
(
poly
,
cornerslist
.
begin
(),
cornerslist
.
end
()
);
polyset_areas
.
push_back
(
poly
);
}
}
else
else
{
{
booleng
->
StartPolygonAdd
(
GROUP_B
);
// Add current hole in polyset_holes
for
(
i
=
1
;
i
<
cornersBuffer
.
size
();
i
++
)
std
::
vector
<
KPolyPoint
>
cornerslist
;
// a simple boost polygon
booleng
->
AddPoint
(
cornersBuffer
[
i
].
x
,
cornersBuffer
[
i
].
y
);
for
(
unsigned
int
i
=
0
;
i
<
cornersBuffer
.
size
();
i
++
)
{
currpoint
.
x
(
(
coordinate_type
)
(
cornersBuffer
[
i
].
x
*
aInfo
.
m_ScaleX
)
);
currpoint
.
y
(
(
coordinate_type
)
(
cornersBuffer
[
i
].
y
*
aInfo
.
m_ScaleY
)
);
cornerslist
.
push_back
(
currpoint
);
}
booleng
->
EndPolygonAdd
();
KPolygon
poly
;
bpl
::
set_points
(
poly
,
cornerslist
.
begin
(),
cornerslist
.
end
()
);
polyset_holes
.
push_back
(
poly
);
}
}
cornersBuffer
.
clear
();
cornersBuffer
.
clear
();
/* at the end of a group of a positive path and its negative
/* at the end of a group of a positive path and its negative
children, fill.
*
children, fill. *
/
*/
if
(
paths
->
next
==
NULL
||
paths
->
next
->
sign
==
'+'
)
if
(
paths
->
next
==
NULL
||
paths
->
next
->
sign
==
'+'
)
{
{
booleng
->
Do_Operation
(
BOOL_A_SUB_B
);
// Substract holes to main polygon:
std
::
vector
<
potrace_dpoint_t
>
PolygonBuffer
;
polyset_areas
-=
polyset_holes
;
while
(
booleng
->
StartPolygonGet
()
)
{
potrace_dpoint_t
corner
;
PolygonBuffer
.
clear
();
while
(
booleng
->
PolygonHasMorePoints
()
)
{
corner
.
x
=
booleng
->
GetPolygonXPoint
();
corner
.
y
=
booleng
->
GetPolygonYPoint
();
PolygonBuffer
.
push_back
(
corner
);
}
booleng
->
EndPolygonGet
();
// Output current resulting polygon(s)
OuputOnePolygon
(
aInfo
,
PolygonBuffer
);
for
(
unsigned
ii
=
0
;
ii
<
polyset_areas
.
size
();
ii
++
)
PolygonBuffer
.
clear
();
{
KPolygon
&
poly
=
polyset_areas
[
ii
];
OuputOnePolygon
(
aInfo
,
poly
);
}
}
delete
booleng
;
polyset_areas
.
clear
()
;
booleng
=
NULL
;
polyset_holes
.
clear
()
;
main_outline
=
true
;
main_outline
=
true
;
}
}
paths
=
paths
->
next
;
paths
=
paths
->
next
;
...
@@ -505,7 +440,7 @@ void BezierToPolyline( std::vector <potrace_dpoint_t>& aCornersBuffer,
...
@@ -505,7 +440,7 @@ void BezierToPolyline( std::vector <potrace_dpoint_t>& aCornersBuffer,
* between the true curve and its approximation does not exceed the
* between the true curve and its approximation does not exceed the
* desired accuracy delta. */
* desired accuracy delta. */
delta
=
0.5
;
/* desired accuracy, in pixels */
delta
=
0.
2
5
;
/* desired accuracy, in pixels */
/* let dd = maximal value of 2nd derivative over curve - this must
/* let dd = maximal value of 2nd derivative over curve - this must
* occur at an endpoint. */
* occur at an endpoint. */
...
...
potrace/potracelib.h
View file @
51a84547
...
@@ -77,10 +77,11 @@ typedef struct potrace_dpoint_s potrace_dpoint_t;
...
@@ -77,10 +77,11 @@ typedef struct potrace_dpoint_s potrace_dpoint_t;
/* closed curve segment */
/* closed curve segment */
struct
potrace_curve_s
struct
potrace_curve_s
{
{
int
n
;
/
* number of segments */
int
n
;
/
/ number of segments
int
*
tag
;
/
* tag[n]: POTRACE_CURVETO or POTRACE_CORNER */
int
*
tag
;
/
/ tag[n]: POTRACE_CURVETO or POTRACE_CORNER
potrace_dpoint_t
(
*
c
)[
3
];
/* c[n][3]: control points.
potrace_dpoint_t
(
*
c
)[
3
];
/* c[n][3]: control points.
* c[n][0] is unused for tag[n]=POTRACE_CORNER */
* c[n][0] is unused for tag[n]=POTRACE_CORNER
*/
};
};
typedef
struct
potrace_curve_s
potrace_curve_t
;
typedef
struct
potrace_curve_s
potrace_curve_t
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment