mirror of https://github.com/KLayout/klayout.git
Merge pull request #2189 from KLayout/feature/issue-2180
Feature/issue 2180
This commit is contained in:
commit
df261559b0
|
|
@ -1155,6 +1155,8 @@ Service::transient_select (const db::DPoint &pos)
|
|||
if (m_cell_inst_service) {
|
||||
|
||||
lay::InstFinder finder (true, view ()->is_editable () && m_top_level_sel, view ()->is_editable () /*full arrays in editable mode*/, true /*enclose instances*/, &m_previous_selection, true /*visible layers only*/);
|
||||
finder.consider_ghost_cells (view ()->ghost_cells_visible ());
|
||||
finder.consider_normal_cells (view ()->cell_box_visible ());
|
||||
|
||||
// go through all transform variants
|
||||
std::set< std::pair<db::DCplxTrans, int> > variants = view ()->cv_transform_variants_with_empty ();
|
||||
|
|
@ -1204,7 +1206,7 @@ Service::transient_select (const db::DPoint &pos)
|
|||
// In viewer mode, individual instances of arrays can be selected. Since that is not supported by
|
||||
// InstanceMarker, we just indicate the individual instance's bounding box.
|
||||
lay::Marker *marker = new lay::Marker (view (), r->cv_index ());
|
||||
db::box_convert<db::CellInst> bc (cv->layout ());
|
||||
db::box_convert<db::CellInst, false> bc (cv->layout ());
|
||||
marker->set (bc (r->back ().inst_ptr.cell_inst ().object ()), gt * r->back ().inst_ptr.cell_inst ().complex_trans (*r->back ().array_inst), tv);
|
||||
marker->set_vertex_size (view ()->default_transient_marker_vertex_size ());
|
||||
marker->set_line_width (view ()->default_transient_marker_line_width ());
|
||||
|
|
@ -1489,6 +1491,8 @@ Service::select (const db::DBox &box, lay::Editable::SelectionMode mode)
|
|||
} else if (m_cell_inst_service) {
|
||||
|
||||
lay::InstFinder finder (box.is_point (), view ()->is_editable () && m_top_level_sel, view ()->is_editable () /*full arrays in editable mode*/, true /*enclose_inst*/, exclude, true /*only visible layers*/);
|
||||
finder.consider_ghost_cells (view ()->ghost_cells_visible ());
|
||||
finder.consider_normal_cells (view ()->cell_box_visible ());
|
||||
|
||||
// go through all cell views
|
||||
std::set< std::pair<db::DCplxTrans, int> > variants = view ()->cv_transform_variants_with_empty ();
|
||||
|
|
@ -1802,7 +1806,7 @@ Service::do_selection_to_view ()
|
|||
if (r->seq () > 0 && m_indicate_secondary_selection) {
|
||||
marker->set_dither_pattern (3);
|
||||
}
|
||||
db::box_convert<db::CellInst> bc (cv->layout ());
|
||||
db::box_convert<db::CellInst, false> bc (cv->layout ());
|
||||
marker->set (bc (r->back ().inst_ptr.cell_inst ().object ()), gt * r->back ().inst_ptr.cell_inst ().complex_trans (*r->back ().array_inst), *tv_list);
|
||||
m_markers.push_back (std::make_pair (r.operator-> (), marker));
|
||||
|
||||
|
|
|
|||
|
|
@ -4507,6 +4507,7 @@ public:
|
|||
menu_entries.push_back (lay::config_menu_item ("show_markers", at, tl::to_string (QObject::tr ("Show Markers")), cfg_markers_visible, "?"));
|
||||
menu_entries.push_back (lay::config_menu_item ("show_texts", at, tl::to_string (QObject::tr ("Show Texts")), cfg_text_visible, "?"));
|
||||
menu_entries.push_back (lay::config_menu_item ("show_cell_boxes", at, tl::to_string (QObject::tr ("Show Cell Frames")), cfg_cell_box_visible, "?"));
|
||||
menu_entries.push_back (lay::config_menu_item ("show_ghost_cells", at, tl::to_string (QObject::tr ("Show Unresolved References")), cfg_ghost_cells_visible, "?"));
|
||||
menu_entries.push_back (lay::config_menu_item ("no_stipples", at, tl::to_string (QObject::tr ("Show Layers Without Fill")), cfg_no_stipple, "?"));
|
||||
menu_entries.push_back (lay::config_menu_item ("synchronized_views", at, tl::to_string (QObject::tr ("Synchronized Views")), cfg_synchronized_views, "?"));
|
||||
menu_entries.push_back (lay::config_menu_item ("edit_top_level_selection:edit_mode", at, tl::to_string (QObject::tr ("Select Top Level Objects")), edt::cfg_edit_top_level_selection, "?"));
|
||||
|
|
|
|||
|
|
@ -721,6 +721,8 @@ InstFinder::InstFinder (bool point_mode, bool top_level_sel, bool full_arrays, b
|
|||
m_full_arrays (full_arrays),
|
||||
m_enclose_insts (enclose_inst),
|
||||
m_visible_layers (visible_layers),
|
||||
m_consider_ghost_cells (true),
|
||||
m_consider_normal_cells (true),
|
||||
mp_view (0),
|
||||
mp_progress (0)
|
||||
{
|
||||
|
|
@ -805,6 +807,12 @@ InstFinder::checkpoint ()
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
InstFinder::consider_cell (const db::Cell &cell) const
|
||||
{
|
||||
return cell.is_ghost_cell () ? m_consider_ghost_cells : m_consider_normal_cells;
|
||||
}
|
||||
|
||||
void
|
||||
InstFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const db::Box & /*scan_box*/, const db::DCplxTrans &vp, const db::ICplxTrans &t, int level)
|
||||
{
|
||||
|
|
@ -818,15 +826,18 @@ InstFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const d
|
|||
++*mp_progress;
|
||||
|
||||
// look for instances to check here ..
|
||||
db::Cell::touching_iterator inst = cell.begin_touching (search_box);
|
||||
while (! inst.at_end ()) {
|
||||
for (db::Cell::touching_iterator inst = cell.begin_touching (search_box); ! inst.at_end (); ++inst) {
|
||||
|
||||
const db::CellInstArray &cell_inst = inst->cell_inst ();
|
||||
const db::Cell &inst_cell = layout ().cell (cell_inst.object ().cell_index ());
|
||||
|
||||
++*mp_progress;
|
||||
|
||||
// just consider the instances exactly at the last level of
|
||||
if (! consider_cell (inst_cell)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// just consider the instances exactly at the last level of
|
||||
// hierarchy (this is where the boxes are drawn) or of cells that
|
||||
// are hidden.
|
||||
if (level == max_level () - 1 || inst_cell.is_proxy () || inst_cell.is_ghost_cell () || mp_view->is_cell_hidden (inst_cell.cell_index (), m_cv_index)) {
|
||||
|
|
@ -887,21 +898,22 @@ InstFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const d
|
|||
|
||||
}
|
||||
|
||||
++inst;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// look for instances to check here ..
|
||||
db::Cell::touching_iterator inst = cell.begin_touching (search_box);
|
||||
while (! inst.at_end ()) {
|
||||
for (db::Cell::touching_iterator inst = cell.begin_touching (search_box); ! inst.at_end (); ++inst) {
|
||||
|
||||
checkpoint ();
|
||||
|
||||
const db::CellInstArray &cell_inst = inst->cell_inst ();
|
||||
const db::Cell &inst_cell = layout ().cell (cell_inst.object ().cell_index ());
|
||||
|
||||
if (! consider_cell (inst_cell)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// just consider the instances exactly at the last level of
|
||||
// hierarchy (this is where the boxes are drawn) or if of cells that
|
||||
// are hidden.
|
||||
|
|
@ -909,7 +921,7 @@ InstFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const d
|
|||
|
||||
db::box_convert <db::CellInst, false> bc (layout ());
|
||||
for (db::CellInstArray::iterator p = cell_inst.begin_touching (search_box, bc); ! p.at_end (); ++p) {
|
||||
|
||||
|
||||
checkpoint ();
|
||||
|
||||
bool match = false;
|
||||
|
|
@ -1000,8 +1012,6 @@ InstFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const d
|
|||
|
||||
}
|
||||
|
||||
++inst;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -343,7 +343,17 @@ public:
|
|||
|
||||
bool find (LayoutViewBase *view, unsigned int cv_index, const db::DCplxTrans &trans, const db::DBox ®ion_mu);
|
||||
bool find (LayoutViewBase *view, const db::DBox ®ion_mu);
|
||||
|
||||
void consider_ghost_cells (bool f)
|
||||
{
|
||||
m_consider_ghost_cells = f;
|
||||
}
|
||||
|
||||
void consider_normal_cells (bool f)
|
||||
{
|
||||
m_consider_normal_cells = f;
|
||||
}
|
||||
|
||||
iterator begin () const
|
||||
{
|
||||
return m_founds.begin ();
|
||||
|
|
@ -360,6 +370,7 @@ private:
|
|||
virtual void visit_cell (const db::Cell &cell, const db::Box &hit_box, const db::Box &scan_box, const db::DCplxTrans &vp, const db::ICplxTrans &t, int level);
|
||||
|
||||
bool find_internal (LayoutViewBase *view, unsigned int cv_index, const db::DCplxTrans &trans_mu, const db::DBox ®ion_mu);
|
||||
bool consider_cell (const db::Cell &cell) const;
|
||||
|
||||
unsigned int m_cv_index;
|
||||
db::cell_index_type m_topcell;
|
||||
|
|
@ -369,6 +380,8 @@ private:
|
|||
bool m_full_arrays;
|
||||
bool m_enclose_insts;
|
||||
bool m_visible_layers;
|
||||
bool m_consider_ghost_cells;
|
||||
bool m_consider_normal_cells;
|
||||
std::vector<int> m_visible_layer_indexes;
|
||||
LayoutViewBase *mp_view;
|
||||
tl::AbsoluteProgress *mp_progress;
|
||||
|
|
|
|||
|
|
@ -343,6 +343,7 @@ LayoutViewBase::init (db::Manager *mgr)
|
|||
m_box_font = 0;
|
||||
m_min_size_for_label = 16;
|
||||
m_cell_box_visible = true;
|
||||
m_ghost_cells_visible = true;
|
||||
m_text_visible = true;
|
||||
m_default_font_size = lay::FixedFont::default_font_size ();
|
||||
m_text_lazy_rendering = true;
|
||||
|
|
@ -964,6 +965,13 @@ LayoutViewBase::configure (const std::string &name, const std::string &value)
|
|||
cell_box_visible (flag);
|
||||
return true;
|
||||
|
||||
} else if (name == cfg_ghost_cells_visible) {
|
||||
|
||||
bool flag;
|
||||
tl::from_string (value, flag);
|
||||
ghost_cells_visible (flag);
|
||||
return true;
|
||||
|
||||
} else if (name == cfg_cell_box_color) {
|
||||
|
||||
tl::Color color;
|
||||
|
|
@ -4333,6 +4341,62 @@ LayoutViewBase::set_view_ops ()
|
|||
}
|
||||
}
|
||||
|
||||
// ghost cells
|
||||
if (m_ghost_cells_visible) {
|
||||
|
||||
lay::ViewOp vop, vopv;
|
||||
|
||||
// context level
|
||||
if (m_ctx_color.is_valid ()) {
|
||||
vop = lay::ViewOp (m_ctx_color.rgb (), lay::ViewOp::Copy, 0, 0, 0);
|
||||
} else {
|
||||
vop = lay::ViewOp (lay::LayerProperties::brighter (box_color.rgb (), brightness_for_context), lay::ViewOp::Copy, 0, 0, 0);
|
||||
}
|
||||
vopv = vop;
|
||||
vopv.shape (lay::ViewOp::Cross);
|
||||
vopv.width (mark_size);
|
||||
|
||||
// fill, frame, text, vertex
|
||||
view_ops.push_back (lay::ViewOp (0, lay::ViewOp::Or, 0, 0, 0));
|
||||
view_ops.push_back (vop);
|
||||
view_ops.push_back (vop);
|
||||
view_ops.push_back (vopv);
|
||||
|
||||
// child level
|
||||
if (m_child_ctx_color.is_valid ()) {
|
||||
vop = lay::ViewOp (m_child_ctx_color.rgb (), lay::ViewOp::Copy, 0, 0, 0);
|
||||
} else {
|
||||
vop = lay::ViewOp (lay::LayerProperties::brighter (box_color.rgb (), brightness_for_context), lay::ViewOp::Copy, 0, 0, 0);
|
||||
}
|
||||
vopv = vop;
|
||||
vopv.shape (lay::ViewOp::Cross);
|
||||
vopv.width (mark_size);
|
||||
|
||||
// fill, frame, text, vertex
|
||||
view_ops.push_back (lay::ViewOp (0, lay::ViewOp::Or, 0, 0, 0));
|
||||
view_ops.push_back (vop);
|
||||
view_ops.push_back (vop);
|
||||
view_ops.push_back (vopv);
|
||||
|
||||
// current level
|
||||
vop = lay::ViewOp (box_color.rgb (), lay::ViewOp::Copy, 0, 0, 0);
|
||||
vopv = vop;
|
||||
vopv.shape (lay::ViewOp::Cross);
|
||||
vopv.width (mark_size);
|
||||
|
||||
// fill, frame, text, vertex
|
||||
view_ops.push_back (lay::ViewOp (0, lay::ViewOp::Or, 0, 0, 0));
|
||||
view_ops.push_back (vop);
|
||||
view_ops.push_back (vop);
|
||||
view_ops.push_back (vopv);
|
||||
|
||||
} else {
|
||||
// invisible
|
||||
for (unsigned int i = 0; i < (unsigned int) planes_per_layer; ++i) { // frame, fill, vertex, text
|
||||
view_ops.push_back (lay::ViewOp (0, lay::ViewOp::Or, 0, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
// sanity check: number of planes defined in layRedrawThreadWorker must match to view_ops layout
|
||||
tl_assert (view_ops.size () == (size_t)cell_box_planes);
|
||||
|
||||
|
|
@ -5385,7 +5449,16 @@ LayoutViewBase::cell_box_visible (bool vis)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
LayoutViewBase::ghost_cells_visible (bool vis)
|
||||
{
|
||||
if (m_ghost_cells_visible != vis) {
|
||||
m_ghost_cells_visible = vis;
|
||||
update_content ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LayoutViewBase::text_font (unsigned int f)
|
||||
{
|
||||
if (m_text_font != f) {
|
||||
|
|
|
|||
|
|
@ -1123,6 +1123,19 @@ public:
|
|||
return m_cell_box_visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Visibility of ghost cells
|
||||
*/
|
||||
void ghost_cells_visible (bool vis);
|
||||
|
||||
/**
|
||||
* @brief Visibility of ghost cells
|
||||
*/
|
||||
bool ghost_cells_visible () const
|
||||
{
|
||||
return m_ghost_cells_visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Min instance label size setter
|
||||
*/
|
||||
|
|
@ -2929,6 +2942,7 @@ private:
|
|||
unsigned int m_box_font;
|
||||
int m_min_size_for_label;
|
||||
bool m_cell_box_visible;
|
||||
bool m_ghost_cells_visible;
|
||||
|
||||
tl::Color m_marker_color;
|
||||
int m_marker_line_width;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ public:
|
|||
options.push_back (std::pair<std::string, std::string> (cfg_cell_box_text_transform, "true"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_cell_box_color, "auto"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_cell_box_visible, "true"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_ghost_cells_visible, "true"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_text_color, "auto"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_text_visible, "true"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_text_lazy_rendering, "true"));
|
||||
|
|
|
|||
|
|
@ -316,6 +316,73 @@ RedrawThreadWorker::perform_task (tl::Task *task)
|
|||
|
||||
transfer ();
|
||||
|
||||
// Draw the ghost cells
|
||||
|
||||
// HINT: the order in which the planes are delivered (the index stored in the first member of the pair below)
|
||||
// must correspond with the order by which the ViewOp's are created inside LayoutView::set_view_ops
|
||||
m_buffers.clear ();
|
||||
for (unsigned int i = 0; i < (unsigned int) planes_per_layer / 3; ++i) {
|
||||
|
||||
// context level planes
|
||||
unsigned int i1 = plain_cell_box_planes + i;
|
||||
mp_canvas->initialize_plane (m_planes[i], i1);
|
||||
m_buffers.push_back (std::make_pair (i1, m_planes [i]));
|
||||
|
||||
// child level planes (if used)
|
||||
unsigned int i2 = plain_cell_box_planes + i + planes_per_layer / 3;
|
||||
mp_canvas->initialize_plane (m_planes [i + planes_per_layer / 3], i2);
|
||||
m_buffers.push_back (std::make_pair (i2, m_planes [i + planes_per_layer / 3]));
|
||||
|
||||
// current level planes
|
||||
unsigned int i3 = plain_cell_box_planes + i + 2 * (planes_per_layer / 3);
|
||||
mp_canvas->initialize_plane (m_planes [i + 2 * (planes_per_layer / 3)], i3);
|
||||
m_buffers.push_back (std::make_pair (i3, m_planes [i + 2 * (planes_per_layer / 3)]));
|
||||
|
||||
}
|
||||
|
||||
// detect whether the text planes are empty. If not, the whole text plane must be redrawn to account for clipped texts
|
||||
text_planes_empty = true;
|
||||
for (unsigned int i = 0; i < (unsigned int) planes_per_layer && text_planes_empty; i += (unsigned int) planes_per_layer / 3) {
|
||||
lay::Bitmap *text = dynamic_cast<lay::Bitmap *> (m_planes[i + 2]);
|
||||
if (text && ! text->empty ()) {
|
||||
text_planes_empty = false;
|
||||
}
|
||||
}
|
||||
|
||||
text_redraw_regions = m_redraw_region;
|
||||
if (! text_planes_empty) {
|
||||
// if there are non-empty text planes, redraw the whole area for texts
|
||||
text_redraw_regions.clear ();
|
||||
text_redraw_regions.push_back(db::Box(0, 0, mp_canvas->canvas_width (), mp_canvas->canvas_height ()));
|
||||
for (unsigned int i = 0; i < (unsigned int) planes_per_layer; i += (unsigned int) planes_per_layer / 3) {
|
||||
lay::Bitmap *text = dynamic_cast<lay::Bitmap *> (m_planes[i + 2]);
|
||||
if (text) {
|
||||
text->clear ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (std::set< std::pair<db::DCplxTrans, int> >::const_iterator b = m_box_variants.begin (); b != m_box_variants.end (); ++b) {
|
||||
|
||||
const lay::CellView &cv = m_cellviews [b->second];
|
||||
if (cv.is_valid () && ! cv->layout ().under_construction () && ! (cv->layout ().manager () && cv->layout ().manager ()->transacting ())) {
|
||||
|
||||
mp_layout = &cv->layout ();
|
||||
m_cv_index = b->second;
|
||||
|
||||
db::CplxTrans trans = m_vp_trans * b->first * db::CplxTrans (mp_layout->dbu ());
|
||||
|
||||
iterate_variants (m_redraw_region, cv.cell_index (), trans, &RedrawThreadWorker::draw_boxes_for_ghosts);
|
||||
iterate_variants (text_redraw_regions, cv.cell_index (), trans, &RedrawThreadWorker::draw_box_properties_for_ghosts);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
transfer ();
|
||||
|
||||
// draw guiding and error shapes
|
||||
|
||||
// HINT: the order in which the planes are delivered (the index stored in the first member of the pair below)
|
||||
// must correspond with the order by which the ViewOp's are created inside LayoutView::set_view_ops
|
||||
m_buffers.clear ();
|
||||
|
|
@ -689,31 +756,51 @@ cells_in (const db::Layout *layout, const db::Cell &cell,
|
|||
}
|
||||
|
||||
bool
|
||||
RedrawThreadWorker::need_draw_box (const db::Layout *layout, const db::Cell &cell, int level)
|
||||
RedrawThreadWorker::need_draw_box (const db::Layout *layout, const db::Cell &cell, int level, bool for_ghosts)
|
||||
{
|
||||
if (level > m_to_level) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_ghost_cells.size () > (size_t) m_cv_index && ! m_ghost_cells [m_cv_index].empty ()) {
|
||||
std::set <std::pair <int, db::cell_index_type> > cache;
|
||||
if (cells_in (layout, cell, m_ghost_cells [m_cv_index], m_to_level - level, cache)) {
|
||||
return true;
|
||||
} else if (for_ghosts) {
|
||||
|
||||
if (m_ghost_cells.size () > (size_t) m_cv_index && ! m_ghost_cells [m_cv_index].empty ()) {
|
||||
std::set <std::pair <int, db::cell_index_type> > cache;
|
||||
if (cells_in (layout, cell, m_ghost_cells [m_cv_index], m_to_level - level, cache)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_hidden_cells.size () > (size_t) m_cv_index && ! m_hidden_cells [m_cv_index].empty ()) {
|
||||
std::set <std::pair <int, db::cell_index_type> > cache;
|
||||
if (cells_in (layout, cell, m_hidden_cells [m_cv_index], m_to_level - level, cache)) {
|
||||
return true;
|
||||
return false;
|
||||
|
||||
} else {
|
||||
|
||||
if (m_hidden_cells.size () > (size_t) m_cv_index && ! m_hidden_cells [m_cv_index].empty ()) {
|
||||
std::set <std::pair <int, db::cell_index_type> > cache;
|
||||
if (cells_in (layout, cell, m_hidden_cells [m_cv_index], m_to_level - level, cache)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return int (cell.hierarchy_levels ()) + level >= m_to_level;
|
||||
return int (cell.hierarchy_levels ()) + level >= m_to_level;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RedrawThreadWorker::draw_boxes (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const std::vector<db::Box> &redraw_regions, int level)
|
||||
{
|
||||
draw_boxes_impl (drawing_context, ci, trans, redraw_regions, level, false);
|
||||
}
|
||||
|
||||
void
|
||||
RedrawThreadWorker::draw_boxes_for_ghosts (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const std::vector<db::Box> &redraw_regions, int level)
|
||||
{
|
||||
draw_boxes_impl (drawing_context, ci, trans, redraw_regions, level, true);
|
||||
}
|
||||
|
||||
void
|
||||
RedrawThreadWorker::draw_boxes_impl (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const std::vector<db::Box> &redraw_regions, int level, bool for_ghosts)
|
||||
{
|
||||
// do not draw, if there is nothing to draw
|
||||
if (mp_layout->cells () <= ci || redraw_regions.empty ()) {
|
||||
|
|
@ -723,7 +810,7 @@ RedrawThreadWorker::draw_boxes (bool drawing_context, db::cell_index_type ci, co
|
|||
const db::Cell &cell = mp_layout->cell (ci);
|
||||
|
||||
// we will never come to a valid level ..
|
||||
if (! need_draw_box (mp_layout, cell, level)) {
|
||||
if (! need_draw_box (mp_layout, cell, level, for_ghosts)) {
|
||||
return;
|
||||
}
|
||||
if (cell_var_cached (ci, trans)) {
|
||||
|
|
@ -731,12 +818,12 @@ RedrawThreadWorker::draw_boxes (bool drawing_context, db::cell_index_type ci, co
|
|||
}
|
||||
|
||||
for (std::vector<db::Box>::const_iterator b = redraw_regions.begin (); b != redraw_regions.end (); ++b) {
|
||||
draw_boxes (drawing_context, ci, trans, *b, level);
|
||||
draw_boxes_impl (drawing_context, ci, trans, *b, level, for_ghosts);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RedrawThreadWorker::draw_boxes (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const db::Box &redraw_box, int level)
|
||||
RedrawThreadWorker::draw_boxes_impl (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const db::Box &redraw_box, int level, bool for_ghosts)
|
||||
{
|
||||
lay::Renderer &r = *mp_renderer;
|
||||
const db::Cell &cell = mp_layout->cell (ci);
|
||||
|
|
@ -749,7 +836,12 @@ RedrawThreadWorker::draw_boxes (bool drawing_context, db::cell_index_type ci, co
|
|||
|
||||
// small cell dropped
|
||||
|
||||
} else if (level == m_to_level || cell.is_ghost_cell () || (m_cv_index < int (m_hidden_cells.size ()) && m_hidden_cells [m_cv_index].find (ci) != m_hidden_cells [m_cv_index].end ())) {
|
||||
} else if (for_ghosts && cell.is_ghost_cell ()) {
|
||||
|
||||
// paint the box on this level
|
||||
draw_cell (drawing_context, level, trans, bbox, empty_cell, mp_layout->display_name (ci));
|
||||
|
||||
} else if (! for_ghosts && ! cell.is_ghost_cell () && (level == m_to_level || (m_cv_index < int (m_hidden_cells.size ()) && m_hidden_cells [m_cv_index].find (ci) != m_hidden_cells [m_cv_index].end ()))) {
|
||||
|
||||
// paint the box on this level
|
||||
draw_cell (drawing_context, level, trans, bbox, empty_cell, mp_layout->display_name (ci));
|
||||
|
|
@ -759,7 +851,7 @@ RedrawThreadWorker::draw_boxes (bool drawing_context, db::cell_index_type ci, co
|
|||
db::DBox dbbox = trans * bbox;
|
||||
if (!empty_cell && (dbbox.width () < 1.5 && dbbox.height () < 1.5)) {
|
||||
|
||||
if (need_draw_box (mp_layout, cell, level)) {
|
||||
if (need_draw_box (mp_layout, cell, level, for_ghosts)) {
|
||||
// the cell is a very small box and we know there must be
|
||||
// some level at which to draw the boundary: just draw it
|
||||
// here and stop looking further down ..
|
||||
|
|
@ -836,7 +928,7 @@ RedrawThreadWorker::draw_boxes (bool drawing_context, db::cell_index_type ci, co
|
|||
if (simplify) {
|
||||
|
||||
// The array can be simplified if there are levels below to draw
|
||||
if (need_draw_box (mp_layout, mp_layout->cell (new_ci), level + 1)) {
|
||||
if (need_draw_box (mp_layout, mp_layout->cell (new_ci), level + 1, for_ghosts)) {
|
||||
|
||||
unsigned int plane_group = 2;
|
||||
if (drawing_context) {
|
||||
|
|
@ -865,7 +957,7 @@ RedrawThreadWorker::draw_boxes (bool drawing_context, db::cell_index_type ci, co
|
|||
test_snapshot (0);
|
||||
db::ICplxTrans t (cell_inst.complex_trans (*p));
|
||||
db::Box new_vp = safe_transformed_box (*v, t.inverted ());
|
||||
draw_boxes (drawing_context, new_ci, trans * t, new_vp, level + 1);
|
||||
draw_boxes_impl (drawing_context, new_ci, trans * t, new_vp, level + 1, for_ghosts);
|
||||
|
||||
if (p.quad_id () > 0 && p.quad_id () != qid) {
|
||||
|
||||
|
|
@ -902,18 +994,30 @@ RedrawThreadWorker::draw_boxes (bool drawing_context, db::cell_index_type ci, co
|
|||
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
RedrawThreadWorker::draw_box_properties (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const std::vector<db::Box> &vp, int level)
|
||||
{
|
||||
draw_box_properties_impl (drawing_context, ci, trans, vp, level, false);
|
||||
}
|
||||
|
||||
void
|
||||
RedrawThreadWorker::draw_box_properties_for_ghosts (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const std::vector<db::Box> &vp, int level)
|
||||
{
|
||||
draw_box_properties_impl (drawing_context, ci, trans, vp, level, true);
|
||||
}
|
||||
|
||||
void
|
||||
RedrawThreadWorker::draw_box_properties_impl (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const std::vector<db::Box> &vp, int level, bool for_ghosts)
|
||||
{
|
||||
if (! m_text_visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
draw_box_properties (drawing_context, ci, trans, vp, level, 0);
|
||||
draw_box_properties_impl (drawing_context, ci, trans, vp, level, 0, for_ghosts);
|
||||
}
|
||||
|
||||
void
|
||||
RedrawThreadWorker::draw_box_properties (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const std::vector<db::Box> &vp, int level, db::properties_id_type prop_id)
|
||||
RedrawThreadWorker::draw_box_properties_impl (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const std::vector<db::Box> &vp, int level, db::properties_id_type prop_id, bool for_ghosts)
|
||||
{
|
||||
// do not draw, if there is nothing to draw
|
||||
if (mp_layout->cells () <= ci || vp.empty ()) {
|
||||
|
|
@ -923,7 +1027,7 @@ RedrawThreadWorker::draw_box_properties (bool drawing_context, db::cell_index_ty
|
|||
const db::Cell &cell = mp_layout->cell (ci);
|
||||
|
||||
// we will never come to a valid level ..
|
||||
if (! need_draw_box (mp_layout, cell, level)) {
|
||||
if (! need_draw_box (mp_layout, cell, level, for_ghosts)) {
|
||||
return;
|
||||
}
|
||||
if (cell_var_cached (ci, trans)) {
|
||||
|
|
@ -931,12 +1035,12 @@ RedrawThreadWorker::draw_box_properties (bool drawing_context, db::cell_index_ty
|
|||
}
|
||||
|
||||
for (std::vector<db::Box>::const_iterator b = vp.begin (); b != vp.end (); ++b) {
|
||||
draw_box_properties (drawing_context, ci, trans, *b, level, prop_id);
|
||||
draw_box_properties_impl (drawing_context, ci, trans, *b, level, prop_id, for_ghosts);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RedrawThreadWorker::draw_box_properties (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const db::Box &vp, int level, db::properties_id_type prop_id)
|
||||
RedrawThreadWorker::draw_box_properties_impl (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const db::Box &vp, int level, db::properties_id_type prop_id, bool for_ghosts)
|
||||
{
|
||||
const db::Cell &cell = mp_layout->cell (ci);
|
||||
|
||||
|
|
@ -948,7 +1052,12 @@ RedrawThreadWorker::draw_box_properties (bool drawing_context, db::cell_index_ty
|
|||
|
||||
// small cell dropped
|
||||
|
||||
} else if (level == m_to_level || cell.is_ghost_cell () || (m_cv_index < int (m_hidden_cells.size ()) && m_hidden_cells [m_cv_index].find (ci) != m_hidden_cells [m_cv_index].end ())) {
|
||||
} else if (for_ghosts && cell.is_ghost_cell ()) {
|
||||
|
||||
// paint the box on this level
|
||||
draw_cell_properties (drawing_context, level, trans, bbox, prop_id);
|
||||
|
||||
} else if (! for_ghosts && ! cell.is_ghost_cell () && (level == m_to_level || (m_cv_index < int (m_hidden_cells.size ()) && m_hidden_cells [m_cv_index].find (ci) != m_hidden_cells [m_cv_index].end ()))) {
|
||||
|
||||
// paint the box on this level
|
||||
draw_cell_properties (drawing_context, level, trans, bbox, prop_id);
|
||||
|
|
@ -1036,7 +1145,7 @@ RedrawThreadWorker::draw_box_properties (bool drawing_context, db::cell_index_ty
|
|||
test_snapshot (0);
|
||||
db::ICplxTrans t (cell_inst.complex_trans (*p));
|
||||
db::Box new_vp = safe_transformed_box (*v, t.inverted ());
|
||||
draw_box_properties (drawing_context, new_ci, trans * t, new_vp, level + 1, cell_inst_prop);
|
||||
draw_box_properties_impl (drawing_context, new_ci, trans * t, new_vp, level + 1, cell_inst_prop, for_ghosts);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,8 @@ class CanvasPlane;
|
|||
|
||||
// some helpful constants
|
||||
const int planes_per_layer = 12;
|
||||
const int cell_box_planes = planes_per_layer; // for cell boxes
|
||||
const int plain_cell_box_planes = planes_per_layer; // for cell boxes, not including ghost_cells
|
||||
const int cell_box_planes = planes_per_layer * 2; // for cell boxes, including ghost cells
|
||||
const int guiding_shape_planes = planes_per_layer; // for guiding shapes
|
||||
const int special_planes_before = cell_box_planes + guiding_shape_planes;
|
||||
const int special_planes_after = 1;
|
||||
|
|
@ -181,11 +182,15 @@ private:
|
|||
void draw_layer_wo_cache (int from_level, int to_level, db::cell_index_type ci, const db::CplxTrans &trans, const std::vector<db::Box> &vv, int level, lay::CanvasPlane *fill, lay::CanvasPlane *frame, lay::CanvasPlane *vertex, lay::CanvasPlane *text, const UpdateSnapshotCallback *update_snapshot);
|
||||
void draw_text_layer (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const std::vector <db::Box> &redraw_regions, int level);
|
||||
void draw_text_layer (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const db::Box &redraw_region, int level, lay::CanvasPlane *fill, lay::CanvasPlane *frame, lay::CanvasPlane *vertex, lay::CanvasPlane *text, Bitmap *opt_bitmap);
|
||||
void draw_boxes_for_ghosts (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const std::vector <db::Box> &redraw_regions, int level);
|
||||
void draw_boxes (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const std::vector <db::Box> &redraw_regions, int level);
|
||||
void draw_boxes (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const db::Box &redraw_region, int level);
|
||||
void draw_boxes_impl (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const std::vector <db::Box> &redraw_regions, int level, bool for_ghosts);
|
||||
void draw_boxes_impl (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const db::Box &redraw_region, int level, bool for_ghosts);
|
||||
void draw_box_properties_for_ghosts (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const std::vector <db::Box> &redraw_regions, int level);
|
||||
void draw_box_properties (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const std::vector <db::Box> &redraw_regions, int level);
|
||||
void draw_box_properties (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const std::vector <db::Box> &redraw_regions, int level, db::properties_id_type prop_id);
|
||||
void draw_box_properties (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const db::Box &redraw_box, int level, db::properties_id_type prop_id);
|
||||
void draw_box_properties_impl (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const std::vector <db::Box> &redraw_regions, int level, bool for_ghosts);
|
||||
void draw_box_properties_impl (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const std::vector <db::Box> &redraw_regions, int level, db::properties_id_type prop_id, bool for_ghosts);
|
||||
void draw_box_properties_impl (bool drawing_context, db::cell_index_type ci, const db::CplxTrans &trans, const db::Box &redraw_box, int level, db::properties_id_type prop_id, bool for_ghosts);
|
||||
void draw_cell (bool drawing_context, int level, const db::CplxTrans &trans, const db::Box &box, bool empty_cell, const std::string &txt);
|
||||
void draw_cell_properties (bool drawing_context, int level, const db::CplxTrans &trans, const db::Box &box, db::properties_id_type prop_id);
|
||||
void draw_cell_shapes (const db::CplxTrans &trans, const db::Cell &cell, const db::Box &vp, lay::CanvasPlane *fill, lay::CanvasPlane *frame, lay::CanvasPlane *vertex, lay::CanvasPlane *text);
|
||||
|
|
@ -199,7 +204,7 @@ private:
|
|||
bool any_shapes (db::cell_index_type cell_index, unsigned int levels);
|
||||
bool any_text_shapes (db::cell_index_type cell_index, unsigned int levels);
|
||||
bool any_cell_box (db::cell_index_type cell_index, unsigned int levels);
|
||||
bool need_draw_box (const db::Layout *layout, const db::Cell &cell, int level);
|
||||
bool need_draw_box (const db::Layout *layout, const db::Cell &cell, int level, bool for_ghosts);
|
||||
|
||||
RedrawThread *mp_redraw_thread;
|
||||
std::vector <db::Box> m_redraw_region;
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ static const std::string cfg_cell_box_text_font ("inst-label-font");
|
|||
static const std::string cfg_cell_box_text_transform ("inst-label-transform");
|
||||
static const std::string cfg_cell_box_color ("inst-color");
|
||||
static const std::string cfg_cell_box_visible ("inst-visible");
|
||||
static const std::string cfg_ghost_cells_visible ("ghost-cells-visible");
|
||||
static const std::string cfg_text_color ("text-color");
|
||||
static const std::string cfg_text_visible ("text-visible");
|
||||
static const std::string cfg_text_lazy_rendering ("text-lazy-rendering");
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>631</width>
|
||||
<height>320</height>
|
||||
<width>656</width>
|
||||
<height>397</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
|
@ -21,13 +21,33 @@
|
|||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="cell_group">
|
||||
<property name="title">
|
||||
<widget class="QCheckBox" name="cell_boxes_visible">
|
||||
<property name="text">
|
||||
<string>Show cell boxes</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="ghost_cells_visible">
|
||||
<property name="text">
|
||||
<string>Show unresolved references (ghost cells) </string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="cell_group">
|
||||
<property name="title">
|
||||
<string>Cell box appearance</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout">
|
||||
<property name="margin" stdset="0">
|
||||
<number>9</number>
|
||||
|
|
|
|||
|
|
@ -207,7 +207,10 @@ LayoutViewConfigPage2a::setup (lay::Dispatcher *root)
|
|||
mp_ui->cell_xform_text_cbx->setChecked (flag);
|
||||
|
||||
root->config_get (cfg_cell_box_visible, flag);
|
||||
mp_ui->cell_group->setChecked (flag);
|
||||
mp_ui->cell_boxes_visible->setChecked (flag);
|
||||
|
||||
root->config_get (cfg_ghost_cells_visible, flag);
|
||||
mp_ui->ghost_cells_visible->setChecked (flag);
|
||||
|
||||
int font = 0;
|
||||
root->config_get (cfg_cell_box_text_font, font);
|
||||
|
|
@ -247,7 +250,8 @@ LayoutViewConfigPage2a::commit (lay::Dispatcher *root)
|
|||
root->config_set (cfg_cell_box_text_transform, mp_ui->cell_xform_text_cbx->isChecked ());
|
||||
root->config_set (cfg_cell_box_text_font, mp_ui->cell_font_cb->currentIndex ());
|
||||
root->config_set (cfg_cell_box_color, mp_ui->cell_box_color_pb->get_color (), ColorConverter ());
|
||||
root->config_set (cfg_cell_box_visible, mp_ui->cell_group->isChecked ());
|
||||
root->config_set (cfg_cell_box_visible, mp_ui->cell_boxes_visible->isChecked ());
|
||||
root->config_set (cfg_ghost_cells_visible, mp_ui->ghost_cells_visible->isChecked ());
|
||||
|
||||
root->config_set (cfg_guiding_shape_visible, mp_ui->pcell_gs_group->isChecked ());
|
||||
root->config_set (cfg_guiding_shape_line_width, mp_ui->pcell_gs_lw->value ());
|
||||
|
|
|
|||
Loading…
Reference in New Issue