diff --git a/src/buddies/src/bd/bdWriterOptions.cc b/src/buddies/src/bd/bdWriterOptions.cc index fe039106a..251b7b66a 100644 --- a/src/buddies/src/bd/bdWriterOptions.cc +++ b/src/buddies/src/bd/bdWriterOptions.cc @@ -84,6 +84,10 @@ GenericWriterOptions::init_from_options (const db::SaveLayoutOptions &save_optio m_magic_lambda = 1.0; m_dxf_polygon_mode = save_options.get_option_by_name ("dxf_polygon_mode").to_int (); + + m_lstream_compression_level = save_options.get_option_by_name ("lstream_compression_level").to_int (); + m_lstream_recompress = save_options.get_option_by_name ("lstream_recompress").to_bool (); + m_lstream_permissive = save_options.get_option_by_name ("lstream_permissive").to_bool (); } const std::string GenericWriterOptions::gds2_format_name = "GDS2"; @@ -278,6 +282,34 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin } + if (format.empty () || format == lstream_format_name) { + + // Add LStream format options + std::string group = "[Output options - LStream specific]"; + + cmd << tl::arg (group + + "-oc|--lstr-compression-level=level", &m_lstream_compression_level, "Specifies the LStream compression level", + "This level describes how hard the LStream writer will try to compress the shapes " + "using shape arrays. Building shape arrays may take some time and requires some memory. " + "The default compression level is 2.\n" + "* 0 - no shape array building\n" + "* 1 - nearest neighbor shape array formation\n" + "* 2++ - enhanced shape array search algorithm using 2nd and further neighbor distances as well\n" + ) + << tl::arg (group + + "#--lstr-recompress", &m_lstream_recompress, "Compresses shape arrays again", + "With this option, shape arrays will be expanded and recompressed. This may result in a better " + "compression ratio, but at the cost of slower execution." + ) + << tl::arg (group + + "#--lstr-permissive", &m_lstream_permissive, "Permissive mode", + "In permissive mode, certain forbidden objects are reported as warnings, not as errors: " + "paths with odd width, polygons with less than three points etc." + ) + ; + + } + if (format.empty () || format == dxf_format_name) { // Add DXF format options @@ -419,6 +451,10 @@ GenericWriterOptions::configure (db::SaveLayoutOptions &save_options, const db:: save_options.set_option_by_name ("dxf_polygon_mode", m_dxf_polygon_mode); + save_options.set_option_by_name ("lstream_compression_level", m_lstream_compression_level); + save_options.set_option_by_name ("lstream_recompress", m_lstream_recompress); + save_options.set_option_by_name ("lstream_permissive", m_lstream_permissive); + save_options.set_option_by_name ("mag_lambda", m_magic_lambda); save_options.set_option_by_name ("mag_tech", m_magic_tech); diff --git a/src/buddies/src/bd/bdWriterOptions.h b/src/buddies/src/bd/bdWriterOptions.h index 9319762de..fc55c933e 100644 --- a/src/buddies/src/bd/bdWriterOptions.h +++ b/src/buddies/src/bd/bdWriterOptions.h @@ -149,6 +149,10 @@ private: int m_dxf_polygon_mode; + int m_lstream_compression_level; + bool m_lstream_recompress; + bool m_lstream_permissive; + void set_oasis_substitution_char (const std::string &text); void init_from_options (const db::SaveLayoutOptions &options); }; diff --git a/src/plugins/streamers/cif/db_plugin/dbCIF.cc b/src/plugins/streamers/cif/db_plugin/dbCIF.cc index 3aff1e5f7..69ed925fb 100644 --- a/src/plugins/streamers/cif/db_plugin/dbCIF.cc +++ b/src/plugins/streamers/cif/db_plugin/dbCIF.cc @@ -72,6 +72,14 @@ public: // by the stream and won't trigger a reset of the stream which is not available // on some sources. std::string head = s.read_all (4000); + + // CIF files must not contain null characters + for (auto c = head.begin (); c != head.end (); ++c) { + if (*c == 0) { + return false; + } + } + int n = 0; tl::Extractor ex (head.c_str ()); diff --git a/src/plugins/streamers/lstream/db_plugin/lstrPlugin.cc b/src/plugins/streamers/lstream/db_plugin/lstrPlugin.cc index 176499ea5..67e3f2105 100644 --- a/src/plugins/streamers/lstream/db_plugin/lstrPlugin.cc +++ b/src/plugins/streamers/lstream/db_plugin/lstrPlugin.cc @@ -115,7 +115,7 @@ class LStreamFormatDeclaration } }; -static tl::RegisteredClass format_decl (new LStreamFormatDeclaration (), 0, "LStream"); +static tl::RegisteredClass format_decl (new LStreamFormatDeclaration (), 2050, "LStream"); } diff --git a/src/plugins/streamers/lstream/db_plugin/lstrWriter.cc b/src/plugins/streamers/lstream/db_plugin/lstrWriter.cc index e4951130c..2db530382 100644 --- a/src/plugins/streamers/lstream/db_plugin/lstrWriter.cc +++ b/src/plugins/streamers/lstream/db_plugin/lstrWriter.cc @@ -91,6 +91,18 @@ Writer::write (db::Layout &layout, tl::OutputStream &stream, const db::SaveLayou m_compression_level = lstr_options.compression_level; m_recompress = lstr_options.recompress; + double dbu = (options.dbu () == 0.0) ? layout.dbu () : options.dbu (); + double sf = options.scale_factor () * (layout.dbu () / dbu); + if (fabs (sf - 1.0) < 1e-9) { + // to avoid rounding problems, set to 1.0 exactly if possible. + sf = 1.0; + } + + // TODO: implement + if (sf != 1.0) { + throw tl::Exception (tl::to_string (tr ("Scaling is not supported in LStream writer currently"))); + } + mp_stream = &stream; m_options = options; mp_layout = &layout; diff --git a/src/plugins/streamers/lstream/lay_plugin/LStreamWriterOptionPage.ui b/src/plugins/streamers/lstream/lay_plugin/LStreamWriterOptionPage.ui new file mode 100644 index 000000000..8b66e7aa8 --- /dev/null +++ b/src/plugins/streamers/lstream/lay_plugin/LStreamWriterOptionPage.ui @@ -0,0 +1,283 @@ + + + LStreamWriterOptionPage + + + + 0 + 0 + 633 + 338 + + + + Form + + + + 6 + + + 9 + + + 9 + + + 9 + + + 9 + + + + + LStream Writer Options + + + + 6 + + + 9 + + + 9 + + + 9 + + + 9 + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 6 + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 0 + 0 + + + + Compaction level +(repetition detection) + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + 0 + 0 + + + + 0 (low) + + + + + + + Permissive mode + + + + + + + + 0 + 0 + + + + 10 + + + 1 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + + + + + Don't fail on paths with odd width and other odd shapes + + + + + + + + 0 + 0 + + + + (high) 10 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + Qt::Vertical + + + + 524 + 51 + + + + + + + + compression_slider + + + + diff --git a/src/plugins/streamers/lstream/lay_plugin/layLStreamWriterPlugin.cc b/src/plugins/streamers/lstream/lay_plugin/layLStreamWriterPlugin.cc new file mode 100644 index 000000000..504391031 --- /dev/null +++ b/src/plugins/streamers/lstream/lay_plugin/layLStreamWriterPlugin.cc @@ -0,0 +1,99 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + 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, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + +#include "dbSaveLayoutOptions.h" +#include "lstrWriter.h" +#include "lstrFormat.h" +#include "layLStreamWriterPlugin.h" + +#include + +namespace lay +{ + +// --------------------------------------------------------------- +// LStreamWriterOptionPage definition and implementation + +LStreamWriterOptionPage::LStreamWriterOptionPage (QWidget *parent) + : StreamWriterOptionsPage (parent) +{ + mp_ui = new Ui::LStreamWriterOptionPage (); + mp_ui->setupUi (this); +} + +LStreamWriterOptionPage::~LStreamWriterOptionPage () +{ + delete mp_ui; +} + +void +LStreamWriterOptionPage::setup (const db::FormatSpecificWriterOptions *o, const db::Technology * /*tech*/) +{ + const lstr::WriterOptions *options = dynamic_cast (o); + if (options) { + mp_ui->compression_slider->setValue (options->compression_level); + mp_ui->permissive->setChecked (options->permissive); + } +} + +void +LStreamWriterOptionPage::commit (db::FormatSpecificWriterOptions *o, const db::Technology * /*tech*/, bool gzip) +{ + lstr::WriterOptions *options = dynamic_cast (o); + if (options) { + options->compression_level = mp_ui->compression_slider->value (); + options->permissive = mp_ui->permissive->isChecked (); + } +} + +// --------------------------------------------------------------- +// LStreamWriterPluginDeclaration definition and implementation + +class LStreamWriterPluginDeclaration + : public StreamWriterPluginDeclaration +{ +public: + LStreamWriterPluginDeclaration () + : StreamWriterPluginDeclaration (lstr::WriterOptions ().format_name ()) + { + // .. nothing yet .. + } + + StreamWriterOptionsPage *format_specific_options_page (QWidget *parent) const + { + return new LStreamWriterOptionPage (parent); + } + + db::FormatSpecificWriterOptions *create_specific_options () const + { + return new lstr::WriterOptions (); + } +}; + +static tl::RegisteredClass plugin_decl (new lay::LStreamWriterPluginDeclaration (), 10002, "LStreamWriter"); + +} + + + + diff --git a/src/plugins/streamers/lstream/lay_plugin/layLStreamWriterPlugin.h b/src/plugins/streamers/lstream/lay_plugin/layLStreamWriterPlugin.h new file mode 100644 index 000000000..3b7510e5c --- /dev/null +++ b/src/plugins/streamers/lstream/lay_plugin/layLStreamWriterPlugin.h @@ -0,0 +1,52 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + 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, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + +#ifndef HDR_layLStreamWriterPlugin_h +#define HDR_layLStreamWriterPlugin_h + +#include "layStream.h" +#include "ui_LStreamWriterOptionPage.h" + +namespace lay +{ + +class LStreamWriterOptionPage + : public StreamWriterOptionsPage +{ +Q_OBJECT + +public: + LStreamWriterOptionPage (QWidget *parent); + ~LStreamWriterOptionPage (); + + void setup (const db::FormatSpecificWriterOptions *options, const db::Technology *tech); + void commit (db::FormatSpecificWriterOptions *options, const db::Technology *tech, bool gzip); + +private: + Ui::LStreamWriterOptionPage *mp_ui; +}; + +} + +#endif + diff --git a/src/plugins/streamers/lstream/lay_plugin/lay_plugin.pro b/src/plugins/streamers/lstream/lay_plugin/lay_plugin.pro index f73d83840..bac0bd3f6 100644 --- a/src/plugins/streamers/lstream/lay_plugin/lay_plugin.pro +++ b/src/plugins/streamers/lstream/lay_plugin/lay_plugin.pro @@ -14,8 +14,12 @@ LIBS += -L$$DESTDIR/../db_plugins -llstream HEADERS = \ layLStreamReaderPlugin.h \ + layLStreamWriterPlugin.h \ SOURCES = \ layLStreamReaderPlugin.cc \ + layLStreamWriterPlugin.cc \ FORMS = \ + LStreamWriterOptionPage.ui \ +