mirror of https://github.com/KLayout/klayout.git
WIP: refactoring, debugging needed
This commit is contained in:
parent
e8048d6686
commit
0b0f62130c
|
|
@ -742,7 +742,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
virtual void visit_cell (const db::Cell &cell, const db::Box &search_box, const db::ICplxTrans &t, int /*level*/);
|
||||
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);
|
||||
|
||||
founds_vector_type m_founds;
|
||||
};
|
||||
|
|
@ -751,25 +751,25 @@ private:
|
|||
// PartialShapeFinder implementation
|
||||
|
||||
PartialShapeFinder::PartialShapeFinder (bool point_mode, bool top_level_sel, db::ShapeIterator::flags_type flags)
|
||||
: lay::ShapeFinder (point_mode, top_level_sel, flags)
|
||||
: lay::ShapeFinder (point_mode, top_level_sel, flags, 0)
|
||||
{
|
||||
set_test_count (point_sel_tests);
|
||||
}
|
||||
|
||||
void
|
||||
PartialShapeFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const db::ICplxTrans &t, int /*level*/)
|
||||
PartialShapeFinder::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*/)
|
||||
{
|
||||
if (! point_mode ()) {
|
||||
|
||||
for (std::vector<int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
||||
|
||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (search_box))) {
|
||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (scan_box))) {
|
||||
|
||||
checkpoint ();
|
||||
|
||||
const db::Shapes &shapes = cell.shapes (*l);
|
||||
|
||||
db::ShapeIterator shape = shapes.begin_touching (search_box, flags (), prop_sel (), inv_prop_sel ());
|
||||
db::ShapeIterator shape = shapes.begin_touching (scan_box, flags (), prop_sel (), inv_prop_sel ());
|
||||
while (! shape.at_end ()) {
|
||||
|
||||
checkpoint ();
|
||||
|
|
@ -799,9 +799,9 @@ PartialShapeFinder::visit_cell (const db::Cell &cell, const db::Box &search_box,
|
|||
++ee;
|
||||
unsigned int nn = ee.at_end () ? 0 : n + 1;
|
||||
|
||||
if (search_box.contains ((*e).p1 ())) {
|
||||
if (hit_box.contains ((*e).p1 ())) {
|
||||
edges.push_back (EdgeWithIndex (db::Edge ((*e).p1 (), (*e).p1 ()), n, n, c));
|
||||
if (search_box.contains ((*e).p2 ())) {
|
||||
if (hit_box.contains ((*e).p2 ())) {
|
||||
edges.push_back (EdgeWithIndex (*e, n, nn, c));
|
||||
}
|
||||
}
|
||||
|
|
@ -816,9 +816,9 @@ PartialShapeFinder::visit_cell (const db::Cell &cell, const db::Box &search_box,
|
|||
db::Point pl;
|
||||
unsigned int n = 0;
|
||||
for (db::Shape::point_iterator pt = shape->begin_point (); pt != shape->end_point (); ++pt, ++n) {
|
||||
if (search_box.contains (*pt)) {
|
||||
if (hit_box.contains (*pt)) {
|
||||
edges.push_back (EdgeWithIndex (db::Edge (*pt, *pt), n, n, 0));
|
||||
if (pl_set && search_box.contains (pl)) {
|
||||
if (pl_set && hit_box.contains (pl)) {
|
||||
edges.push_back (EdgeWithIndex (db::Edge (pl, *pt), n - 1, n, 0));
|
||||
}
|
||||
}
|
||||
|
|
@ -840,9 +840,9 @@ PartialShapeFinder::visit_cell (const db::Cell &cell, const db::Box &search_box,
|
|||
++ee;
|
||||
unsigned int nn = ee.at_end () ? 0 : n + 1;
|
||||
|
||||
if (search_box.contains ((*e).p1 ())) {
|
||||
if (hit_box.contains ((*e).p1 ())) {
|
||||
edges.push_back (EdgeWithIndex (db::Edge ((*e).p1 (), (*e).p1 ()), n, n, 0));
|
||||
if (search_box.contains ((*e).p2 ())) {
|
||||
if (hit_box.contains ((*e).p2 ())) {
|
||||
edges.push_back (EdgeWithIndex (*e, n, nn, 0));
|
||||
}
|
||||
}
|
||||
|
|
@ -852,8 +852,21 @@ PartialShapeFinder::visit_cell (const db::Cell &cell, const db::Box &search_box,
|
|||
} else if (shape->is_text ()) {
|
||||
|
||||
db::Point tp (shape->text_trans () * db::Point ());
|
||||
if (search_box.contains (tp)) {
|
||||
edges.push_back (EdgeWithIndex (db::Edge (tp, tp), 0, 0, 0));
|
||||
|
||||
if (text_info ()) {
|
||||
|
||||
db::CplxTrans t_dbu = db::CplxTrans (layout ().dbu ()) * t;
|
||||
db::Box tb = t_dbu.inverted () * text_info ()->bbox (t_dbu * shape->text (), vp);
|
||||
if (tb.inside (hit_box)) {
|
||||
edges.push_back (EdgeWithIndex (db::Edge (tp, tp), 0, 0, 0));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (hit_box.contains (tp)) {
|
||||
edges.push_back (EdgeWithIndex (db::Edge (tp, tp), 0, 0, 0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -875,14 +888,14 @@ PartialShapeFinder::visit_cell (const db::Cell &cell, const db::Box &search_box,
|
|||
|
||||
for (std::vector<int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
||||
|
||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (search_box))) {
|
||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (hit_box))) {
|
||||
|
||||
checkpoint ();
|
||||
|
||||
const db::Shapes &shapes = cell.shapes (*l);
|
||||
std::vector <EdgeWithIndex> edge_sel;
|
||||
|
||||
db::ShapeIterator shape = shapes.begin_touching (search_box, flags (), prop_sel (), inv_prop_sel ());
|
||||
db::ShapeIterator shape = shapes.begin_touching (scan_box, flags (), prop_sel (), inv_prop_sel ());
|
||||
while (! shape.at_end ()) {
|
||||
|
||||
bool match = false;
|
||||
|
|
@ -983,11 +996,27 @@ PartialShapeFinder::visit_cell (const db::Cell &cell, const db::Box &search_box,
|
|||
} else if (shape->is_text ()) {
|
||||
|
||||
db::Point tp (shape->text_trans () * db::Point ());
|
||||
if (search_box.contains (tp)) {
|
||||
d = tp.distance (search_box.center ());
|
||||
edge_sel.clear ();
|
||||
edge_sel.push_back (EdgeWithIndex (db::Edge (tp, tp), 0, 0, 0));
|
||||
match = true;
|
||||
|
||||
if (text_info ()) {
|
||||
|
||||
db::CplxTrans t_dbu = db::CplxTrans (layout ().dbu ()) * t;
|
||||
db::Box tb (t_dbu.inverted () * text_info ()->bbox (t_dbu * shape->text (), vp));
|
||||
if (tb.contains (hit_box.center ())) {
|
||||
d = tp.distance (hit_box.center ());
|
||||
edge_sel.clear ();
|
||||
edge_sel.push_back (EdgeWithIndex (db::Edge (tp, tp), 0, 0, 0));
|
||||
match = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (hit_box.contains (tp)) {
|
||||
d = tp.distance (hit_box.center ());
|
||||
edge_sel.clear ();
|
||||
edge_sel.push_back (EdgeWithIndex (db::Edge (tp, tp), 0, 0, 0));
|
||||
match = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -472,6 +472,8 @@ Service::selection_bbox ()
|
|||
// TODO: this is done multiple times - once for each service!
|
||||
TransformationVariants tv (view ());
|
||||
|
||||
lay::TextInfo text_info (view ());
|
||||
|
||||
db::DBox box;
|
||||
for (objects::const_iterator r = m_selection.begin (); r != m_selection.end (); ++r) {
|
||||
|
||||
|
|
@ -486,7 +488,11 @@ Service::selection_bbox ()
|
|||
const std::vector<db::DCplxTrans> *tv_list = tv.per_cv_and_layer (r->cv_index (), r->layer ());
|
||||
if (tv_list != 0) {
|
||||
for (std::vector<db::DCplxTrans>::const_iterator t = tv_list->begin (); t != tv_list->end (); ++t) {
|
||||
box += *t * (ctx_trans * r->shape ().bbox ());
|
||||
if (r->shape ().is_text ()) {
|
||||
box += *t * text_info.bbox (ctx_trans * r->shape ().text (), *t);
|
||||
} else {
|
||||
box += *t * (ctx_trans * r->shape ().bbox ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "layMarker.h"
|
||||
#include "laySnap.h"
|
||||
#include "layObjectInstPath.h"
|
||||
#include "layTextInfo.h"
|
||||
#include "tlColor.h"
|
||||
#include "dbLayout.h"
|
||||
#include "dbShape.h"
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "tlProgress.h"
|
||||
#include "layFinder.h"
|
||||
#include "layTextInfo.h"
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
|
@ -86,10 +87,11 @@ Finder::closer (double d)
|
|||
}
|
||||
|
||||
void
|
||||
Finder::start (lay::LayoutViewBase *view, const lay::CellView &cv, unsigned int cv_index, const std::vector<db::ICplxTrans> &trans, const db::Box ®ion, int min_level, int max_level, const std::vector<int> &layers)
|
||||
Finder::start (lay::LayoutViewBase *view, unsigned int cv_index, const std::vector<db::DCplxTrans> &trans, const db::DBox ®ion, const db::DBox &scan_region, int min_level, int max_level, const std::vector<int> &layers)
|
||||
{
|
||||
const lay::CellView &cv = view->cellview (cv_index);
|
||||
|
||||
m_layers = layers;
|
||||
m_region = region;
|
||||
mp_layout = &cv->layout ();
|
||||
mp_view = view;
|
||||
m_cv_index = cv_index;
|
||||
|
|
@ -97,17 +99,27 @@ Finder::start (lay::LayoutViewBase *view, const lay::CellView &cv, unsigned int
|
|||
m_max_level = std::max (m_min_level, std::min (max_level, m_top_level_sel ? ((int) cv.specific_path ().size () + 1) : max_level));
|
||||
|
||||
if (layers.size () == 1) {
|
||||
|
||||
m_box_convert = db::box_convert <db::CellInst> (*mp_layout, (unsigned int) layers [0]);
|
||||
m_cell_box_convert = db::box_convert <db::Cell> ((unsigned int) layers [0]);
|
||||
|
||||
} else {
|
||||
|
||||
m_box_convert = db::box_convert <db::CellInst> (*mp_layout);
|
||||
m_cell_box_convert = db::box_convert <db::Cell> ();
|
||||
|
||||
}
|
||||
|
||||
m_path.erase (m_path.begin (), m_path.end ());
|
||||
|
||||
for (std::vector<db::ICplxTrans>::const_iterator t = trans.begin (); t != trans.end (); ++t) {
|
||||
do_find (*cv.cell (), int (cv.specific_path ().size ()), *t * cv.context_trans ());
|
||||
for (std::vector<db::DCplxTrans>::const_iterator t = trans.begin (); t != trans.end (); ++t) {
|
||||
|
||||
db::VCplxTrans it = (*t * db::CplxTrans (mp_layout->dbu ())).inverted ();
|
||||
m_region = it * region;
|
||||
m_scan_region = it * scan_region;
|
||||
|
||||
do_find (*cv.cell (), int (cv.specific_path ().size ()), *t, cv.context_trans ());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -155,7 +167,7 @@ Finder::test_edge (const db::ICplxTrans &trans, const db::Edge &edg, double &dis
|
|||
}
|
||||
|
||||
void
|
||||
Finder::do_find (const db::Cell &cell, int level, const db::ICplxTrans &t)
|
||||
Finder::do_find (const db::Cell &cell, int level, const db::DCplxTrans &vp, const db::ICplxTrans &t)
|
||||
{
|
||||
if (level <= m_max_level /*take level of cell itself*/
|
||||
&& cell.is_proxy ()
|
||||
|
|
@ -164,10 +176,12 @@ Finder::do_find (const db::Cell &cell, int level, const db::ICplxTrans &t)
|
|||
|
||||
// when looking at the guiding shape layer, we can visit this cell as well allowing to find the guiding shapes
|
||||
|
||||
db::Box touch_box (t.inverted () * m_region);
|
||||
db::ICplxTrans it = t.inverted ();
|
||||
db::Box scan_box (it * m_scan_region);
|
||||
db::Box hit_box (it * m_region);
|
||||
|
||||
if (level >= m_min_level) {
|
||||
visit_cell (cell, touch_box, t, level);
|
||||
visit_cell (cell, hit_box, scan_box, vp, t, level);
|
||||
}
|
||||
|
||||
} else if (level < m_max_level
|
||||
|
|
@ -175,22 +189,25 @@ Finder::do_find (const db::Cell &cell, int level, const db::ICplxTrans &t)
|
|||
&& (mp_view->select_inside_pcells_mode () || !cell.is_proxy ())
|
||||
&& !mp_view->is_cell_hidden (cell.cell_index (), m_cv_index)) {
|
||||
|
||||
db::Box touch_box (t.inverted () * m_region);
|
||||
db::ICplxTrans it = t.inverted ();
|
||||
db::Box scan_box (it * m_scan_region);
|
||||
db::Box hit_box (it * m_region);
|
||||
|
||||
if (level >= m_min_level) {
|
||||
visit_cell (cell, touch_box, t, level);
|
||||
visit_cell (cell, hit_box, scan_box, vp, t, level);
|
||||
}
|
||||
|
||||
db::Cell::touching_iterator inst = cell.begin_touching (touch_box);
|
||||
db::Cell::touching_iterator inst = cell.begin_touching (scan_box);
|
||||
while (! inst.at_end ()) {
|
||||
|
||||
const db::CellInstArray &cell_inst = inst->cell_inst ();
|
||||
for (db::CellInstArray::iterator p = cell_inst.begin_touching (touch_box, m_box_convert); ! p.at_end (); ++p) {
|
||||
for (db::CellInstArray::iterator p = cell_inst.begin_touching (scan_box, m_box_convert); ! p.at_end (); ++p) {
|
||||
|
||||
m_path.push_back (db::InstElement (*inst, p));
|
||||
|
||||
do_find (mp_layout->cell (cell_inst.object ().cell_index ()),
|
||||
level + 1,
|
||||
vp,
|
||||
t * cell_inst.complex_trans (*p));
|
||||
|
||||
m_path.pop_back ();
|
||||
|
|
@ -211,6 +228,7 @@ ShapeFinder::ShapeFinder (bool point_mode, bool top_level_sel, db::ShapeIterator
|
|||
: Finder (point_mode, top_level_sel),
|
||||
mp_excludes ((excludes && !excludes->empty ()) ? excludes : 0),
|
||||
m_flags (flags), m_cv_index (0), m_topcell (0),
|
||||
mp_text_info (0),
|
||||
mp_prop_sel (0), m_inv_prop_sel (false), mp_progress (0)
|
||||
{
|
||||
m_tries = point_sel_tests;
|
||||
|
|
@ -275,6 +293,9 @@ ShapeFinder::find (LayoutViewBase *view, const db::DBox ®ion_mu)
|
|||
m_context_layers.clear ();
|
||||
m_cells_with_context.clear ();
|
||||
|
||||
lay::TextInfo text_info (view);
|
||||
mp_text_info = (m_flags & db::ShapeIterator::Texts) != 0 ? &text_info : 0;
|
||||
|
||||
std::vector<lay::LayerPropertiesConstIterator> lprops;
|
||||
for (lay::LayerPropertiesConstIterator lp = view->begin_layers (); ! lp.at_end (); ++lp) {
|
||||
if (lp->is_visual ()) {
|
||||
|
|
@ -340,6 +361,9 @@ ShapeFinder::find (lay::LayoutViewBase *view, const lay::LayerProperties &lprops
|
|||
m_cells_with_context.clear ();
|
||||
m_context_layers.clear ();
|
||||
|
||||
lay::TextInfo text_info (view);
|
||||
mp_text_info = (m_flags & db::ShapeIterator::Texts) != 0 ? &text_info : 0;
|
||||
|
||||
std::vector<int> layers;
|
||||
layers.push_back (lprops.layer_index ());
|
||||
bool result = find_internal (view, lprops.cellview_index (), &lprops.prop_sel (), lprops.inverse_prop_sel (), lprops.hier_levels (), lprops.trans (), layers, region_mu);
|
||||
|
|
@ -360,12 +384,10 @@ ShapeFinder::find_internal (lay::LayoutViewBase *view, unsigned int cv_index, co
|
|||
|
||||
m_topcell = cv.cell_index ();
|
||||
|
||||
double dbu = cv->layout ().dbu ();
|
||||
db::Box region = db::VCplxTrans (1.0 / dbu) * region_mu;
|
||||
std::vector<db::ICplxTrans> trans;
|
||||
trans.reserve(trans_mu.size());
|
||||
for (std::vector<db::DCplxTrans>::const_iterator t = trans_mu.begin(); t != trans_mu.end(); ++t) {
|
||||
trans.push_back(db::VCplxTrans(1.0 / dbu) * *t * db::CplxTrans(dbu));
|
||||
db::DBox scan_region_mu = region_mu;
|
||||
if (mp_text_info) {
|
||||
// for catching all labels we search the whole view area
|
||||
scan_region_mu = view->viewport ().box ();
|
||||
}
|
||||
|
||||
mp_prop_sel = prop_sel;
|
||||
|
|
@ -384,7 +406,7 @@ ShapeFinder::find_internal (lay::LayoutViewBase *view, unsigned int cv_index, co
|
|||
|
||||
// actually find
|
||||
try {
|
||||
start (view, cv, m_cv_index, trans, region, min_level, max_level, layers);
|
||||
start (view, m_cv_index, trans_mu, region_mu, scan_region_mu, min_level, max_level, layers);
|
||||
} catch (StopException) {
|
||||
// ..
|
||||
}
|
||||
|
|
@ -406,7 +428,7 @@ ShapeFinder::checkpoint ()
|
|||
}
|
||||
|
||||
void
|
||||
ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const db::ICplxTrans &t, int /*level*/)
|
||||
ShapeFinder::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*/)
|
||||
{
|
||||
if (! m_context_layers.empty ()) {
|
||||
|
||||
|
|
@ -436,17 +458,25 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const
|
|||
|
||||
for (std::vector<int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
||||
|
||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (search_box))) {
|
||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (scan_box))) {
|
||||
|
||||
const db::Shapes &shapes = cell.shapes ((unsigned int) *l);
|
||||
|
||||
db::ShapeIterator shape = shapes.begin_touching (search_box, m_flags, mp_prop_sel, m_inv_prop_sel);
|
||||
db::ShapeIterator shape = shapes.begin_touching (scan_box, m_flags, mp_prop_sel, m_inv_prop_sel);
|
||||
while (! shape.at_end ()) {
|
||||
|
||||
checkpoint ();
|
||||
|
||||
db::Box bbox;
|
||||
if (text_info () && shape->is_text ()) {
|
||||
db::CplxTrans t_dbu = db::CplxTrans (layout ().dbu ()) * t;
|
||||
bbox = t_dbu.inverted () * text_info ()->bbox (t_dbu * shape->text (), vp);
|
||||
} else {
|
||||
bbox = shape->bbox ();
|
||||
}
|
||||
|
||||
// in box mode, just test the boxes
|
||||
if (shape->bbox ().inside (search_box)) {
|
||||
if (bbox.inside (hit_box)) {
|
||||
|
||||
m_founds.push_back (lay::ObjectInstPath ());
|
||||
m_founds.back ().set_cv_index (m_cv_index);
|
||||
|
|
@ -474,13 +504,13 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const
|
|||
|
||||
for (std::vector<int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
||||
|
||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (search_box))) {
|
||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (scan_box))) {
|
||||
|
||||
checkpoint ();
|
||||
|
||||
const db::Shapes &shapes = cell.shapes (*l);
|
||||
|
||||
db::ShapeIterator shape = shapes.begin_touching (search_box, m_flags, mp_prop_sel, m_inv_prop_sel);
|
||||
db::ShapeIterator shape = shapes.begin_touching (scan_box, m_flags, mp_prop_sel, m_inv_prop_sel);
|
||||
while (! shape.at_end ()) {
|
||||
|
||||
bool match = false;
|
||||
|
|
@ -488,7 +518,7 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const
|
|||
|
||||
checkpoint ();
|
||||
|
||||
db::Point point (search_box.center ());
|
||||
db::Point point (hit_box.center ());
|
||||
|
||||
// in point mode, test the edges and use a "closest" criterion
|
||||
if (shape->is_polygon ()) {
|
||||
|
|
@ -529,9 +559,13 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const
|
|||
match = true;
|
||||
}
|
||||
|
||||
} else if (shape->is_box ()) {
|
||||
} else if (shape->is_box () || shape->is_text ()) {
|
||||
|
||||
const db::Box &box = shape->box ();
|
||||
db::Box box = shape->bbox ();
|
||||
if (text_info () && shape->is_text ()) {
|
||||
db::CplxTrans t_dbu = db::CplxTrans (layout ().dbu ()) * t;
|
||||
box = t_dbu.inverted () * text_info ()->bbox (t_dbu * shape->text (), vp);
|
||||
}
|
||||
|
||||
// point-like boxes are handles which attract the finder
|
||||
if (box.width () == 0 && box.height () == 0) {
|
||||
|
|
@ -545,21 +579,13 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const
|
|||
test_edge (t, *e, d, match);
|
||||
}
|
||||
|
||||
if (! match && box.contains (search_box.center ())) {
|
||||
if (! match && box.contains (hit_box.center ())) {
|
||||
d = t.ctrans (poly_dist (poly.begin_edge (), point));
|
||||
match = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if (shape->is_text ()) {
|
||||
|
||||
db::Point tp (shape->text_trans () * db::Point ());
|
||||
if (search_box.contains (tp)) {
|
||||
d = t.ctrans (tp.distance (search_box.center ()));
|
||||
match = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (match) {
|
||||
|
|
@ -679,14 +705,11 @@ InstFinder::find_internal (LayoutViewBase *view, unsigned int cv_index, const db
|
|||
m_topcell = cv.cell ()->cell_index ();
|
||||
mp_view = view;
|
||||
|
||||
double dbu = cv->layout ().dbu ();
|
||||
db::Box region = db::VCplxTrans (1.0 / dbu) * region_mu;
|
||||
|
||||
// actually find
|
||||
try {
|
||||
std::vector<db::ICplxTrans> tv;
|
||||
tv.push_back (db::VCplxTrans (1.0 / dbu) * trans_mu * db::CplxTrans (dbu));
|
||||
start (view, cv, cv_index, tv, region, view->get_min_hier_levels (), view->get_max_hier_levels (), std::vector<int> ());
|
||||
std::vector<db::DCplxTrans> tv;
|
||||
tv.push_back (trans_mu);
|
||||
start (view, cv_index, tv, region_mu, region_mu, view->get_min_hier_levels (), view->get_max_hier_levels (), std::vector<int> ());
|
||||
} catch (StopException) {
|
||||
// ..
|
||||
}
|
||||
|
|
@ -696,7 +719,7 @@ InstFinder::find_internal (LayoutViewBase *view, unsigned int cv_index, const db
|
|||
}
|
||||
|
||||
void
|
||||
InstFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const db::ICplxTrans &t, int level)
|
||||
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)
|
||||
{
|
||||
if (! point_mode ()) {
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ namespace tl
|
|||
namespace lay
|
||||
{
|
||||
|
||||
class TextInfo;
|
||||
|
||||
/**
|
||||
* @brief A generic finder class
|
||||
*
|
||||
|
|
@ -152,8 +154,17 @@ protected:
|
|||
* are used). For each matching cell, the "visit_cell" method is called. A
|
||||
* path of instantiations up to the top cell is maintained and accessible by
|
||||
* the path() accessor.
|
||||
*
|
||||
* @param view The layout view to run the scan on
|
||||
* @param cv_index The cell view to run the scan on
|
||||
* @param trans A set of visual transformations applied to the display (layer properties transformations) in micron space
|
||||
* @param region The hit region which the object is checked against
|
||||
* @param scan_region The region where the object is looked up (can be bigger than the hit region for visual label box detection)
|
||||
* @param min_level The minimum hierarchy level to check
|
||||
* @param max_level The maximum hierarchy level to check
|
||||
* @param layers A set of layers to check
|
||||
*/
|
||||
void start (LayoutViewBase *view, const lay::CellView &cv, unsigned int cv_index, const std::vector<db::ICplxTrans> &trans, const db::Box ®ion, int min_level, int max_level, const std::vector<int> &layers = std::vector<int> ());
|
||||
void start (LayoutViewBase *view, unsigned int cv_index, const std::vector<db::DCplxTrans> &trans, const db::DBox ®ion, const db::DBox &scan_region, int min_level, int max_level, const std::vector<int> &layers = std::vector<int> ());
|
||||
|
||||
/**
|
||||
* @brief Provide a basic edge test facility
|
||||
|
|
@ -172,7 +183,7 @@ protected:
|
|||
unsigned int test_edge (const db::ICplxTrans &trans, const db::Edge &edge, double &distance, bool &match);
|
||||
|
||||
private:
|
||||
void do_find (const db::Cell &cell, int level, const db::ICplxTrans &t);
|
||||
void do_find (const db::Cell &cell, int level, const db::DCplxTrans &vp, const db::ICplxTrans &t);
|
||||
|
||||
/**
|
||||
* @brief Visitor sugar function
|
||||
|
|
@ -181,7 +192,7 @@ private:
|
|||
* cell. It may use the "closer" method to determine if something is closer
|
||||
* to whatever.
|
||||
*/
|
||||
virtual void visit_cell (const db::Cell &cell, const db::Box &search_box, const db::ICplxTrans &t, int level) = 0;
|
||||
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) = 0;
|
||||
|
||||
int m_min_level, m_max_level;
|
||||
std::vector<db::InstElement> m_path;
|
||||
|
|
@ -189,6 +200,7 @@ private:
|
|||
lay::LayoutViewBase *mp_view;
|
||||
unsigned int m_cv_index;
|
||||
db::Box m_region;
|
||||
db::Box m_scan_region;
|
||||
std::vector<int> m_layers;
|
||||
double m_distance;
|
||||
bool m_point_mode;
|
||||
|
|
@ -233,7 +245,12 @@ protected:
|
|||
return m_flags;
|
||||
}
|
||||
|
||||
unsigned int cv_index () const
|
||||
const lay::TextInfo *text_info () const
|
||||
{
|
||||
return mp_text_info;
|
||||
}
|
||||
|
||||
unsigned int cv_index () const
|
||||
{
|
||||
return m_cv_index;
|
||||
}
|
||||
|
|
@ -261,7 +278,8 @@ protected:
|
|||
void checkpoint ();
|
||||
|
||||
private:
|
||||
virtual void visit_cell (const db::Cell &cell, const db::Box &search_box, const db::ICplxTrans &t, int /*level*/);
|
||||
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 std::set<db::properties_id_type> *prop_sel,
|
||||
|
|
@ -276,6 +294,7 @@ private:
|
|||
db::ShapeIterator::flags_type m_flags;
|
||||
unsigned int m_cv_index;
|
||||
db::cell_index_type m_topcell;
|
||||
const lay::TextInfo *mp_text_info;
|
||||
const std::set<db::properties_id_type> *mp_prop_sel;
|
||||
bool m_inv_prop_sel;
|
||||
int m_tries;
|
||||
|
|
@ -314,7 +333,8 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
virtual void visit_cell (const db::Cell &cell, const db::Box &search_box, const db::ICplxTrans &t, int level);
|
||||
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);
|
||||
|
||||
unsigned int m_cv_index;
|
||||
|
|
|
|||
|
|
@ -29,28 +29,26 @@
|
|||
namespace lay
|
||||
{
|
||||
|
||||
TextInfo::TextInfo (const LayoutViewBase *view, const db::DCplxTrans &vp_trans)
|
||||
TextInfo::TextInfo (const LayoutViewBase *view)
|
||||
: m_default_text_size (view->default_text_size ()),
|
||||
m_default_font (db::Font (view->text_font ())),
|
||||
m_apply_text_trans (view->apply_text_trans ()),
|
||||
m_resolution (view->canvas ()->resolution ()),
|
||||
m_vp_trans (vp_trans)
|
||||
m_resolution (view->canvas ()->resolution ())
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
TextInfo::TextInfo (double default_text_size, const db::Font &default_font, bool apply_text_trans, double resolution, const db::DCplxTrans &vp_trans)
|
||||
TextInfo::TextInfo (double default_text_size, const db::Font &default_font, bool apply_text_trans, double resolution)
|
||||
: m_default_text_size (default_text_size),
|
||||
m_default_font (default_font),
|
||||
m_apply_text_trans (apply_text_trans),
|
||||
m_resolution (resolution),
|
||||
m_vp_trans (vp_trans)
|
||||
m_resolution (resolution)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
db::DBox
|
||||
TextInfo::get_bbox (const db::DText &text) const
|
||||
TextInfo::bbox (const db::DText &text, const db::DCplxTrans &vp_trans) const
|
||||
{
|
||||
// offset in pixels (space between origin and text)
|
||||
const double offset = 2.0;
|
||||
|
|
@ -60,10 +58,10 @@ TextInfo::get_bbox (const db::DText &text) const
|
|||
db::Font font = text.font () == db::NoFont ? m_default_font : text.font ();
|
||||
|
||||
if (m_apply_text_trans && font != db::NoFont && font != db::DefaultFont) {
|
||||
fp = db::DFTrans (m_vp_trans.fp_trans () * text.trans ().fp_trans ());
|
||||
h = m_vp_trans.ctrans (text.size () > 0 ? text.size () : m_default_text_size);
|
||||
fp = db::DFTrans (vp_trans.fp_trans () * text.trans ().fp_trans ());
|
||||
h = vp_trans.ctrans (text.size () > 0 ? text.size () : m_default_text_size);
|
||||
} else {
|
||||
h = m_vp_trans.ctrans (m_default_text_size);
|
||||
h = vp_trans.ctrans (m_default_text_size);
|
||||
}
|
||||
|
||||
db::HAlign halign = text.halign ();
|
||||
|
|
@ -156,12 +154,12 @@ TextInfo::get_bbox (const db::DText &text) const
|
|||
|
||||
}
|
||||
|
||||
return db::DBox (xleft, ybottom, xright, ytop).transformed (m_vp_trans.inverted ());
|
||||
return db::DBox (xleft, ybottom, xright, ytop).transformed (vp_trans.inverted ());
|
||||
|
||||
} else {
|
||||
|
||||
db::DHershey ht (text.string (), font);
|
||||
ht.justify (b.transformed (m_vp_trans.inverted ()), halign, valign);
|
||||
ht.justify (b.transformed (vp_trans.inverted ()), halign, valign);
|
||||
return ht.bbox ();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,9 +46,8 @@ public:
|
|||
* @brief Constructor
|
||||
*
|
||||
* @param view The LayoutView from which to take the text display parameters
|
||||
* @param vp_trans The effective micron-to-pixel transformation
|
||||
*/
|
||||
TextInfo (const LayoutViewBase *view, const db::DCplxTrans &vp_trans);
|
||||
TextInfo (const LayoutViewBase *view);
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
|
|
@ -59,7 +58,7 @@ public:
|
|||
* @param resolution The resolution value (logical pixel size per physical unit pixel)
|
||||
* @param vp_trans The effective micron-to-pixel transformation
|
||||
*/
|
||||
TextInfo (double default_text_size, const db::Font &default_font, bool apply_text_trans, double resolution, const db::DCplxTrans &vp_trans);
|
||||
TextInfo (double default_text_size, const db::Font &default_font, bool apply_text_trans, double resolution);
|
||||
|
||||
/**
|
||||
* @brief Gets the visual bounding box of the given DText object
|
||||
|
|
@ -67,11 +66,11 @@ public:
|
|||
* The visual bounding box is returned in micrometer units.
|
||||
* It encloses the glyphs of the text, taking into account the
|
||||
* text view settings by the view.
|
||||
*
|
||||
* @param text The text object
|
||||
* @param vp_trans The effective micron-to-pixel transformation
|
||||
*/
|
||||
db::DBox operator() (const db::DText &text) const
|
||||
{
|
||||
return get_bbox (text);
|
||||
}
|
||||
db::DBox bbox (const db::DText &text, const db::DCplxTrans &vp_trans) const;
|
||||
|
||||
private:
|
||||
double m_default_text_size;
|
||||
|
|
@ -79,8 +78,6 @@ private:
|
|||
bool m_apply_text_trans;
|
||||
double m_resolution;
|
||||
db::DCplxTrans m_vp_trans;
|
||||
|
||||
db::DBox get_bbox (const db::DText &text) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue