Bugfix, text reference made the program assert

This commit is contained in:
Matthias Koefferlein 2023-05-11 18:57:24 +02:00
parent c45d1d70d4
commit 1422dfb93d
7 changed files with 112 additions and 43 deletions

View File

@ -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<db::DPoint> &linestarts)
hershey_justify (const std::string &s, unsigned int f, db::DBox bx, HAlign halign, VAlign valign, std::vector<db::DPoint> &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 ());
}
}
}

View File

@ -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<db::DPoint> &linestarts);
DB_PUBLIC void hershey_justify (const std::string &s, unsigned int f, db::DBox bx, HAlign halign, VAlign valign, std::vector<db::DPoint> &linestarts, double &left, double &bottom);
DB_PUBLIC std::vector<std::string> 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 <db::DPoint> m_linestarts;
double m_left, m_bottom;
};
/**

View File

@ -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 ();

View File

@ -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

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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)");
}