Initializing MALY plugin

This commit is contained in:
Matthias Koefferlein 2025-04-27 01:11:38 +02:00
parent 449a9a968e
commit 07eb49d482
14 changed files with 1296 additions and 0 deletions

View File

@ -0,0 +1,123 @@
/*
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 "dbMALY.h"
#include "dbMALYReader.h"
#include "dbStream.h"
#include "tlClassRegistry.h"
namespace db
{
// ---------------------------------------------------------------
// MALYDiagnostics implementation
MALYDiagnostics::~MALYDiagnostics ()
{
// .. nothing yet ..
}
// ---------------------------------------------------------------
// MALY format declaration
class MALYFormatDeclaration
: public db::StreamFormatDeclaration
{
public:
MALYFormatDeclaration ()
{
// .. nothing yet ..
}
virtual std::string format_name () const { return "MALY"; }
virtual std::string format_desc () const { return "MALY jobdeck"; }
virtual std::string format_title () const { return "MALY (MALY jobdeck format)"; }
virtual std::string file_format () const { return "MALY jobdeck files (*.maly *.MALY)"; }
virtual bool detect (tl::InputStream &s) const
{
return false; // @@@
}
virtual ReaderBase *create_reader (tl::InputStream &s) const
{
return new db::MALYReader (s);
}
virtual WriterBase *create_writer () const
{
return 0;
// @@@ return new db::MALYWriter ();
}
virtual bool can_read () const
{
return true;
}
virtual bool can_write () const
{
return false;
// @@@ return true;
}
virtual tl::XMLElementBase *xml_reader_options_element () const
{
return new db::ReaderOptionsXMLElement<db::MALYReaderOptions> ("mag",
tl::make_member (&db::MALYReaderOptions::dbu, "dbu")
/* @@@
tl::make_member (&db::MALYReaderOptions::lambda, "lambda") +
tl::make_member (&db::MALYReaderOptions::layer_map, "layer-map") +
tl::make_member (&db::MALYReaderOptions::create_other_layers, "create-other-layers") +
tl::make_member (&db::MALYReaderOptions::keep_layer_names, "keep-layer-names") +
tl::make_member (&db::MALYReaderOptions::merge, "merge") +
tl::make_element<std::vector<std::string>, db::MALYReaderOptions> (&db::MALYReaderOptions::lib_paths, "lib-paths",
tl::make_member<std::string, std::vector<std::string>::const_iterator, std::vector<std::string> > (&std::vector<std::string>::begin, &std::vector<std::string>::end, &std::vector<std::string>::push_back, "lib-path")
)
*/
);
}
/* @@@
virtual tl::XMLElementBase *xml_writer_options_element () const
{
return new db::WriterOptionsXMLElement<db::MALYWriterOptions> ("mag",
tl::make_member (&db::MALYWriterOptions::lambda, "lambda") +
tl::make_member (&db::MALYWriterOptions::tech, "tech") +
tl::make_member (&db::MALYWriterOptions::write_timestamp, "write-timestamp")
);
}
@@@ */
};
// NOTE: Because MALY has such a high degree of syntactic freedom, the detection is somewhat
// fuzzy: do MALY at the very end of the detection chain
static tl::RegisteredClass<db::StreamFormatDeclaration> reader_decl (new MALYFormatDeclaration (), 2300, "MALY");
// provide a symbol to force linking against
int force_link_MALY = 0;
}

View File

@ -0,0 +1,62 @@
/*
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_dbMALY
#define HDR_dbMALY
#include "dbPoint.h"
#include "tlException.h"
#include "tlInternational.h"
#include "tlString.h"
#include "tlAssert.h"
#include <string>
#include <vector>
namespace db
{
/**
* @brief The diagnostics interface for reporting problems in the reader or writer
*/
class MALYDiagnostics
{
public:
virtual ~MALYDiagnostics ();
/**
* @brief Issue an error with positional information
*/
virtual void error (const std::string &txt) = 0;
/**
* @brief Issue a warning with positional information
*/
virtual void warn (const std::string &txt, int warn_level) = 0;
};
}
#endif

View File

@ -0,0 +1,162 @@
/*
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_dbMALYFormat
#define HDR_dbMALYFormat
#include "dbSaveLayoutOptions.h"
#include "dbLoadLayoutOptions.h"
#include "dbPluginCommon.h"
namespace db
{
/**
* @brief Structure that holds the MALY specific options for the reader
* NOTE: this structure is non-public linkage by intention. This way it's instantiated
* in all compile units and the shared object does not need to be linked.
*/
class DB_PLUGIN_PUBLIC MALYReaderOptions
: public FormatSpecificReaderOptions
{
public:
/**
* @brief The constructor
*/
MALYReaderOptions ()
: dbu (0.001),
create_other_layers (true)
{
// .. nothing yet ..
}
/**
* @brief Specify the database unit to produce
*
* Specify the database unit which the resulting layout will receive.
*/
double dbu;
/**
* @brief Specifies a layer mapping
*
* If a layer mapping is specified, only the given layers are read.
* Otherwise, all layers are read.
* Setting "create_other_layers" to true will make the reader
* create other layers for all layers not given in the layer map.
* Setting an empty layer map and create_other_layers to true effectively
* enables all layers for reading.
*/
db::LayerMap layer_map;
/**
* @brief A flag indicating that a new layers shall be created
*
* If this flag is set to true, layers not listed in the layer map a created
* too.
*/
bool create_other_layers;
/**
* @brief Implementation of FormatSpecificReaderOptions
*/
virtual FormatSpecificReaderOptions *clone () const
{
return new MALYReaderOptions (*this);
}
/**
* @brief Implementation of FormatSpecificReaderOptions
*/
virtual const std::string &format_name () const
{
static const std::string n ("MALY");
return n;
}
};
#if 0 // @@@
/**
* @brief Structure that holds the MALY specific options for the Writer
* NOTE: this structure is non-public linkage by intention. This way it's instantiated
* in all compile units and the shared object does not need to be linked.
*/
class DB_PLUGIN_PUBLIC MALYWriterOptions
: public FormatSpecificWriterOptions
{
public:
/**
* @brief The constructor
*/
MALYWriterOptions ()
: lambda (0.0), write_timestamp (true)
{
// .. nothing yet ..
}
/**
* @brief Specifies the lambda value for writing
*
* The lambda value is the basic scaling parameter.
* If this value is set to 0 or negative, the lambda value stored in the layout
* is used (meta data "lambda").
*/
double lambda;
/**
* @brief Specifies the technology value for writing Magic files
*
* If this value is set an empty string, the technology store in the layout's
* "technology" meta data is used.
*/
std::string tech;
/**
* @brief A value indicating whether the real (true) or fake (false) timestamp is written
*
* A fake, static timestamp is useful for comparing files.
*/
bool write_timestamp;
/**
* @brief Implementation of FormatSpecificWriterOptions
*/
virtual FormatSpecificWriterOptions *clone () const
{
return new MALYWriterOptions (*this);
}
/**
* @brief Implementation of FormatSpecificWriterOptions
*/
virtual const std::string &format_name () const
{
static std::string n ("MALY");
return n;
}
};
#endif
}
#endif

View File

@ -0,0 +1,142 @@
/*
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 "dbMALYReader.h"
#include "dbStream.h"
#include "dbObjectWithProperties.h"
#include "dbArray.h"
#include "dbStatic.h"
#include "dbShapeProcessor.h"
#include "dbTechnology.h"
#include "tlException.h"
#include "tlString.h"
#include "tlClassRegistry.h"
#include "tlFileUtils.h"
#include "tlUri.h"
#include <cctype>
#include <string>
namespace db
{
// ---------------------------------------------------------------
// MALYReader
MALYReader::MALYReader (tl::InputStream &s)
: m_stream (s),
m_progress (tl::to_string (tr ("Reading MALY file")), 1000),
m_dbu (0.001)
{
m_progress.set_format (tl::to_string (tr ("%.0fk lines")));
m_progress.set_format_unit (1000.0);
m_progress.set_unit (100000.0);
}
MALYReader::~MALYReader ()
{
// .. nothing yet ..
}
const LayerMap &
MALYReader::read (db::Layout &layout)
{
return read (layout, db::LoadLayoutOptions ());
}
const LayerMap &
MALYReader::read (db::Layout &layout, const db::LoadLayoutOptions &options)
{
init (options);
prepare_layers (layout);
// @@@
finish_layers (layout);
return layer_map_out ();
}
void
MALYReader::error (const std::string &msg)
{
throw MALYReaderException (msg, m_stream.line_number (), m_stream.source ());
}
void
MALYReader::warn (const std::string &msg, int wl)
{
if (warn_level () < wl) {
return;
}
if (first_warning ()) {
tl::warn << tl::sprintf (tl::to_string (tr ("In file %s:")), m_stream.source ());
}
int ws = compress_warning (msg);
if (ws < 0) {
tl::warn << msg
<< tl::to_string (tr (" (line=")) << m_stream.line_number ()
<< tl::to_string (tr (", file=")) << m_stream.source ()
<< ")";
} else if (ws == 0) {
tl::warn << tl::to_string (tr ("... further warnings of this kind are not shown"));
}
}
std::string
MALYReader::resolve_path (const std::string &path)
{
tl::URI path_uri (path);
if (tl::is_absolute (path_uri.path ())) {
return path_uri.to_string ();
} else {
tl::URI source_uri (m_stream.source ());
source_uri.set_path (tl::dirname (source_uri.path ()));
return source_uri.resolved (tl::URI (path)).to_string ();
}
}
void
MALYReader::do_read (db::Layout &layout, db::cell_index_type cell_index, tl::TextInputStream &stream)
{
try {
// @@@
} catch (tl::Exception &ex) {
error (ex.msg ());
}
}
}

View File

@ -0,0 +1,148 @@
/*
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_dbMALYReader
#define HDR_dbMALYReader
#include "dbPluginCommon.h"
#include "dbNamedLayerReader.h"
#include "dbLayout.h"
#include "dbMALY.h"
#include "dbMALYFormat.h"
#include "dbStreamLayers.h"
#include "dbPropertiesRepository.h"
#include "tlException.h"
#include "tlInternational.h"
#include "tlProgress.h"
#include "tlString.h"
#include "tlStream.h"
#include <map>
#include <set>
namespace db
{
class Technology;
/**
* @brief Generic base class of MALY reader exceptions
*/
class DB_PLUGIN_PUBLIC MALYReaderException
: public ReaderException
{
public:
MALYReaderException (const std::string &msg, size_t l, const std::string &file)
: ReaderException (tl::sprintf (tl::to_string (tr ("%s (line=%ld, file=%s)")), msg, l, file))
{ }
};
/**
* @brief The MALY format stream reader
*/
class DB_PLUGIN_PUBLIC MALYReader
: public NamedLayerReader,
public MALYDiagnostics
{
public:
typedef std::vector<tl::Variant> property_value_list;
/**
* @brief Construct a stream reader object
*
* @param s The stream delegate from which to read stream data from
*/
MALYReader (tl::InputStream &s);
/**
* @brief Destructor
*/
~MALYReader ();
/**
* @brief The basic read method
*
* This method will read the stream data and translate this to
* insert calls into the layout object. This will not do much
* on the layout object beside inserting the objects.
* A set of options can be specified with the LoadLayoutOptions
* object.
* The returned map will contain all layers, the passed
* ones and the newly created ones.
*
* @param layout The layout object to write to
* @param map The LayerMap object
* @param create true, if new layers should be created
* @return The LayerMap object that tells where which layer was loaded
*/
virtual const LayerMap &read (db::Layout &layout, const LoadLayoutOptions &options);
/**
* @brief The basic read method (without mapping)
*
* This method will read the stream data and translate this to
* insert calls into the layout object. This will not do much
* on the layout object beside inserting the objects.
* This version will read all input layers and return a map
* which tells which MALY layer has been read into which logical
* layer.
*
* @param layout The layout object to write to
* @return The LayerMap object
*/
virtual const LayerMap &read (db::Layout &layout);
/**
* @brief Format
*/
virtual const char *format () const { return "MALY"; }
/**
* @brief Issue an error with positional information
*
* Reimplements MALYDiagnostics
*/
virtual void error (const std::string &txt);
/**
* @brief Issue a warning with positional information
*
* Reimplements MALYDiagnostics
*/
virtual void warn (const std::string &txt, int wl = 1);
private:
tl::TextInputStream m_stream;
tl::AbsoluteProgress m_progress;
double m_dbu;
void do_read (db::Layout &layout, db::cell_index_type to_cell, tl::TextInputStream &stream);
std::string resolve_path(const std::string &path);
};
}
#endif

View File

@ -0,0 +1,15 @@
TARGET = maly
DESTDIR = $$OUT_PWD/../../../../db_plugins
include($$PWD/../../../db_plugin.pri)
HEADERS = \
dbMALY.h \
dbMALYReader.h \
dbMALYFormat.h \
SOURCES = \
dbMALY.cc \
dbMALYReader.cc \
gsiDeclDbMALY.cc \

View File

@ -0,0 +1,133 @@
/*
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 "dbMALY.h"
#include "dbMALYReader.h"
#include "dbLoadLayoutOptions.h"
#include "dbSaveLayoutOptions.h"
#include "gsiDecl.h"
namespace gsi
{
// ---------------------------------------------------------------
// gsi Implementation of specific methods
static void set_maly_dbu (db::LoadLayoutOptions *options, double dbu)
{
options->get_options<db::MALYReaderOptions> ().dbu = dbu;
}
static double get_maly_dbu (const db::LoadLayoutOptions *options)
{
return options->get_options<db::MALYReaderOptions> ().dbu;
}
static void set_layer_map (db::LoadLayoutOptions *options, const db::LayerMap &lm, bool f)
{
options->get_options<db::MALYReaderOptions> ().layer_map = lm;
options->get_options<db::MALYReaderOptions> ().create_other_layers = f;
}
static void set_layer_map1 (db::LoadLayoutOptions *options, const db::LayerMap &lm)
{
options->get_options<db::MALYReaderOptions> ().layer_map = lm;
}
static db::LayerMap &get_layer_map (db::LoadLayoutOptions *options)
{
return options->get_options<db::MALYReaderOptions> ().layer_map;
}
static void select_all_layers (db::LoadLayoutOptions *options)
{
options->get_options<db::MALYReaderOptions> ().layer_map = db::LayerMap ();
options->get_options<db::MALYReaderOptions> ().create_other_layers = true;
}
static bool create_other_layers (const db::LoadLayoutOptions *options)
{
return options->get_options<db::MALYReaderOptions> ().create_other_layers;
}
static void set_create_other_layers (db::LoadLayoutOptions *options, bool l)
{
options->get_options<db::MALYReaderOptions> ().create_other_layers = l;
}
// extend lay::LoadLayoutOptions with the MALY options
static
gsi::ClassExt<db::LoadLayoutOptions> maly_reader_options (
gsi::method_ext ("maly_set_layer_map", &set_layer_map, gsi::arg ("map"), gsi::arg ("create_other_layers"),
"@brief Sets the layer map\n"
"This sets a layer mapping for the reader. The layer map allows selection and translation of the original layers, for example to assign layer/datatype numbers to the named layers.\n"
"@param map The layer map to set.\n"
"@param create_other_layers The flag indicating whether other layers will be created as well. Set to false to read only the layers in the layer map.\n"
"\n"
"This method has been added in version 0.26.2."
) +
gsi::method_ext ("maly_layer_map=", &set_layer_map1, gsi::arg ("map"),
"@brief Sets the layer map\n"
"This sets a layer mapping for the reader. Unlike \\maly_set_layer_map, the 'create_other_layers' flag is not changed.\n"
"@param map The layer map to set.\n"
"\n"
"This method has been added in version 0.26.2."
) +
gsi::method_ext ("maly_select_all_layers", &select_all_layers,
"@brief Selects all layers and disables the layer map\n"
"\n"
"This disables any layer map and enables reading of all layers.\n"
"New layers will be created when required.\n"
"\n"
"This method has been added in version 0.26.2."
) +
gsi::method_ext ("maly_layer_map", &get_layer_map,
"@brief Gets the layer map\n"
"@return A reference to the layer map\n"
"\n"
"This method has been added in version 0.26.2."
) +
gsi::method_ext ("maly_create_other_layers?", &create_other_layers,
"@brief Gets a value indicating whether other layers shall be created\n"
"@return True, if other layers will be created.\n"
"This attribute acts together with a layer map (see \\maly_layer_map=). Layers not listed in this map are created as well when "
"\\maly_create_other_layers? is true. Otherwise they are ignored.\n"
"\n"
"This method has been added in version 0.26.2."
) +
gsi::method_ext ("maly_create_other_layers=", &set_create_other_layers, gsi::arg ("create"),
"@brief Specifies whether other layers shall be created\n"
"@param create True, if other layers will be created.\n"
"See \\maly_create_other_layers? for a description of this attribute.\n"
"\n"
"This method has been added in version 0.26.2."
) +
gsi::method_ext ("maly_dbu", &get_maly_dbu,
"@brief Specifies the database unit which the reader uses and produces\n"
"See \\maly_dbu= method for a description of this property.\n"
"\nThis property has been added in version 0.26.2.\n"
),
""
);
}

View File

@ -0,0 +1,183 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MALYReaderOptionPage</class>
<widget class="QWidget" name="MALYReaderOptionPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>584</width>
<height>530</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Input Options</string>
</property>
<layout class="QGridLayout">
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="0" column="1">
<widget class="QLineEdit" name="dbu_le">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Micron</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Database unit </string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QLabel" name="label">
<property name="text">
<string>This is the database unit of the resulting layout. Mask pattern with a different grid are adapted to this database unit through scaling.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="layer_subset_grp">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string/>
</property>
<property name="title">
<string>Layer Subset And Layer Mapping</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="_2">
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="read_all_cbx">
<property name="text">
<string>Read all layers (additionally to the ones in the mapping table)</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="0" rowspan="10" colspan="2">
<widget class="lay::LayerMappingWidget" name="layer_map">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>lay::LayerMappingWidget</class>
<extends>QFrame</extends>
<header>layLayerMappingWidget.h</header>
<container>1</container>
<slots>
<signal>enable_all_layers(bool)</signal>
</slots>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>dbu_le</tabstop>
<tabstop>read_all_cbx</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>layer_map</sender>
<signal>enable_all_layers(bool)</signal>
<receiver>read_all_cbx</receiver>
<slot>setChecked(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>122</x>
<y>186</y>
</hint>
<hint type="destinationlabel">
<x>109</x>
<y>147</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,110 @@
/*
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 "dbMALY.h"
#include "dbMALYReader.h"
#include "dbLoadLayoutOptions.h"
#include "layMALYReaderPlugin.h"
#include "ui_MALYReaderOptionPage.h"
#include "gsiDecl.h"
#include <QFrame>
#include <QFileDialog>
namespace lay
{
// ---------------------------------------------------------------
// MALYReaderOptionPage definition and implementation
MALYReaderOptionPage::MALYReaderOptionPage (QWidget *parent)
: StreamReaderOptionsPage (parent)
{
mp_ui = new Ui::MALYReaderOptionPage ();
mp_ui->setupUi (this);
}
MALYReaderOptionPage::~MALYReaderOptionPage ()
{
delete mp_ui;
mp_ui = 0;
}
void
MALYReaderOptionPage::setup (const db::FormatSpecificReaderOptions *o, const db::Technology * /*tech*/)
{
static const db::MALYReaderOptions default_options;
const db::MALYReaderOptions *options = dynamic_cast<const db::MALYReaderOptions *> (o);
if (!options) {
options = &default_options;
}
mp_ui->dbu_le->setText (tl::to_qstring (tl::to_string (options->dbu)));
mp_ui->layer_map->set_layer_map (options->layer_map);
mp_ui->read_all_cbx->setChecked (options->create_other_layers);
}
void
MALYReaderOptionPage::commit (db::FormatSpecificReaderOptions *o, const db::Technology * /*tech*/)
{
db::MALYReaderOptions *options = dynamic_cast<db::MALYReaderOptions *> (o);
if (options) {
tl::from_string_ext (tl::to_string (mp_ui->dbu_le->text ()), options->dbu);
if (options->dbu > 1000.0 || options->dbu < 1e-9) {
throw tl::Exception (tl::to_string (QObject::tr ("Invalid value for database unit")));
}
options->layer_map = mp_ui->layer_map->get_layer_map ();
options->create_other_layers = mp_ui->read_all_cbx->isChecked ();
}
}
// ---------------------------------------------------------------
// MALYReaderPluginDeclaration definition and implementation
class MALYReaderPluginDeclaration
: public StreamReaderPluginDeclaration
{
public:
MALYReaderPluginDeclaration ()
: StreamReaderPluginDeclaration (db::MALYReaderOptions ().format_name ())
{
// .. nothing yet ..
}
StreamReaderOptionsPage *format_specific_options_page (QWidget *parent) const
{
return new MALYReaderOptionPage (parent);
}
db::FormatSpecificReaderOptions *create_specific_options () const
{
return new db::MALYReaderOptions ();
}
};
static tl::RegisteredClass<lay::PluginDeclaration> plugin_decl (new lay::MALYReaderPluginDeclaration (), 10000, "MALYReader");
}

View File

@ -0,0 +1,59 @@
/*
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_layMALYReaderPlugin_h
#define HDR_layMALYReaderPlugin_h
#include "layStream.h"
#include <QObject>
namespace Ui
{
class MALYReaderOptionPage;
}
namespace lay
{
class MALYReaderOptionPage
: public StreamReaderOptionsPage
{
Q_OBJECT
public:
MALYReaderOptionPage (QWidget *parent);
~MALYReaderOptionPage ();
void setup (const db::FormatSpecificReaderOptions *options, const db::Technology *tech);
void commit (db::FormatSpecificReaderOptions *options, const db::Technology *tech);
private:
Ui::MALYReaderOptionPage *mp_ui;
};
}
#endif

View File

@ -0,0 +1,22 @@
TARGET = maly_ui
DESTDIR = $$OUT_PWD/../../../../lay_plugins
include($$PWD/../../../lay_plugin.pri)
INCLUDEPATH += $$PWD/../db_plugin
DEPENDPATH += $$PWD/../db_plugin
LIBS += -L$$DESTDIR/../db_plugins -lmaly
!isEmpty(RPATH) {
QMAKE_RPATHDIR += $$RPATH/db_plugins
}
HEADERS = \
layMALYReaderPlugin.h \
SOURCES = \
layMALYReaderPlugin.cc \
FORMS = \
MALYReaderOptionPage.ui \

View File

@ -0,0 +1,10 @@
TEMPLATE = subdirs
SUBDIRS = db_plugin unit_tests
unit_tests.depends += db_plugin
!equals(HAVE_QT, "0") {
SUBDIRS += lay_plugin
lay_plugin.depends += db_plugin
}

View File

@ -0,0 +1,108 @@
/*
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 "dbMALYReader.h"
#include "dbLayoutDiff.h"
#include "dbWriter.h"
#include "tlUnitTest.h"
#include <stdlib.h>
static void run_test (tl::TestBase *_this, const std::string &base, const char *file, const char *file_au, const char *map = 0, double lambda = 0.1, double dbu = 0.001, const std::vector<std::string> *lib_paths = 0)
{
db::MALYReaderOptions *opt = new db::MALYReaderOptions();
opt->dbu = dbu;
db::LayerMap lm;
if (map) {
unsigned int ln = 0;
tl::Extractor ex (map);
while (! ex.at_end ()) {
std::string n;
int l;
ex.read_word_or_quoted (n);
ex.test (":");
ex.read (l);
ex.test (",");
lm.map (n, ln++, db::LayerProperties (l, 0));
}
opt->layer_map = lm;
opt->create_other_layers = true;
}
db::LoadLayoutOptions options;
options.set_options (opt);
db::Manager m (false);
db::Layout layout (&m), layout2 (&m), layout2_mag (&m), layout_au (&m);
{
std::string fn (base);
fn += "/maly/";
fn += file;
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (layout, options);
}
std::string tc_name = layout.cell_name (*layout.begin_top_down ());
// normalize the layout by writing to OASIS and reading from ..
std::string tmp_oas_file = _this->tmp_file (tl::sprintf ("%s.oas", tc_name));
std::string tmp_maly_file = _this->tmp_file (tl::sprintf ("%s.mag", tc_name));
{
tl::OutputStream stream (tmp_oas_file);
db::SaveLayoutOptions options;
options.set_format ("OASIS");
db::Writer writer (options);
writer.write (layout, stream);
}
{
tl::InputStream stream (tmp_oas_file);
db::Reader reader (stream);
reader.read (layout2);
}
{
std::string fn (base);
fn += "/maly/";
fn += file_au;
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (layout_au);
}
bool equal = db::compare_layouts (layout2, layout_au, db::layout_diff::f_boxes_as_polygons | db::layout_diff::f_verbose | db::layout_diff::f_flatten_array_insts, 1);
if (! equal) {
_this->raise (tl::sprintf ("Compare failed after reading - see %s vs %s\n", tmp_oas_file, file_au));
}
}
TEST(1)
{
run_test (_this, tl::testdata (), "MALY_TEST.maly", "mag_test_au.oas");
}

View File

@ -0,0 +1,19 @@
DESTDIR_UT = $$OUT_PWD/../../../..
TARGET = maly_tests
include($$PWD/../../../../lib_ut.pri)
SOURCES = \
dbMALYReader.cc \
INCLUDEPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../../../common
DEPENDPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../../../common
LIBS += -L$$DESTDIR_UT -lklayout_db -lklayout_tl -lklayout_gsi
PLUGINPATH = $$OUT_PWD/../../../../db_plugins
QMAKE_RPATHDIR += $$PLUGINPATH
LIBS += -L$$PLUGINPATH -lmaly