mirror of https://github.com/KLayout/klayout.git
commit
addb7148f6
|
|
@ -133,6 +133,12 @@ Object::Object (const ant::Object &d)
|
|||
// .. nothing else ..
|
||||
}
|
||||
|
||||
Object::~Object ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
|
||||
Object &
|
||||
Object::operator= (const ant::Object &d)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -137,6 +137,11 @@ public:
|
|||
*/
|
||||
Object &operator= (const ant::Object &d);
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~Object ();
|
||||
|
||||
/**
|
||||
* @brief Less operator
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1009,6 +1009,7 @@ View::ruler (const ant::Object *r)
|
|||
void
|
||||
View::render (const lay::Viewport &vp, lay::ViewObjectCanvas &canvas)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
if (! mp_ruler) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -1700,6 +1701,7 @@ Service::end_move (const db::DPoint &, lay::angle_constraint_type)
|
|||
void
|
||||
Service::selection_to_view ()
|
||||
{
|
||||
clear_transient_selection ();
|
||||
annotation_selection_changed_event ();
|
||||
|
||||
// the selection objects need to be recreated since we destroyed the old rulers
|
||||
|
|
|
|||
|
|
@ -260,17 +260,23 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
|
|||
}
|
||||
|
||||
{
|
||||
std::string group ("[" + m_group_prefix + " options - CIF and DXF specific]");
|
||||
std::string group ("[" + m_group_prefix + " options - generic]");
|
||||
|
||||
cmd << tl::arg (group +
|
||||
"-" + m_prefix + "d|--" + m_long_prefix + "dbu-in=dbu", this, &GenericReaderOptions::set_dbu, "Specifies the database unit to use",
|
||||
"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)."
|
||||
"This option specifies the database unit the resulting layout will have. "
|
||||
"The value is given in micrometer units. The default value is 1nm (0.001). "
|
||||
"Note that for DEF, UNITS is not taken for the database unit, but this value is used instead.\n"
|
||||
"\n"
|
||||
"CAUTION: for GDS2 and OASIS, this value is ignored and the database unit of the first file "
|
||||
"is used instead. Beware of trouble when blending multiple GDS or OASIS files with different database units."
|
||||
)
|
||||
<< tl::arg (group +
|
||||
"#--" + m_long_prefix + "keep-layer-names", this, &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."
|
||||
"translate them into GDS layer/datatypes.\n"
|
||||
"\n"
|
||||
"This option does not apply to GDS2 and OASIS files."
|
||||
)
|
||||
;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ static tl::PixelBuffer read_pixel_buffer (const std::string &file)
|
|||
#if defined(HAVE_PNG)
|
||||
tl::InputStream stream (file);
|
||||
return tl::PixelBuffer::read_png (stream);
|
||||
#elif defined(HAVE_QT) && defined(HAVE_QTBINDINGS)
|
||||
#elif defined(HAVE_QT)
|
||||
// QImage is fallback
|
||||
QImage img;
|
||||
img.load (tl::to_qstring (file), "PNG");
|
||||
|
|
@ -80,7 +80,7 @@ static tl::PixelBuffer pixel_buffer_from_png (const std::vector<char> &data)
|
|||
tl::InputMemoryStream data_stream (data.begin ().operator-> (), data.size ());
|
||||
tl::InputStream stream (data_stream);
|
||||
return tl::PixelBuffer::read_png (stream);
|
||||
#elif defined(HAVE_QT) && defined(HAVE_QTBINDINGS)
|
||||
#elif defined(HAVE_QT)
|
||||
// QImage is fallback
|
||||
tl_assert (data.size () < std::numeric_limits<int>::max ());
|
||||
QImage img = QImage::fromData ((const uchar *) data.begin ().operator-> (), int (data.size ()));
|
||||
|
|
@ -96,7 +96,7 @@ static void write_pixel_buffer (const tl::PixelBuffer *pb, const std::string &fi
|
|||
#if defined(HAVE_PNG)
|
||||
tl::OutputStream stream (file);
|
||||
pb->write_png (stream);
|
||||
#elif defined(HAVE_QT) && defined(HAVE_QTBINDINGS)
|
||||
#elif defined(HAVE_QT)
|
||||
// QImage is fallback
|
||||
QImage img = pb->to_image ();
|
||||
img.save (tl::to_qstring (file), "PNG");
|
||||
|
|
@ -115,7 +115,7 @@ static std::vector<char> pixel_buffer_to_png (const tl::PixelBuffer *pb)
|
|||
pb->write_png (stream);
|
||||
}
|
||||
return std::vector<char> (data_stream.data (), data_stream.data () + data_stream.size ());
|
||||
#elif defined(HAVE_QT) && defined(HAVE_QTBINDINGS)
|
||||
#elif defined(HAVE_QT)
|
||||
// QImage is fallback
|
||||
QImage img = pb->to_image ();
|
||||
QBuffer data;
|
||||
|
|
|
|||
|
|
@ -418,7 +418,7 @@ Service::Service (db::Manager *manager, lay::LayoutViewBase *view)
|
|||
mp_transient_view (0),
|
||||
m_move_mode (Service::move_none),
|
||||
m_moved_landmark (0),
|
||||
m_keep_selection_for_landmark (false),
|
||||
m_keep_selection_for_move (false),
|
||||
m_images_visible (true)
|
||||
{
|
||||
// place images behind the grid
|
||||
|
|
@ -623,7 +623,7 @@ Service::begin_move (lay::Editable::MoveMode mode, const db::DPoint &p, lay::ang
|
|||
|
||||
m_move_mode = mm;
|
||||
m_moved_landmark = ml;
|
||||
m_keep_selection_for_landmark = true;
|
||||
m_keep_selection_for_move = true;
|
||||
|
||||
// found a handle of one of the selected object: make the moved image the selection
|
||||
clear_selection ();
|
||||
|
|
@ -660,7 +660,7 @@ Service::begin_move (lay::Editable::MoveMode mode, const db::DPoint &p, lay::ang
|
|||
|
||||
m_move_mode = mm;
|
||||
m_moved_landmark = ml;
|
||||
m_keep_selection_for_landmark = false;
|
||||
m_keep_selection_for_move = false;
|
||||
|
||||
// found anything: make the moved image the selection
|
||||
clear_selection ();
|
||||
|
|
@ -893,7 +893,7 @@ Service::end_move (const db::DPoint &, lay::angle_constraint_type)
|
|||
image_changed_event (id);
|
||||
|
||||
// clear the selection (that was artificially created before)
|
||||
if (! m_keep_selection_for_landmark) {
|
||||
if (! m_keep_selection_for_move) {
|
||||
clear_selection ();
|
||||
} else {
|
||||
selection_to_view ();
|
||||
|
|
@ -907,7 +907,11 @@ Service::end_move (const db::DPoint &, lay::angle_constraint_type)
|
|||
image_changed_event (id);
|
||||
|
||||
// clear the selection (that was artificially created before)
|
||||
clear_selection ();
|
||||
if (! m_keep_selection_for_move) {
|
||||
clear_selection ();
|
||||
} else {
|
||||
selection_to_view ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -956,6 +960,7 @@ Service::find_image (const db::DPoint &p, const db::DBox &search_box, double l,
|
|||
void
|
||||
Service::selection_to_view (img::View::Mode mode)
|
||||
{
|
||||
clear_transient_selection ();
|
||||
image_selection_changed_event ();
|
||||
|
||||
// the selection objects need to be recreated since we destroyed the old images
|
||||
|
|
@ -1006,8 +1011,10 @@ Service::transform (const db::DCplxTrans &trans)
|
|||
void
|
||||
Service::edit_cancel ()
|
||||
{
|
||||
m_move_mode = move_none;
|
||||
selection_to_view ();
|
||||
if (m_move_mode != move_none) {
|
||||
m_move_mode = move_none;
|
||||
selection_to_view ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -506,7 +506,7 @@ private:
|
|||
// The index of the landmark being moved
|
||||
size_t m_moved_landmark;
|
||||
// Flag indicating that we want to keep the selection after the landmark was moved
|
||||
bool m_keep_selection_for_landmark;
|
||||
bool m_keep_selection_for_move;
|
||||
// Flag indicating whether images are visible
|
||||
bool m_images_visible;
|
||||
|
||||
|
|
|
|||
|
|
@ -3152,11 +3152,6 @@ MacroEditorDialog::translate_pseudo_id (size_t &file_id, int &line)
|
|||
}
|
||||
}
|
||||
|
||||
static void exit_from_macro ()
|
||||
{
|
||||
throw tl::ExitException ();
|
||||
}
|
||||
|
||||
void
|
||||
MacroEditorDialog::exception_thrown (gsi::Interpreter *interpreter, size_t file_id, int line, const std::string &eclass, const std::string &emsg, const gsi::StackTraceProvider *stack_trace_provider)
|
||||
{
|
||||
|
|
@ -3165,9 +3160,7 @@ MacroEditorDialog::exception_thrown (gsi::Interpreter *interpreter, size_t file_
|
|||
return;
|
||||
}
|
||||
|
||||
if (!m_in_exec) {
|
||||
exit_from_macro ();
|
||||
}
|
||||
exit_if_needed ();
|
||||
|
||||
// avoid recursive breakpoints and exception catches from the console while in a breakpoint or exception stop
|
||||
if (lay::BusySection::is_busy ()) {
|
||||
|
|
@ -3251,17 +3244,25 @@ MacroEditorDialog::exception_thrown (gsi::Interpreter *interpreter, size_t file_
|
|||
throw;
|
||||
}
|
||||
|
||||
if (! m_in_exec) {
|
||||
exit_from_macro ();
|
||||
exit_if_needed ();
|
||||
}
|
||||
|
||||
void
|
||||
MacroEditorDialog::exit_if_needed ()
|
||||
{
|
||||
// Exit if a stop is requested.
|
||||
// NOTE: we must not raise ExitException from outside events (e.g. PyQt5 events)
|
||||
// as ExitException would otherwise terminate the application.
|
||||
// "mp_exec_controller" is 0 in that case.
|
||||
if (! m_in_exec && mp_exec_controller != 0) {
|
||||
throw tl::ExitException ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroEditorDialog::trace (gsi::Interpreter *interpreter, size_t file_id, int line, const gsi::StackTraceProvider *stack_trace_provider)
|
||||
{
|
||||
if (!m_in_exec) {
|
||||
exit_from_macro ();
|
||||
}
|
||||
exit_if_needed ();
|
||||
|
||||
// avoid recursive breakpoints and exception catches from the console while in a breakpoint or exception stop
|
||||
if (lay::BusySection::is_busy ()) {
|
||||
|
|
@ -3310,9 +3311,7 @@ MacroEditorDialog::trace (gsi::Interpreter *interpreter, size_t file_id, int lin
|
|||
throw;
|
||||
}
|
||||
|
||||
if (! m_in_exec) {
|
||||
exit_from_macro ();
|
||||
}
|
||||
exit_if_needed ();
|
||||
|
||||
} else if (++m_trace_count == 20) {
|
||||
|
||||
|
|
@ -3328,9 +3327,7 @@ MacroEditorDialog::trace (gsi::Interpreter *interpreter, size_t file_id, int lin
|
|||
m_last_process_events = tl::Clock::current ();
|
||||
m_process_events_interval = std::max (0.05, std::min (2.0, (m_last_process_events - start).seconds () * 5.0));
|
||||
|
||||
if (!m_in_exec) {
|
||||
exit_from_macro ();
|
||||
}
|
||||
exit_if_needed ();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -302,6 +302,7 @@ private:
|
|||
bool configure (const std::string &name, const std::string &value);
|
||||
void config_finalize ();
|
||||
void translate_pseudo_id (size_t &file_id, int &line);
|
||||
void exit_if_needed ();
|
||||
|
||||
lay::Dispatcher *mp_plugin_root;
|
||||
lym::MacroCollection *mp_root;
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ AnnotationShapes::replace (iterator pos, const shape_type &&sh)
|
|||
manager ()->queue (this, new AnnotationLayerOp (true /*insert*/, sh));
|
||||
}
|
||||
invalidate_state (); // HINT: must come before the change is done!
|
||||
m_layer.replace (pos, sh);
|
||||
m_layer.replace (pos, std::move (sh));
|
||||
}
|
||||
return *pos;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ public:
|
|||
virtual void plugin_removed (lay::PluginDeclaration *cls)
|
||||
{
|
||||
if (mp_delegate) {
|
||||
mp_delegate->plugin_registered (cls);
|
||||
mp_delegate->plugin_removed (cls);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -318,7 +318,6 @@ Editables::transient_to_selection ()
|
|||
{
|
||||
bool had_transient_selection = false;
|
||||
bool had_selection = false;
|
||||
cancel_edits ();
|
||||
for (iterator e = begin (); e != end (); ++e) {
|
||||
if (e->has_selection ()) {
|
||||
had_selection = true;
|
||||
|
|
|
|||
|
|
@ -5305,6 +5305,7 @@ LayoutViewBase::paste_interactive ()
|
|||
void
|
||||
LayoutViewBase::copy ()
|
||||
{
|
||||
cancel_edits ();
|
||||
if (! lay::Editables::has_selection ()) {
|
||||
// try to use the transient selection for the real one
|
||||
lay::Editables::transient_to_selection ();
|
||||
|
|
@ -5316,6 +5317,7 @@ LayoutViewBase::copy ()
|
|||
void
|
||||
LayoutViewBase::cut ()
|
||||
{
|
||||
cancel_edits ();
|
||||
if (! lay::Editables::has_selection ()) {
|
||||
// try to use the transient selection for the real one
|
||||
lay::Editables::transient_to_selection ();
|
||||
|
|
|
|||
|
|
@ -590,6 +590,7 @@ LayoutView::show_properties ()
|
|||
return;
|
||||
}
|
||||
|
||||
cancel_edits ();
|
||||
if (! has_selection ()) {
|
||||
// try to use the transient selection for the real one
|
||||
transient_to_selection ();
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import klayout.dbcore # enables stream reader plugins
|
||||
import klayout.laycore
|
||||
|
||||
from klayout.laycore import *
|
||||
|
|
|
|||
|
|
@ -139,25 +139,16 @@ class LAYPixelBuffer_TestClass < TestBase
|
|||
assert_equal(compare(pb, pb_copy), true)
|
||||
end
|
||||
|
||||
png = nil
|
||||
begin
|
||||
png = pb.to_png_data
|
||||
rescue => ex
|
||||
# No PNG support
|
||||
end
|
||||
png = pb.to_png_data
|
||||
|
||||
if png
|
||||
assert_equal(png.size > 20 && png.size < 200, true) # some range because implementations may differ
|
||||
pb_copy = RBA::PixelBuffer.from_png_data(png)
|
||||
assert_equal(compare(pb, pb_copy), true)
|
||||
|
||||
assert_equal(png.size > 20 && png.size < 200, true) # some range because implementations may differ
|
||||
pb_copy = RBA::PixelBuffer.from_png_data(png)
|
||||
assert_equal(compare(pb, pb_copy), true)
|
||||
|
||||
tmp = File::join($ut_testtmp, "tmp.png")
|
||||
pb.write_png(tmp)
|
||||
pb_copy = RBA::PixelBuffer.read_png(tmp)
|
||||
assert_equal(compare(pb, pb_copy), true)
|
||||
|
||||
end
|
||||
tmp = File::join($ut_testtmp, "tmp.png")
|
||||
pb.write_png(tmp)
|
||||
pb_copy = RBA::PixelBuffer.read_png(tmp)
|
||||
assert_equal(compare(pb, pb_copy), true)
|
||||
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue