mirror of https://github.com/KLayout/klayout.git
WIP: keep DXF and CIF layer names, DXF contour accuracy.
This commit is contained in:
parent
1b0317c120
commit
085a2ee2b1
|
|
@ -138,6 +138,11 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
|
|||
"This option specifies the database unit the resulting layer will have. "
|
||||
"The value is given in micrometer units. The default value is 1nm (0.001)."
|
||||
)
|
||||
<< tl::arg (group +
|
||||
"#--" + m_long_prefix + "keep-layer-names", &GenericReaderOptions::set_read_named_layers, "Keeps layer names",
|
||||
"If this option is used, layers names are kept as pure names and no attempt is made to\n"
|
||||
"translate them into GDS layer/datatypes."
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
|
|
@ -197,6 +202,11 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
|
|||
"\n"
|
||||
"The value is given in the units of the DXF file."
|
||||
)
|
||||
<< tl::arg (group +
|
||||
"#--" + m_long_prefix + "dxf-contour-accuracy=value", &m_dxf_reader_options.contour_accuracy, "Specifies the point accuracy for contour closing",
|
||||
"This value specifies the distance (in units of the DXF file) by which points can be separated and still\n"
|
||||
"be considered to be connected. This value is effective in polyline mode 3 and 4.\n"
|
||||
)
|
||||
<< tl::arg (group +
|
||||
"#--" + m_long_prefix + "dxf-render-texts-as-polygons", &m_dxf_reader_options.render_texts_as_polygons, "Renders texts as polygons",
|
||||
"If this option is used, texts are converted to polygons instead of being converted to labels."
|
||||
|
|
@ -222,6 +232,12 @@ void GenericReaderOptions::set_layer_map (const std::string &lm)
|
|||
}
|
||||
}
|
||||
|
||||
void GenericReaderOptions::set_read_named_layers (bool f)
|
||||
{
|
||||
m_dxf_reader_options.read_named_layers = f;
|
||||
m_cif_reader_options.read_named_layers = f;
|
||||
}
|
||||
|
||||
void GenericReaderOptions::set_dbu (double dbu)
|
||||
{
|
||||
m_dxf_reader_options.dbu = dbu;
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ private:
|
|||
std::string m_prefix, m_long_prefix, m_group_prefix;
|
||||
db::LayerMap m_layer_map;
|
||||
bool m_create_other_layers;
|
||||
bool m_read_named_layers;
|
||||
db::CommonReaderOptions m_common_reader_options;
|
||||
db::GDS2ReaderOptions m_gds2_reader_options;
|
||||
db::OASISReaderOptions m_oasis_reader_options;
|
||||
|
|
@ -109,6 +110,7 @@ private:
|
|||
|
||||
void set_layer_map (const std::string &lm);
|
||||
void set_dbu (double dbu);
|
||||
void set_read_named_layers (bool f);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,237 @@
|
|||
namespace db
|
||||
{
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// NamedLayerReader
|
||||
|
||||
NamedLayerReader::NamedLayerReader ()
|
||||
: m_create_layers (true), m_read_named_layers (false), m_next_layer_index (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void
|
||||
NamedLayerReader::set_create_layers (bool f)
|
||||
{
|
||||
m_create_layers = f;
|
||||
}
|
||||
|
||||
void
|
||||
NamedLayerReader::set_read_named_layers (bool f)
|
||||
{
|
||||
m_read_named_layers = f;
|
||||
}
|
||||
|
||||
void NamedLayerReader::set_layer_map (const LayerMap &lm)
|
||||
{
|
||||
m_layer_map = lm;
|
||||
}
|
||||
|
||||
static bool
|
||||
extract_plain_layer (const char *s, int &l)
|
||||
{
|
||||
l = 0;
|
||||
if (! *s) {
|
||||
return false;
|
||||
}
|
||||
while (*s && isdigit (*s)) {
|
||||
l = l * 10 + (unsigned int) (*s - '0');
|
||||
++s;
|
||||
}
|
||||
return (*s == 0);
|
||||
}
|
||||
|
||||
static bool
|
||||
extract_ld (const char *s, int &l, int &d, std::string &n)
|
||||
{
|
||||
l = d = 0;
|
||||
|
||||
if (*s == 'L') {
|
||||
++s;
|
||||
}
|
||||
|
||||
if (! *s || ! isdigit (*s)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (*s && isdigit (*s)) {
|
||||
l = l * 10 + (unsigned int) (*s - '0');
|
||||
++s;
|
||||
}
|
||||
|
||||
if (*s == 'D' || *s == '.') {
|
||||
++s;
|
||||
if (! *s || ! isdigit (*s)) {
|
||||
return false;
|
||||
}
|
||||
while (*s && isdigit (*s)) {
|
||||
d = d * 10 + (unsigned int) (*s - '0');
|
||||
++s;
|
||||
}
|
||||
}
|
||||
|
||||
if (*s && (isspace (*s) || *s == '_')) {
|
||||
++s;
|
||||
n = s;
|
||||
return true;
|
||||
} else if (*s == 0) {
|
||||
n.clear ();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair <bool, unsigned int>
|
||||
NamedLayerReader::open_layer (db::Layout &layout, const std::string &n)
|
||||
{
|
||||
int l = -1, d = -1;
|
||||
std::string on;
|
||||
|
||||
std::pair<bool, unsigned int> ll (false, 0);
|
||||
|
||||
ll = m_layer_map.logical (n);
|
||||
if (! ll.first && !m_read_named_layers) {
|
||||
|
||||
if (extract_plain_layer (n.c_str (), l)) {
|
||||
|
||||
db::LayerProperties lp;
|
||||
lp.layer = l;
|
||||
lp.datatype = 0;
|
||||
ll = m_layer_map.logical (lp);
|
||||
|
||||
} else if (extract_ld (n.c_str (), l, d, on)) {
|
||||
|
||||
db::LayerProperties lp;
|
||||
lp.layer = l;
|
||||
lp.datatype = d;
|
||||
lp.name = on;
|
||||
ll = m_layer_map.logical (lp);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (ll.first) {
|
||||
|
||||
// create the layer if it is not part of the layout yet.
|
||||
if (! layout.is_valid_layer (ll.second)) {
|
||||
layout.insert_layer (ll.second, m_layer_map.mapping (ll.second));
|
||||
}
|
||||
|
||||
return ll;
|
||||
|
||||
} else if (! m_create_layers) {
|
||||
|
||||
return std::pair<bool, unsigned int> (false, 0);
|
||||
|
||||
} else {
|
||||
|
||||
std::map <std::string, unsigned int>::const_iterator nl = m_new_layers.find (n);
|
||||
if (nl == m_new_layers.end ()) {
|
||||
|
||||
unsigned int ll = m_next_layer_index++;
|
||||
|
||||
layout.insert_layer (ll, db::LayerProperties ());
|
||||
m_new_layers.insert (std::make_pair (n, ll));
|
||||
|
||||
return std::pair<bool, unsigned int> (true, ll);
|
||||
|
||||
} else {
|
||||
return std::pair<bool, unsigned int> (true, nl->second);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NamedLayerReader::map_layer (const std::string &name, unsigned int layer)
|
||||
{
|
||||
m_layer_map.map (name, layer);
|
||||
}
|
||||
|
||||
void
|
||||
NamedLayerReader::prepare_layers ()
|
||||
{
|
||||
m_new_layers.clear ();
|
||||
m_next_layer_index = m_layer_map.next_index ();
|
||||
}
|
||||
|
||||
void
|
||||
NamedLayerReader::finish_layers (db::Layout &layout)
|
||||
{
|
||||
// assign layer numbers to new layers
|
||||
if (! m_new_layers.empty () && !m_read_named_layers) {
|
||||
|
||||
std::set<std::pair<int, int> > used_ld;
|
||||
for (db::Layout::layer_iterator l = layout.begin_layers (); l != layout.end_layers (); ++l) {
|
||||
used_ld.insert (std::make_pair((*l).second->layer, (*l).second->datatype));
|
||||
}
|
||||
|
||||
// assign fixed layer numbers for all layers whose name is a fixed number unless there is already a layer with that number
|
||||
for (std::map<std::string, unsigned int>::iterator i = m_new_layers.begin (); i != m_new_layers.end (); ) {
|
||||
|
||||
std::map<std::string, unsigned int>::iterator ii = i;
|
||||
++ii;
|
||||
|
||||
int l = -1;
|
||||
if (extract_plain_layer (i->first.c_str (), l) && used_ld.find (std::make_pair (l, 0)) == used_ld.end ()) {
|
||||
|
||||
used_ld.insert (std::make_pair (l, 0));
|
||||
|
||||
db::LayerProperties lp;
|
||||
lp.layer = l;
|
||||
lp.datatype = 0;
|
||||
layout.set_properties (i->second, lp);
|
||||
m_layer_map.map (lp, i->second);
|
||||
|
||||
m_new_layers.erase (i);
|
||||
|
||||
}
|
||||
|
||||
i = ii;
|
||||
|
||||
}
|
||||
|
||||
// assign fixed layer numbers for all layers whose name is a LxDy or Lx notation unless there is already a layer with that layer/datatype
|
||||
for (std::map<std::string, unsigned int>::iterator i = m_new_layers.begin (); i != m_new_layers.end (); ) {
|
||||
|
||||
std::map<std::string, unsigned int>::iterator ii = i;
|
||||
++ii;
|
||||
|
||||
int l = -1, d = -1;
|
||||
std::string n;
|
||||
|
||||
if (extract_ld (i->first.c_str (), l, d, n) && used_ld.find (std::make_pair (l, d)) == used_ld.end ()) {
|
||||
|
||||
used_ld.insert (std::make_pair (l, d));
|
||||
|
||||
db::LayerProperties lp;
|
||||
lp.layer = l;
|
||||
lp.datatype = d;
|
||||
lp.name = n;
|
||||
layout.set_properties (i->second, lp);
|
||||
m_layer_map.map (lp, i->second);
|
||||
|
||||
m_new_layers.erase (i);
|
||||
|
||||
}
|
||||
|
||||
i = ii;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// insert the remaining ones
|
||||
for (std::map<std::string, unsigned int>::const_iterator i = m_new_layers.begin (); i != m_new_layers.end (); ++i) {
|
||||
db::LayerProperties lp;
|
||||
lp.name = i->first;
|
||||
layout.set_properties (i->second, lp);
|
||||
m_layer_map.map (lp, i->second);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// DXFReader
|
||||
|
||||
|
|
@ -57,11 +288,10 @@ static std::string zero_layer_name ("0");
|
|||
|
||||
DXFReader::DXFReader (tl::InputStream &s)
|
||||
: m_stream (s),
|
||||
m_create_layers (true),
|
||||
m_progress (tl::to_string (QObject::tr ("Reading DXF file")), 1000),
|
||||
m_dbu (0.001), m_unit (1.0), m_text_scaling (1.0), m_polyline_mode (0), m_circle_points (100), m_circle_accuracy (0.0),
|
||||
m_dbu (0.001), m_unit (1.0), m_text_scaling (1.0), m_polyline_mode (0), m_circle_points (100), m_circle_accuracy (0.0), m_contour_accuracy (0.0),
|
||||
m_ascii (false), m_initial (true), m_render_texts_as_polygons (false), m_keep_other_cells (false), m_line_number (0),
|
||||
m_zero_layer (0), m_next_layer_index (0)
|
||||
m_zero_layer (0)
|
||||
{
|
||||
m_progress.set_format (tl::to_string (QObject::tr ("%.0fk lines")));
|
||||
m_progress.set_format_unit (1000.0);
|
||||
|
|
@ -301,6 +531,7 @@ DXFReader::read (db::Layout &layout, const db::LoadLayoutOptions &options)
|
|||
m_polyline_mode = specific_options.polyline_mode;
|
||||
m_circle_points = specific_options.circle_points;
|
||||
m_circle_accuracy = specific_options.circle_accuracy;
|
||||
m_contour_accuracy = specific_options.contour_accuracy;
|
||||
m_render_texts_as_polygons = specific_options.render_texts_as_polygons;
|
||||
m_keep_other_cells = specific_options.keep_other_cells;
|
||||
|
||||
|
|
@ -318,10 +549,11 @@ DXFReader::read (db::Layout &layout, const db::LoadLayoutOptions &options)
|
|||
m_stream.reset ();
|
||||
m_initial = true;
|
||||
m_line_number = 0;
|
||||
m_layer_map = specific_options.layer_map;
|
||||
m_layer_map.prepare (layout);
|
||||
m_next_layer_index = 0;
|
||||
m_create_layers = specific_options.create_other_layers;
|
||||
db::LayerMap lm = specific_options.layer_map;
|
||||
lm.prepare (layout);
|
||||
set_layer_map (lm);
|
||||
set_create_layers (specific_options.create_other_layers);
|
||||
set_read_named_layers (specific_options.read_named_layers);
|
||||
|
||||
db::cell_index_type top = layout.add_cell("TOP"); // TODO: make variable ..
|
||||
|
||||
|
|
@ -329,7 +561,7 @@ DXFReader::read (db::Layout &layout, const db::LoadLayoutOptions &options)
|
|||
do_read (layout, top);
|
||||
cleanup (layout, top);
|
||||
|
||||
return m_layer_map;
|
||||
return layer_map ();
|
||||
}
|
||||
|
||||
const LayerMap &
|
||||
|
|
@ -365,144 +597,29 @@ DXFReader::warn (const std::string &msg)
|
|||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
extract_plain_layer (const char *s, int &l)
|
||||
{
|
||||
l = 0;
|
||||
if (! *s) {
|
||||
return false;
|
||||
}
|
||||
while (*s && isdigit (*s)) {
|
||||
l = l * 10 + (unsigned int) (*s - '0');
|
||||
++s;
|
||||
}
|
||||
return (*s == 0);
|
||||
}
|
||||
|
||||
static bool
|
||||
extract_ld (const char *s, int &l, int &d, std::string &n)
|
||||
{
|
||||
l = d = 0;
|
||||
|
||||
if (*s == 'L') {
|
||||
++s;
|
||||
}
|
||||
|
||||
if (! *s || ! isdigit (*s)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (*s && isdigit (*s)) {
|
||||
l = l * 10 + (unsigned int) (*s - '0');
|
||||
++s;
|
||||
}
|
||||
|
||||
if (*s == 'D' || *s == '.') {
|
||||
++s;
|
||||
if (! *s || ! isdigit (*s)) {
|
||||
return false;
|
||||
}
|
||||
while (*s && isdigit (*s)) {
|
||||
d = d * 10 + (unsigned int) (*s - '0');
|
||||
++s;
|
||||
}
|
||||
}
|
||||
|
||||
if (*s && (isspace (*s) || *s == '_')) {
|
||||
++s;
|
||||
n = s;
|
||||
return true;
|
||||
} else if (*s == 0) {
|
||||
n.clear ();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair <bool, unsigned int>
|
||||
std::pair <bool, unsigned int>
|
||||
DXFReader::open_layer (db::Layout &layout, const std::string &n)
|
||||
{
|
||||
std::string name (n);
|
||||
|
||||
int l = -1, d = -1;
|
||||
std::string on;
|
||||
|
||||
std::pair<bool, unsigned int> ll (false, 0);
|
||||
|
||||
if (n == zero_layer_name) {
|
||||
return std::make_pair (true, m_zero_layer);
|
||||
}
|
||||
|
||||
ll = m_layer_map.logical (n);
|
||||
if (! ll.first) {
|
||||
|
||||
if (extract_plain_layer (n.c_str (), l)) {
|
||||
|
||||
db::LayerProperties lp;
|
||||
lp.layer = l;
|
||||
lp.datatype = 0;
|
||||
ll = m_layer_map.logical (lp);
|
||||
|
||||
} else if (extract_ld (n.c_str (), l, d, on)) {
|
||||
|
||||
db::LayerProperties lp;
|
||||
lp.layer = l;
|
||||
lp.datatype = d;
|
||||
lp.name = on;
|
||||
ll = m_layer_map.logical (lp);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (ll.first) {
|
||||
|
||||
// create the layer if it is not part of the layout yet.
|
||||
if (! layout.is_valid_layer (ll.second)) {
|
||||
layout.insert_layer (ll.second, m_layer_map.mapping (ll.second));
|
||||
}
|
||||
|
||||
return ll;
|
||||
|
||||
} else if (! m_create_layers) {
|
||||
|
||||
return std::pair<bool, unsigned int> (false, 0);
|
||||
|
||||
} else {
|
||||
|
||||
std::map <std::string, unsigned int>::const_iterator nl = m_new_layers.find (n);
|
||||
if (nl == m_new_layers.end ()) {
|
||||
|
||||
unsigned int ll = m_next_layer_index++;
|
||||
|
||||
layout.insert_layer (ll, db::LayerProperties ());
|
||||
m_new_layers.insert (std::make_pair (n, ll));
|
||||
|
||||
return std::pair<bool, unsigned int> (true, ll);
|
||||
|
||||
} else {
|
||||
return std::pair<bool, unsigned int> (true, nl->second);
|
||||
}
|
||||
|
||||
return NamedLayerReader::open_layer (layout, n);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
DXFReader::do_read (db::Layout &layout, db::cell_index_type top)
|
||||
{
|
||||
tl::SelfTimer timer (tl::verbosity () >= 21, "File read");
|
||||
|
||||
m_new_layers.clear ();
|
||||
|
||||
// create the zero layer - this is not mapped to GDS but can be specified in the layer mapping as
|
||||
// a layer named "0".
|
||||
std::pair<bool, unsigned int> ll = m_layer_map.logical (zero_layer_name);
|
||||
std::pair<bool, unsigned int> ll = layer_map ().logical (zero_layer_name);
|
||||
if (ll.first) {
|
||||
|
||||
// create the layer if it is not part of the layout yet.
|
||||
if (! layout.is_valid_layer (ll.second)) {
|
||||
layout.insert_layer (ll.second, m_layer_map.mapping (ll.second));
|
||||
layout.insert_layer (ll.second, layer_map ().mapping (ll.second));
|
||||
}
|
||||
|
||||
m_zero_layer = ll.second;
|
||||
|
|
@ -510,13 +627,13 @@ DXFReader::do_read (db::Layout &layout, db::cell_index_type top)
|
|||
} else {
|
||||
|
||||
// or explicitly create the layer:
|
||||
m_zero_layer = m_layer_map.next_index ();
|
||||
m_zero_layer = layer_map ().next_index ();
|
||||
layout.insert_layer (m_zero_layer, db::LayerProperties (0, 0, zero_layer_name));
|
||||
m_layer_map.map (zero_layer_name, m_zero_layer);
|
||||
map_layer (zero_layer_name, m_zero_layer);
|
||||
|
||||
}
|
||||
|
||||
m_next_layer_index = m_layer_map.next_index ();
|
||||
prepare_layers ();
|
||||
|
||||
// Read sections
|
||||
int g;
|
||||
|
|
@ -630,76 +747,7 @@ DXFReader::do_read (db::Layout &layout, db::cell_index_type top)
|
|||
|
||||
}
|
||||
|
||||
// assign layer numbers to new layers
|
||||
if (! m_new_layers.empty ()) {
|
||||
|
||||
std::set<std::pair<int, int> > used_ld;
|
||||
for (db::Layout::layer_iterator l = layout.begin_layers (); l != layout.end_layers (); ++l) {
|
||||
used_ld.insert (std::make_pair((*l).second->layer, (*l).second->datatype));
|
||||
}
|
||||
|
||||
// assign fixed layer numbers for all layers whose name is a fixed number unless there is already a layer with that number
|
||||
for (std::map<std::string, unsigned int>::iterator i = m_new_layers.begin (); i != m_new_layers.end (); ) {
|
||||
|
||||
std::map<std::string, unsigned int>::iterator ii = i;
|
||||
++ii;
|
||||
|
||||
int l = -1;
|
||||
if (extract_plain_layer (i->first.c_str (), l) && used_ld.find (std::make_pair (l, 0)) == used_ld.end ()) {
|
||||
|
||||
used_ld.insert (std::make_pair (l, 0));
|
||||
|
||||
db::LayerProperties lp;
|
||||
lp.layer = l;
|
||||
lp.datatype = 0;
|
||||
layout.set_properties (i->second, lp);
|
||||
m_layer_map.map (lp, i->second);
|
||||
|
||||
m_new_layers.erase (i);
|
||||
|
||||
}
|
||||
|
||||
i = ii;
|
||||
|
||||
}
|
||||
|
||||
// assign fixed layer numbers for all layers whose name is a LxDy or Lx notation unless there is already a layer with that layer/datatype
|
||||
for (std::map<std::string, unsigned int>::iterator i = m_new_layers.begin (); i != m_new_layers.end (); ) {
|
||||
|
||||
std::map<std::string, unsigned int>::iterator ii = i;
|
||||
++ii;
|
||||
|
||||
int l = -1, d = -1;
|
||||
std::string n;
|
||||
|
||||
if (extract_ld (i->first.c_str (), l, d, n) && used_ld.find (std::make_pair (l, d)) == used_ld.end ()) {
|
||||
|
||||
used_ld.insert (std::make_pair (l, d));
|
||||
|
||||
db::LayerProperties lp;
|
||||
lp.layer = l;
|
||||
lp.datatype = d;
|
||||
lp.name = n;
|
||||
layout.set_properties (i->second, lp);
|
||||
m_layer_map.map (lp, i->second);
|
||||
|
||||
m_new_layers.erase (i);
|
||||
|
||||
}
|
||||
|
||||
i = ii;
|
||||
|
||||
}
|
||||
|
||||
// insert the remaining ones
|
||||
for (std::map<std::string, unsigned int>::const_iterator i = m_new_layers.begin (); i != m_new_layers.end (); ++i) {
|
||||
db::LayerProperties lp;
|
||||
lp.name = i->first;
|
||||
layout.set_properties (i->second, lp);
|
||||
m_layer_map.map (lp, i->second);
|
||||
}
|
||||
|
||||
}
|
||||
finish_layers (layout);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -62,9 +62,11 @@ public:
|
|||
polyline_mode (0),
|
||||
circle_points (100),
|
||||
circle_accuracy (0.0),
|
||||
contour_accuracy (0.0),
|
||||
render_texts_as_polygons (false),
|
||||
keep_other_cells (false),
|
||||
create_other_layers (true)
|
||||
create_other_layers (true),
|
||||
read_named_layers (false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -128,6 +130,17 @@ public:
|
|||
*/
|
||||
double circle_accuracy;
|
||||
|
||||
/**
|
||||
* @brief Accuracy for closing polylines
|
||||
*
|
||||
* When polylines need to be connected or closed, this
|
||||
* value is used to indicate the accuracy. This is the value
|
||||
* by while points may be separated and still be considered
|
||||
* connected. The default is 0.0 which implies exact
|
||||
* (within one DBU) closing.
|
||||
*/
|
||||
double contour_accuracy;
|
||||
|
||||
/**
|
||||
* @brief If set to true, converts texts to polygons on read
|
||||
*
|
||||
|
|
@ -160,6 +173,14 @@ public:
|
|||
*/
|
||||
bool create_other_layers;
|
||||
|
||||
/**
|
||||
* @brief A flag indicating whether the names of layers shall be read (maintained)
|
||||
*
|
||||
* Name translation will try to extract GDS layer/datatype numbers from the
|
||||
* layer names. If this value is set to true, no name translation happens.
|
||||
*/
|
||||
bool read_named_layers;
|
||||
|
||||
/**
|
||||
* @brief Implementation of FormatSpecificReaderOptions
|
||||
*/
|
||||
|
|
@ -194,11 +215,111 @@ public:
|
|||
{ }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A reader base class for streams with named-only layers
|
||||
*
|
||||
* This class implements the layer name translation logic.
|
||||
* Specifically:
|
||||
* - a number is translated to the corresponding layer, datatype 0
|
||||
* - Lx is translated to layer x, datatype 0
|
||||
* - Lx_SUFFIX is translated to layer x, datatype 0, name "SUFFIX"
|
||||
* - LxDy is translated to layer x, datatype y
|
||||
* - LxDy_SUFFIX is translated to layer x, datatype y, name "SUFFIX"
|
||||
*
|
||||
* Furthermore, the layer map and creation of new layers is handled in this
|
||||
* base class.
|
||||
*/
|
||||
class DB_PUBLIC NamedLayerReader
|
||||
: public ReaderBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief The constructor
|
||||
*/
|
||||
NamedLayerReader ();
|
||||
|
||||
/**
|
||||
* @brief Sets a value indicating whether to create new layers
|
||||
*/
|
||||
void set_create_layers (bool f);
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether to create new layers
|
||||
*/
|
||||
bool create_layers () const
|
||||
{
|
||||
return m_create_layers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the layer map
|
||||
*/
|
||||
void set_layer_map (const LayerMap &lm);
|
||||
|
||||
/**
|
||||
* @brief Gets the layer map
|
||||
*/
|
||||
const LayerMap &layer_map ()
|
||||
{
|
||||
return m_layer_map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a value indicating whether layer names are kept
|
||||
* If set to true, no name translation is performed and layers are
|
||||
* always named only. If set the false (the default), layer names will
|
||||
* be translated to GDS layer/datatypes if possible.
|
||||
*/
|
||||
void set_read_named_layers (bool f);
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether layer names are kept
|
||||
*/
|
||||
bool read_named_layers () const
|
||||
{
|
||||
return m_read_named_layers;
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Opens a new layer
|
||||
* This method will create or locate a layer for a given name.
|
||||
* The result's first attribute is true, if such a layer could be found
|
||||
* or created. In this case, the second attribute is the layer index.
|
||||
*/
|
||||
std::pair <bool, unsigned int> open_layer (db::Layout &layout, const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief Force mapping of a name to a layer index
|
||||
*/
|
||||
void map_layer (const std::string &name, unsigned int layer);
|
||||
|
||||
/**
|
||||
* @brief Finish reading
|
||||
* This method must be called after the reading has been done.
|
||||
* It will finalize the layers.
|
||||
*/
|
||||
void finish_layers (db::Layout &layout);
|
||||
|
||||
/**
|
||||
* @brief Prepares reading
|
||||
* This method must be called before the reading is done.
|
||||
*/
|
||||
void prepare_layers ();
|
||||
|
||||
private:
|
||||
bool m_create_layers;
|
||||
bool m_read_named_layers;
|
||||
LayerMap m_layer_map;
|
||||
unsigned int m_next_layer_index;
|
||||
std::map <std::string, unsigned int> m_new_layers;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The DXF format stream reader
|
||||
*/
|
||||
class DB_PUBLIC DXFReader
|
||||
: public ReaderBase,
|
||||
: public NamedLayerReader,
|
||||
public DXFDiagnostics
|
||||
{
|
||||
public:
|
||||
|
|
@ -303,8 +424,6 @@ private:
|
|||
};
|
||||
|
||||
tl::InputStream &m_stream;
|
||||
bool m_create_layers;
|
||||
LayerMap m_layer_map;
|
||||
tl::AbsoluteProgress m_progress;
|
||||
double m_dbu;
|
||||
double m_unit;
|
||||
|
|
@ -312,6 +431,7 @@ private:
|
|||
int m_polyline_mode;
|
||||
int m_circle_points;
|
||||
double m_circle_accuracy;
|
||||
double m_contour_accuracy;
|
||||
std::string m_cellname;
|
||||
std::string m_line;
|
||||
bool m_ascii;
|
||||
|
|
@ -320,8 +440,6 @@ private:
|
|||
bool m_keep_other_cells;
|
||||
int m_line_number;
|
||||
unsigned int m_zero_layer;
|
||||
unsigned int m_next_layer_index;
|
||||
std::map <std::string, unsigned int> m_new_layers;
|
||||
std::map <db::cell_index_type, std::string> m_template_cells;
|
||||
std::set <db::cell_index_type> m_used_template_cells;
|
||||
std::map <std::string, db::cell_index_type> m_block_per_name;
|
||||
|
|
@ -329,8 +447,8 @@ private:
|
|||
|
||||
void do_read (db::Layout &layout, db::cell_index_type top);
|
||||
|
||||
std::pair <bool, unsigned int> open_layer (db::Layout &layout, const std::string &name);
|
||||
db::cell_index_type make_layer_variant (db::Layout &layout, const std::string &cellname, db::cell_index_type template_cell, unsigned int layer, double sx, double sy);
|
||||
std::pair <bool, unsigned int> open_layer (db::Layout &layout, const std::string &n);
|
||||
db::cell_index_type make_layer_variant (db::Layout &layout, const std::string &cellname, db::cell_index_type template_cell, unsigned int layer, double sx, double sy);
|
||||
void cleanup (db::Layout &layout, db::cell_index_type top);
|
||||
|
||||
int read_int16 ();
|
||||
|
|
|
|||
Loading…
Reference in New Issue