diff --git a/src/db/db/dbHershey.cc b/src/db/db/dbHershey.cc index 41e0726d3..7e862d4a2 100644 --- a/src/db/db/dbHershey.cc +++ b/src/db/db/dbHershey.cc @@ -177,12 +177,15 @@ hershey_text_box (const std::string &s, unsigned int f) } hl += h; - return db::DBox (0, 0, wl, hl); + return db::DBox (0, fp->ymin, wl, hl); } void -hershey_justify (const std::string &s, unsigned int f, db::DBox bx, HAlign halign, VAlign valign, std::vector &linestarts) +hershey_justify (const std::string &s, unsigned int f, db::DBox bx, HAlign halign, VAlign valign, std::vector &linestarts, double &left, double &bottom) { + left = 0.0; + bottom = 0.0; + HersheyFont *fp = fonts [f]; int hl = 0; @@ -234,6 +237,13 @@ hershey_justify (const std::string &s, unsigned int f, db::DBox bx, HAlign halig p += db::DVector (0, l->y ()); } *l = p; + if (l == linestarts.begin ()) { + left = l->x (); + bottom = l->y (); + } else { + left = std::min (left, l->x ()); + bottom = std::min (bottom, l->y ()); + } } } diff --git a/src/db/db/dbHershey.h b/src/db/db/dbHershey.h index b5b60d0f3..2c446a7cd 100644 --- a/src/db/db/dbHershey.h +++ b/src/db/db/dbHershey.h @@ -38,7 +38,7 @@ struct HersheyFont; DB_PUBLIC int hershey_font_width (unsigned int f); DB_PUBLIC int hershey_font_height (unsigned int f); DB_PUBLIC db::DBox hershey_text_box (const std::string &s, unsigned int f); -DB_PUBLIC void hershey_justify (const std::string &s, unsigned int f, db::DBox bx, HAlign halign, VAlign valign, std::vector &linestarts); +DB_PUBLIC void hershey_justify (const std::string &s, unsigned int f, db::DBox bx, HAlign halign, VAlign valign, std::vector &linestarts, double &left, double &bottom); DB_PUBLIC std::vector hershey_font_names (); DB_PUBLIC size_t hershey_count_edges (const std::string &s, unsigned int f); @@ -137,7 +137,8 @@ struct DB_PUBLIC_TEMPLATE hershey hershey () : m_string (), m_font (DefaultFont), - m_scale (1.0) + m_scale (1.0), + m_left (0.0), m_bottom (0.0) { // .. nothing yet .. } @@ -150,7 +151,8 @@ struct DB_PUBLIC_TEMPLATE hershey hershey (const std::string &s, Font f) : m_string (s), m_font (f), - m_scale (1.0) + m_scale (1.0), + m_left (0.0), m_bottom (0.0) { // .. nothing yet .. } @@ -181,9 +183,7 @@ struct DB_PUBLIC_TEMPLATE hershey db::DBox bbox () const { db::DBox b = hershey_text_box (m_string, m_font); - if (! m_linestarts.empty ()) { - b.move (m_linestarts.back () - db::DPoint ()); - } + b.move (db::DVector (m_left, m_bottom)); return b * m_scale; } @@ -220,7 +220,7 @@ struct DB_PUBLIC_TEMPLATE hershey db::DPoint p1 (b.p1 ().x () / m_scale, b.p1 ().y () / m_scale); db::DPoint p2 (b.p2 ().x () / m_scale, b.p2 ().y () / m_scale); - hershey_justify (m_string, m_font, db::DBox (p1, p2), halign, valign, m_linestarts); + hershey_justify (m_string, m_font, db::DBox (p1, p2), halign, valign, m_linestarts, m_left, m_bottom); } else { @@ -245,7 +245,7 @@ struct DB_PUBLIC_TEMPLATE hershey if (m_scale > 1e-6) { db::DPoint p1 (b.p1 ().x () / m_scale, b.p1 ().y () / m_scale); db::DPoint p2 (b.p2 ().x () / m_scale, b.p2 ().y () / m_scale); - hershey_justify (m_string, m_font, db::DBox (p1, p2), halign, valign, m_linestarts); + hershey_justify (m_string, m_font, db::DBox (p1, p2), halign, valign, m_linestarts, m_left, m_bottom); } } @@ -294,6 +294,7 @@ private: Font m_font; double m_scale; std::vector m_linestarts; + double m_left, m_bottom; }; /** diff --git a/src/edt/edt/edtPartialService.cc b/src/edt/edt/edtPartialService.cc index 8e69a836e..8950458f0 100644 --- a/src/edt/edt/edtPartialService.cc +++ b/src/edt/edt/edtPartialService.cc @@ -856,7 +856,9 @@ PartialShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, co 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); + db::Text text; + shape->text (text); + db::Box tb = t_dbu.inverted () * text_info ()->bbox (t_dbu * text, vp); if (tb.inside (hit_box)) { edges.push_back (EdgeWithIndex (db::Edge (tp, tp), 0, 0, 0)); } @@ -1000,7 +1002,9 @@ PartialShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, co 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)); + db::Text text; + shape->text (text); + db::Box tb (t_dbu.inverted () * text_info ()->bbox (t_dbu * text, vp)); if (tb.contains (hit_box.center ())) { d = tp.distance (hit_box.center ()); edge_sel.clear (); diff --git a/src/laybasic/laybasic/layFinder.cc b/src/laybasic/laybasic/layFinder.cc index ba12f5c72..acb79f9f5 100644 --- a/src/laybasic/laybasic/layFinder.cc +++ b/src/laybasic/laybasic/layFinder.cc @@ -384,13 +384,6 @@ ShapeFinder::find_internal (lay::LayoutViewBase *view, unsigned int cv_index, co m_topcell = cv.cell_index (); - db::DBox scan_region_mu = region_mu; - if (mp_text_info) { - // for catching all labels we search the whole view area - // @@@ multiple passes - with and without texts (with texts with big area) - scan_region_mu = view->viewport ().box (); - } - mp_prop_sel = prop_sel; m_inv_prop_sel = inv_prop_sel; @@ -405,13 +398,34 @@ ShapeFinder::find_internal (lay::LayoutViewBase *view, unsigned int cv_index, co max_level = hier_sel.to_level (ctx_path_length, max_level); } - // actually find + auto flags_saved = m_flags; + try { - start (view, m_cv_index, trans_mu, region_mu, scan_region_mu, min_level, max_level, layers); + + if ((m_flags & db::ShapeIterator::Texts) != 0 && mp_text_info) { + + m_flags = db::ShapeIterator::Texts; + + // for catching all labels we search the whole view area + db::DBox scan_region_mu = view->viewport ().box (); + start (view, m_cv_index, trans_mu, region_mu, scan_region_mu, min_level, max_level, layers); + + m_flags = db::ShapeIterator::flags_type (flags_saved - db::ShapeIterator::Texts); + + } + + // another pass with tight search box and without texts + start (view, m_cv_index, trans_mu, region_mu, region_mu, min_level, max_level, layers); + } catch (StopException) { - // .. + // ... + } catch (...) { + m_flags = flags_saved; + throw; } + m_flags = flags_saved; + // return true if anything was found return ! m_founds.empty (); } @@ -471,7 +485,9 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db: 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); + db::Text text; + shape->text (text); + bbox = t_dbu.inverted () * text_info ()->bbox (t_dbu * text, vp); } else { bbox = shape->bbox (); } @@ -565,7 +581,9 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db: 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); + db::Text text; + shape->text (text); + box = t_dbu.inverted () * text_info ()->bbox (t_dbu * text, vp); } // point-like boxes are handles which attract the finder diff --git a/src/laybasic/laybasic/layMarker.cc b/src/laybasic/laybasic/layMarker.cc index a7a8bb1c0..16d0ca19b 100644 --- a/src/laybasic/laybasic/layMarker.cc +++ b/src/laybasic/laybasic/layMarker.cc @@ -36,6 +36,13 @@ namespace lay { +static db::DVector text_box_enlargement (const db::DCplxTrans &vp_trans) +{ + // 4.0 is the text box border in pixels + double b = 4.0 / vp_trans.mag (); + return db::DVector (b, b); +} + // ------------------------------------------------------------------------ void render_cell_inst (const db::Layout &layout, const db::CellInstArray &inst, const db::CplxTrans &trans, lay::Renderer &r, @@ -630,7 +637,9 @@ ShapeMarker::render (const Viewport &vp, ViewObjectCanvas &canvas) // draw a frame around the text lay::TextInfo ti (view ()); db::DCplxTrans vp_trans = vp.trans () * *tr; - db::DBox box = ti.bbox (trans () * m_shape.text (), vp_trans).enlarged (db::DVector (2.0 / vp_trans.mag (), 2.0 / vp_trans.mag ())); + db::Text t; + m_shape.text (t); + db::DBox box = ti.bbox (trans () * t, vp_trans).enlarged (text_box_enlargement (vp_trans)); r.draw (box, vp_trans, 0, text, 0, 0); } r.draw (m_shape, t, fill, contour, vertex, text); @@ -641,7 +650,9 @@ ShapeMarker::render (const Viewport &vp, ViewObjectCanvas &canvas) if (m_shape.is_text () && text) { // draw a frame around the text lay::TextInfo ti (view ()); - db::DBox box = ti.bbox (trans () * m_shape.text (), vp.trans ()).enlarged (db::DVector (2.0 / vp.trans ().mag (), 2.0 / vp.trans ().mag ())); + db::Text t; + m_shape.text (t); + db::DBox box = ti.bbox (trans () * t, vp.trans ()).enlarged (text_box_enlargement (vp.trans ())); r.draw (box, vp.trans (), 0, text, 0, 0); } r.draw (m_shape, t, fill, contour, vertex, text); @@ -1101,8 +1112,9 @@ Marker::draw (lay::Renderer &r, const db::CplxTrans &t, lay::CanvasPlane *fill, if (view () && text) { // draw a frame around the text lay::TextInfo ti (view ()); - db::DBox box = ti.bbox (*m_object.dtext, db::DCplxTrans (t)).enlarged (db::DVector (2.0 / t.mag (), 2.0 / t.mag ())); - r.draw (box, db::DCplxTrans (t), 0, text, 0, 0); + db::DCplxTrans dt (t); + db::DBox box = ti.bbox (*m_object.dtext, dt).enlarged (text_box_enlargement (dt)); + r.draw (box, dt, 0, text, 0, 0); } r.draw (*m_object.dtext, db::DCplxTrans (t), fill, contour, vertex, text); } else if (m_type == Edge) { @@ -1303,7 +1315,7 @@ DMarker::render (const Viewport &vp, ViewObjectCanvas &canvas) if (view () && text) { // draw a frame around the text lay::TextInfo ti (view ()); - db::DBox box = ti.bbox (*m_object.text, t).enlarged (db::DVector (2.0 / t.mag (), 2.0 / t.mag ())); + db::DBox box = ti.bbox (*m_object.text, t).enlarged (text_box_enlargement (t)); r.draw (box, t, 0, text, 0, 0); } r.draw (*m_object.text, t, fill, contour, vertex, text); diff --git a/src/laybasic/laybasic/layTextInfo.cc b/src/laybasic/laybasic/layTextInfo.cc index f123d5fd1..4f7402a73 100644 --- a/src/laybasic/laybasic/layTextInfo.cc +++ b/src/laybasic/laybasic/layTextInfo.cc @@ -53,14 +53,14 @@ 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; - db::DFTrans fp (db::DFTrans::r0); + db::DTrans tt = text.trans (); db::DCoord h; 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 (vp_trans.fp_trans () * text.trans ().fp_trans ()); h = vp_trans.ctrans (text.size () > 0 ? text.size () : m_default_text_size); } else { + tt = db::DTrans (tt.disp ()); h = vp_trans.ctrans (m_default_text_size); } @@ -83,9 +83,9 @@ TextInfo::bbox (const db::DText &text, const db::DCplxTrans &vp_trans) const db::DVector tp1 (fx * offset, fy * offset + (fy - 1) * 0.5 * h); db::DVector tp2 (fx * offset, fy * offset + (fy + 1) * 0.5 * h); - db::DPoint dp = vp_trans * (db::DPoint () + text.trans ().disp ()); + db::DPoint dp = vp_trans * db::DPoint (); - db::DBox b (dp + fp (tp1), dp + fp (tp2)); + db::DBox b (dp + tp1, dp + tp2); if (font == db::DefaultFont) { @@ -154,13 +154,13 @@ TextInfo::bbox (const db::DText &text, const db::DCplxTrans &vp_trans) const } - return db::DBox (xleft, ybottom, xright, ytop).transformed (vp_trans.inverted ()); + return db::DBox (xleft, ybottom, xright, ytop).transformed (vp_trans.inverted ()).transformed (tt); } else { db::DHershey ht (text.string (), font); ht.justify (b.transformed (vp_trans.inverted ()), halign, valign); - return ht.bbox (); + return ht.bbox ().transformed (tt); } } diff --git a/src/laybasic/unit_tests/layTextInfoTests.cc b/src/laybasic/unit_tests/layTextInfoTests.cc index 3b3259360..0888f9203 100644 --- a/src/laybasic/unit_tests/layTextInfoTests.cc +++ b/src/laybasic/unit_tests/layTextInfoTests.cc @@ -44,46 +44,70 @@ TEST(1) db::DText text3; + // Default font lay::TextInfo ti (&lv); EXPECT_EQ (ti.bbox (text, db::DCplxTrans ()).to_string (), "(12,22;36,37)"); EXPECT_EQ (ti.bbox (text, db::DCplxTrans (2.0)).to_string (), "(11,21;23,28.5)"); EXPECT_EQ (ti.bbox (text2, db::DCplxTrans ()).to_string (), "(12,22;60,52)"); + // valign text3 = text2; text3.valign (db::VAlignCenter); EXPECT_EQ (ti.bbox (text3, db::DCplxTrans ()).to_string (), "(12,5;60,35)"); text3.valign (db::VAlignTop); EXPECT_EQ (ti.bbox (text3, db::DCplxTrans ()).to_string (), "(12,-12;60,18)"); + // halign text3 = text2; text3.halign (db::HAlignCenter); EXPECT_EQ (ti.bbox (text3, db::DCplxTrans ()).to_string (), "(-14,22;34,52)"); text3.halign (db::HAlignRight); EXPECT_EQ (ti.bbox (text3, db::DCplxTrans ()).to_string (), "(-40,22;8,52)"); + // Herschey font lv.text_font (db::Font::StickFont); ti = lay::TextInfo (&lv); - EXPECT_EQ (ti.bbox (text, db::DCplxTrans ()).to_string (), "(12,22;72,47)"); - EXPECT_EQ (ti.bbox (text2, db::DCplxTrans ()).to_string (), "(12,22;134,83)"); + EXPECT_EQ (ti.bbox (text, db::DCplxTrans ()).to_string (), "(12,15;72,47)"); + EXPECT_EQ (ti.bbox (text2, db::DCplxTrans ()).to_string (), "(12,15;134,83)"); + // valign text3 = text2; text3.valign (db::VAlignCenter); - EXPECT_EQ (ti.bbox (text3, db::DCplxTrans ()).to_string (), "(12,-10.5;134,50.5)"); + EXPECT_EQ (ti.bbox (text3, db::DCplxTrans ()).to_string (), "(12,-17.5;134,50.5)"); text3.valign (db::VAlignTop); - EXPECT_EQ (ti.bbox (text3, db::DCplxTrans ()).to_string (), "(12,-43;134,18)"); + EXPECT_EQ (ti.bbox (text3, db::DCplxTrans ()).to_string (), "(12,-50;134,18)"); + // halign text3 = text2; text3.halign (db::HAlignCenter); - EXPECT_EQ (ti.bbox (text3, db::DCplxTrans ()).to_string (), "(-51,22;71,83)"); + EXPECT_EQ (ti.bbox (text3, db::DCplxTrans ()).to_string (), "(-51,15;71,83)"); text3.halign (db::HAlignRight); - EXPECT_EQ (ti.bbox (text3, db::DCplxTrans ()).to_string (), "(-114,22;8,83)"); + EXPECT_EQ (ti.bbox (text3, db::DCplxTrans ()).to_string (), "(-114,15;8,83)"); + // smaller size as default lv.default_text_size (4.2); ti = lay::TextInfo (&lv); - EXPECT_EQ (ti.bbox (text, db::DCplxTrans ()).to_string (), "(12,22;24,27)"); - EXPECT_EQ (ti.bbox (text2, db::DCplxTrans ()).to_string (), "(12,22;36.4,34.2)"); + EXPECT_EQ (ti.bbox (text, db::DCplxTrans ()).to_string (), "(12,20.6;24,27)"); + EXPECT_EQ (ti.bbox (text2, db::DCplxTrans ()).to_string (), "(12,20.6;36.4,34.2)"); + // text with explicit size + text3 = text2; + text3.size (21); + EXPECT_EQ (ti.bbox (text3, db::DCplxTrans ()).to_string (), "(12,15;134,83)"); + // text with rotation + text3.trans (db::DTrans (1, db::DVector (10.0, 20.0))); + EXPECT_EQ (ti.bbox (text3, db::DCplxTrans ()).to_string (), "(-53,22;15,144)"); + + // text with rotation and default font (-> rotation ignored) + text3.font (db::Font::DefaultFont); + EXPECT_EQ (ti.bbox (text3, db::DCplxTrans ()).to_string (), "(12,22;60,52)"); + text3.font (db::Font::StickFont); + + // apply_text_trans = false + lv.apply_text_trans (false); + ti = lay::TextInfo (&lv); + EXPECT_EQ (ti.bbox (text3, db::DCplxTrans ()).to_string (), "(12,20.6;36.4,34.2)"); }