mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
3df88ae279
commit
eb23f2690e
|
|
@ -220,7 +220,11 @@ GDS2WriterBase::write_context_cell (db::Layout &layout, const short *time_data,
|
||||||
|
|
||||||
std::vector <std::string> context_prop_strings;
|
std::vector <std::string> context_prop_strings;
|
||||||
|
|
||||||
if (layout.has_context_info ()) {
|
layout.get_context_info (context_prop_strings);
|
||||||
|
|
||||||
|
// @@@ Add context strings for m_prop_names_map and m_prop_values_map and layout properties if needed
|
||||||
|
|
||||||
|
if (! context_prop_strings.empty ()) {
|
||||||
|
|
||||||
// Use a dummy BOUNDARY element to attach the global context
|
// Use a dummy BOUNDARY element to attach the global context
|
||||||
|
|
||||||
|
|
@ -241,18 +245,12 @@ GDS2WriterBase::write_context_cell (db::Layout &layout, const short *time_data,
|
||||||
write_int (0);
|
write_int (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
context_prop_strings.clear ();
|
// Hint: write in the reverse order since this way, the reader is more efficient (it knows how many strings
|
||||||
|
// will arrive)
|
||||||
if (layout.get_context_info (context_prop_strings)) {
|
for (std::vector <std::string>::const_iterator s = context_prop_strings.end (); s != context_prop_strings.begin (); ) {
|
||||||
|
--s;
|
||||||
// Hint: write in the reverse order since this way, the reader is more efficient (it knows how many strings
|
size_t n = std::distance (std::vector <std::string>::const_iterator (context_prop_strings.begin ()), s);
|
||||||
// will arrive)
|
write_context_string (n, *s);
|
||||||
for (std::vector <std::string>::const_iterator s = context_prop_strings.end (); s != context_prop_strings.begin (); ) {
|
|
||||||
--s;
|
|
||||||
size_t n = std::distance (std::vector <std::string>::const_iterator (context_prop_strings.begin ()), s);
|
|
||||||
write_context_string (n, *s);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
write_record_size (4);
|
write_record_size (4);
|
||||||
|
|
@ -262,7 +260,12 @@ GDS2WriterBase::write_context_cell (db::Layout &layout, const short *time_data,
|
||||||
|
|
||||||
for (std::vector<db::cell_index_type>::const_iterator cell = cells.begin (); cell != cells.end (); ++cell) {
|
for (std::vector<db::cell_index_type>::const_iterator cell = cells.begin (); cell != cells.end (); ++cell) {
|
||||||
|
|
||||||
if (layout.has_context_info (*cell)) {
|
context_prop_strings.clear ();
|
||||||
|
layout.get_context_info (*cell, context_prop_strings);
|
||||||
|
|
||||||
|
// @@@ Add cell properties if needed
|
||||||
|
|
||||||
|
if (! context_prop_strings.empty ()) {
|
||||||
|
|
||||||
write_record_size (4);
|
write_record_size (4);
|
||||||
write_record (sSREF);
|
write_record (sSREF);
|
||||||
|
|
@ -276,16 +279,12 @@ GDS2WriterBase::write_context_cell (db::Layout &layout, const short *time_data,
|
||||||
|
|
||||||
context_prop_strings.clear ();
|
context_prop_strings.clear ();
|
||||||
|
|
||||||
if (layout.get_context_info (*cell, context_prop_strings)) {
|
// Hint: write in the reverse order since this way, the reader is more efficient (it knows how many strings
|
||||||
|
// will arrive)
|
||||||
// Hint: write in the reverse order since this way, the reader is more efficient (it knows how many strings
|
for (std::vector <std::string>::const_iterator s = context_prop_strings.end (); s != context_prop_strings.begin (); ) {
|
||||||
// will arrive)
|
--s;
|
||||||
for (std::vector <std::string>::const_iterator s = context_prop_strings.end (); s != context_prop_strings.begin (); ) {
|
size_t n = std::distance (std::vector <std::string>::const_iterator (context_prop_strings.begin ()), s);
|
||||||
--s;
|
write_context_string (n, *s);
|
||||||
size_t n = std::distance (std::vector <std::string>::const_iterator (context_prop_strings.begin ()), s);
|
|
||||||
write_context_string (n, *s);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
write_record_size (4);
|
write_record_size (4);
|
||||||
|
|
@ -538,23 +537,32 @@ GDS2WriterBase::write (db::Layout &layout, tl::OutputStream &stream, const db::S
|
||||||
write_double (m_dbu / std::max (1e-9, gds2_options.user_units));
|
write_double (m_dbu / std::max (1e-9, gds2_options.user_units));
|
||||||
write_double (m_dbu * 1e-6);
|
write_double (m_dbu * 1e-6);
|
||||||
|
|
||||||
|
// build property translation maps if possible
|
||||||
|
// Property translation maps non-numeric property keys to numeric ones and
|
||||||
|
// complex-type values to string ones. The neccessary maps are included in
|
||||||
|
// the meta data
|
||||||
|
|
||||||
// layout properties
|
// layout properties
|
||||||
|
|
||||||
if (gds2_options.write_file_properties && layout.prop_id () != 0) {
|
if (layout.prop_id () != 0) {
|
||||||
try {
|
if (gds2_options.write_file_properties) {
|
||||||
write_properties (layout, layout.prop_id ());
|
try {
|
||||||
} catch (tl::Exception &ex) {
|
write_properties (layout, layout.prop_id ());
|
||||||
throw tl::Exception (ex.msg () + tl::to_string (tr (", writing layout properties")));
|
} catch (tl::Exception &ex) {
|
||||||
}
|
throw tl::Exception (ex.msg () + tl::to_string (tr (", writing layout properties")));
|
||||||
}
|
}
|
||||||
|
} else if ()
|
||||||
|
|
||||||
// write context info
|
// write context info
|
||||||
|
|
||||||
bool has_context = false;
|
bool has_context = false;
|
||||||
|
|
||||||
if (options.write_context_info ()) {
|
if (options.write_context_info ()) {
|
||||||
has_context = layout.has_context_info ();
|
@@@ require a context if meta data has to be added
|
||||||
for (std::vector<db::cell_index_type>::const_iterator cell = cells.begin (); cell != cells.end () && !has_context; ++cell) {
|
if (! has_context) {
|
||||||
|
has_context = layout.has_context_info ();
|
||||||
|
}
|
||||||
|
for (std::vector<db::cell_index_type>::const_iterator cell = cells.begin (); cell != cells.end () && ! has_context; ++cell) {
|
||||||
has_context = layout.has_context_info (*cell);
|
has_context = layout.has_context_info (*cell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1106,10 +1114,14 @@ GDS2WriterBase::write_polygon (int layer, int datatype, double sf, const db::Sha
|
||||||
void
|
void
|
||||||
GDS2WriterBase::write_properties (const db::Layout & /*layout*/, db::properties_id_type prop_id)
|
GDS2WriterBase::write_properties (const db::Layout & /*layout*/, db::properties_id_type prop_id)
|
||||||
{
|
{
|
||||||
auto props = db::properties (prop_id).to_map ();
|
auto props = db::properties (prop_id);
|
||||||
for (auto p = props.begin (); p != props.end (); ++p) {
|
for (auto p = props.begin (); p != props.end (); ++p) {
|
||||||
|
|
||||||
const tl::Variant &name = p->first;
|
auto pn = m_prop_names_map.find (p->first);
|
||||||
|
auto pv = m_prop_values_map.find (p->second);
|
||||||
|
|
||||||
|
const tl::Variant &value = (pn == m_prop_names_map.end ()) ? db::property_value (p->second) : pn->second;
|
||||||
|
const tl::Variant &name = (pv == m_prop_values_map.end ()) ? db::property_name (p->first) : pv->second;
|
||||||
|
|
||||||
long attr = -1;
|
long attr = -1;
|
||||||
if (name.can_convert_to_long ()) {
|
if (name.can_convert_to_long ()) {
|
||||||
|
|
@ -1122,7 +1134,7 @@ GDS2WriterBase::write_properties (const db::Layout & /*layout*/, db::properties_
|
||||||
write_record (sPROPATTR);
|
write_record (sPROPATTR);
|
||||||
write_short ((int16_t) attr);
|
write_short ((int16_t) attr);
|
||||||
|
|
||||||
write_string_record (sPROPVALUE, p->second.to_string ());
|
write_string_record (sPROPVALUE, value.to_string ());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1152,5 +1164,45 @@ GDS2WriterBase::write_string_record (short record, const std::string &t)
|
||||||
write_string (t);
|
write_string (t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GDS2WriterBase::collect_property_ids (std::set<db::properties_id_type> &property_ids, const db::Layout &layout, const std::vector<cell_index_type> &cells, const std::vector <std::pair <unsigned int, db::LayerProperties> > &layers)
|
||||||
|
{
|
||||||
|
if (layout.prop_id () != 0) {
|
||||||
|
property_ids.insert (layout.prop_id ());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto cell = cells.begin (); cell != cells.end (); ++cell) {
|
||||||
|
|
||||||
|
const db::Cell &cref (layout.cell (*cell));
|
||||||
|
|
||||||
|
if (cref.prop_id () != 0) {
|
||||||
|
property_ids.insert (cref.prop_id ());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (db::Cell::const_iterator inst = cref.begin (); ! inst.at_end (); ++inst) {
|
||||||
|
if (inst->has_prop_id () && inst->prop_id () != 0) {
|
||||||
|
prop_ids_done.insert (inst->prop_id ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto l = layers.begin (); l != layers.end (); ++l) {
|
||||||
|
db::ShapeIterator shape (cref.shapes (l->first).begin (db::ShapeIterator::Properties | db::ShapeIterator::Boxes | db::ShapeIterator::Polygons | db::ShapeIterator::Edges | db::ShapeIterator::Paths | db::ShapeIterator::Texts));
|
||||||
|
while (! shape.at_end ()) {
|
||||||
|
if (shape->has_prop_id () && shape->prop_id () != 0) {
|
||||||
|
prop_ids_done.insert (shape->prop_id ());
|
||||||
|
}
|
||||||
|
shape.finish_array ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GDS2WriterBase::build_property_maps (const std::set<db::properties_id_type> &property_ids)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace db
|
} // namespace db
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,8 @@ private:
|
||||||
bool m_write_cell_properties;
|
bool m_write_cell_properties;
|
||||||
bool m_keep_instances;
|
bool m_keep_instances;
|
||||||
double m_default_text_size;
|
double m_default_text_size;
|
||||||
|
std::map<db::property_values_id_type, tl::Variant> m_prop_values_map;
|
||||||
|
std::map<db::property_names_id_type, tl::Variant> m_prop_names_map;
|
||||||
|
|
||||||
void write_properties (const db::Layout &layout, db::properties_id_type prop_id);
|
void write_properties (const db::Layout &layout, db::properties_id_type prop_id);
|
||||||
void write_context_cell (db::Layout &layout, const short *time_data, const std::vector<cell_index_type> &cells);
|
void write_context_cell (db::Layout &layout, const short *time_data, const std::vector<cell_index_type> &cells);
|
||||||
|
|
@ -183,6 +185,8 @@ private:
|
||||||
void write_cell (db::Layout &layout, const db::Cell &cref, const std::vector <std::pair <unsigned int, db::LayerProperties> > &layers,
|
void write_cell (db::Layout &layout, const db::Cell &cref, const std::vector <std::pair <unsigned int, db::LayerProperties> > &layers,
|
||||||
const std::set <db::cell_index_type> &cell_set, double sf, short *time_data);
|
const std::set <db::cell_index_type> &cell_set, double sf, short *time_data);
|
||||||
void write_shape (const db::Layout &layout, int layer, int datatype, const db::Shape &shape, double sf);
|
void write_shape (const db::Layout &layout, int layer, int datatype, const db::Shape &shape, double sf);
|
||||||
|
void collect_property_ids (std::set<db::properties_id_type> &property_ids, const db::Layout &layout, const std::vector<cell_index_type> &cells, const std::vector <std::pair <unsigned int, db::LayerProperties> > &layers);
|
||||||
|
void build_property_maps (const std::set<db::properties_id_type> &property_ids);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace db
|
} // namespace db
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue