From a22f48d87ad266e5810d6c9212e7edd5628471af Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 23 Mar 2025 15:54:18 +0100 Subject: [PATCH] Texts#polygons now has an argument to specify a property key that receives the text string --- src/db/db/dbAsIfFlatTexts.cc | 22 ++++++++++++++++++++-- src/db/db/dbAsIfFlatTexts.h | 2 +- src/db/db/dbDeepTexts.cc | 22 ++++++++++++++++++++-- src/db/db/dbDeepTexts.h | 2 +- src/db/db/dbEmptyTexts.cc | 2 +- src/db/db/dbEmptyTexts.h | 2 +- src/db/db/dbTexts.cc | 4 ++-- src/db/db/dbTexts.h | 2 +- src/db/db/dbTextsDelegate.h | 2 +- src/db/db/gsiDeclDbTexts.cc | 12 ++++++++---- src/db/unit_tests/dbTextsTests.cc | 31 +++++++++++++++++++++++++++++++ testdata/ruby/dbTextsTest.rb | 13 +++++++++++++ 12 files changed, 100 insertions(+), 16 deletions(-) diff --git a/src/db/db/dbAsIfFlatTexts.cc b/src/db/db/dbAsIfFlatTexts.cc index 6b7f887e9..a9e8c0e91 100644 --- a/src/db/db/dbAsIfFlatTexts.cc +++ b/src/db/db/dbAsIfFlatTexts.cc @@ -233,14 +233,32 @@ AsIfFlatTexts::processed_to_polygons (const TextToPolygonProcessorBase &filter) } RegionDelegate * -AsIfFlatTexts::polygons (db::Coord e) const +AsIfFlatTexts::polygons (db::Coord e, const tl::Variant &text_prop) const { + db::property_names_id_type key_id = 0; + if (! text_prop.is_nil ()) { + key_id = db::property_names_id (text_prop); + } + + std::map value_ids; + std::unique_ptr output (new FlatRegion ()); for (TextsIterator tp (begin ()); ! tp.at_end (); ++tp) { db::Box box = tp->box (); box.enlarge (db::Vector (e, e)); - output->insert (db::Polygon (box)); + if (key_id == 0) { + output->insert (db::Polygon (box)); + } else { + std::string value (tp->string ()); + auto v = value_ids.find (value); + if (v == value_ids.end ()) { + db::PropertiesSet ps; + ps.insert_by_id (key_id, db::property_values_id (value)); + v = value_ids.insert (std::make_pair (value, db::properties_id (ps))).first; + } + output->insert (db::PolygonWithProperties (db::Polygon (box), v->second)); + } } return output.release (); diff --git a/src/db/db/dbAsIfFlatTexts.h b/src/db/db/dbAsIfFlatTexts.h index 79591cf33..bd255399c 100644 --- a/src/db/db/dbAsIfFlatTexts.h +++ b/src/db/db/dbAsIfFlatTexts.h @@ -71,7 +71,7 @@ public: virtual TextsDelegate *add (const Texts &other) const; - virtual RegionDelegate *polygons (db::Coord e) const; + virtual RegionDelegate *polygons (db::Coord e, const tl::Variant &text_prop) const; virtual EdgesDelegate *edges () const; virtual TextsDelegate *in (const Texts &, bool) const; diff --git a/src/db/db/dbDeepTexts.cc b/src/db/db/dbDeepTexts.cc index 107a3f6ed..e272e25ca 100644 --- a/src/db/db/dbDeepTexts.cc +++ b/src/db/db/dbDeepTexts.cc @@ -528,8 +528,15 @@ DeepTexts::processed_to_polygons (const TextToPolygonProcessorBase &filter) cons return shape_collection_processed_impl (deep_layer (), filter); } -RegionDelegate *DeepTexts::polygons (db::Coord e) const +RegionDelegate *DeepTexts::polygons (db::Coord e, const tl::Variant &text_prop) const { + db::property_names_id_type key_id = 0; + if (! text_prop.is_nil ()) { + key_id = db::property_names_id (text_prop); + } + + std::map value_ids; + db::DeepLayer new_layer = deep_layer ().derived (); db::Layout &layout = const_cast (deep_layer ().layout ()); @@ -539,7 +546,18 @@ RegionDelegate *DeepTexts::polygons (db::Coord e) const db::Box box = s->bbox (); box.enlarge (db::Vector (e, e)); db::Polygon poly (box); - output.insert (db::PolygonRef (poly, layout.shape_repository ())); + if (key_id == 0) { + output.insert (db::PolygonRef (poly, layout.shape_repository ())); + } else { + std::string value (s->text_string ()); + auto v = value_ids.find (value); + if (v == value_ids.end ()) { + db::PropertiesSet ps; + ps.insert_by_id (key_id, db::property_values_id (value)); + v = value_ids.insert (std::make_pair (value, db::properties_id (ps))).first; + } + output.insert (db::PolygonRefWithProperties (db::PolygonRef (poly, layout.shape_repository ()), v->second)); + } } } diff --git a/src/db/db/dbDeepTexts.h b/src/db/db/dbDeepTexts.h index 2f2b37aff..7425df7cd 100644 --- a/src/db/db/dbDeepTexts.h +++ b/src/db/db/dbDeepTexts.h @@ -86,7 +86,7 @@ public: virtual TextsDelegate *add_in_place (const Texts &other); virtual TextsDelegate *add (const Texts &other) const; - virtual RegionDelegate *polygons (db::Coord e) const; + virtual RegionDelegate *polygons (db::Coord e, const tl::Variant &text_prop) const; virtual EdgesDelegate *edges () const; virtual TextsDelegate *in (const Texts &, bool) const; diff --git a/src/db/db/dbEmptyTexts.cc b/src/db/db/dbEmptyTexts.cc index 4e4a80b60..2a22100d5 100644 --- a/src/db/db/dbEmptyTexts.cc +++ b/src/db/db/dbEmptyTexts.cc @@ -49,7 +49,7 @@ EmptyTexts::clone () const } RegionDelegate * -EmptyTexts::polygons (db::Coord) const +EmptyTexts::polygons (db::Coord, const tl::Variant &) const { return new EmptyRegion (); } diff --git a/src/db/db/dbEmptyTexts.h b/src/db/db/dbEmptyTexts.h index 2b7b6cc8e..37cdd6725 100644 --- a/src/db/db/dbEmptyTexts.h +++ b/src/db/db/dbEmptyTexts.h @@ -62,7 +62,7 @@ public: virtual TextsDelegate *processed (const TextProcessorBase &) const { return new EmptyTexts (); } virtual RegionDelegate *processed_to_polygons (const TextToPolygonProcessorBase &) const; - virtual RegionDelegate *polygons (db::Coord e) const; + virtual RegionDelegate *polygons (db::Coord e, const tl::Variant &text_prop) const; virtual EdgesDelegate *edges () const; virtual TextsDelegate *add_in_place (const Texts &other); diff --git a/src/db/db/dbTexts.cc b/src/db/db/dbTexts.cc index 37af51e35..9e071fb1a 100644 --- a/src/db/db/dbTexts.cc +++ b/src/db/db/dbTexts.cc @@ -177,9 +177,9 @@ Texts::iter () const return *(i ? i : &def_iter); } -void Texts::polygons (Region &output, db::Coord e) const +void Texts::polygons (Region &output, db::Coord e, const tl::Variant &text_prop) const { - output.set_delegate (mp_delegate->polygons (e)); + output.set_delegate (mp_delegate->polygons (e, text_prop)); } void Texts::edges (Edges &output) const diff --git a/src/db/db/dbTexts.h b/src/db/db/dbTexts.h index 87b471804..a948f3366 100644 --- a/src/db/db/dbTexts.h +++ b/src/db/db/dbTexts.h @@ -590,7 +590,7 @@ public: * The given extension is applied in all directions rendering a square of 2*e * width and height. The center of the boxes will be the position of the texts. */ - void polygons (Region &output, db::Coord e = 1) const; + void polygons (Region &output, db::Coord e = 1, const tl::Variant &text_prop = tl::Variant ()) const; /** * @brief Returns individual, dot-like edges diff --git a/src/db/db/dbTextsDelegate.h b/src/db/db/dbTextsDelegate.h index 0376c69cc..4808e9679 100644 --- a/src/db/db/dbTextsDelegate.h +++ b/src/db/db/dbTextsDelegate.h @@ -100,7 +100,7 @@ public: virtual TextsDelegate *processed (const TextProcessorBase &proc) const = 0; virtual RegionDelegate *processed_to_polygons (const TextToPolygonProcessorBase &proc) const = 0; - virtual RegionDelegate *polygons (db::Coord e) const = 0; + virtual RegionDelegate *polygons (db::Coord e, const tl::Variant &text_prop) const = 0; virtual EdgesDelegate *edges () const = 0; virtual TextsDelegate *add_in_place (const Texts &other) = 0; diff --git a/src/db/db/gsiDeclDbTexts.cc b/src/db/db/gsiDeclDbTexts.cc index 099fa65aa..66e1d34a6 100644 --- a/src/db/db/gsiDeclDbTexts.cc +++ b/src/db/db/gsiDeclDbTexts.cc @@ -349,10 +349,10 @@ static db::Texts moved_xy (const db::Texts *r, db::Coord x, db::Coord y) return r->transformed (db::Disp (db::Vector (x, y))); } -static db::Region polygons0 (const db::Texts *e, db::Coord d) +static db::Region polygons0 (const db::Texts *e, db::Coord d, const tl::Variant &text_prop) { db::Region r; - e->polygons (r, d); + e->polygons (r, d, text_prop); return r; } @@ -710,9 +710,13 @@ Class decl_Texts (decl_dbShapeCollection, "db", "Texts", "@brief Returns a region with the enlarged bounding boxes of the texts\n" "This method acts like the other version of \\extents, but allows giving different enlargements for x and y direction.\n" ) + - method_ext ("polygons", &polygons0, gsi::arg ("e", db::Coord (1)), + method_ext ("polygons", &polygons0, gsi::arg ("e", db::Coord (1)), gsi::arg ("text_prop", tl::Variant (), "nil"), "@brief Converts the edge pairs to polygons\n" - "This method creates polygons from the texts. This is equivalent to calling \\extents." + "This method creates polygons from the texts. This is basically equivalent to calling \\extents. " + "In addition, a user property with the key given by 'text_prop' can be attached. The value of that " + "user property will be the text string. If 'text_prop' is nil, no user property is attached.\n" + "\n" + "The 'text_prop' argument has been added in version 0.30." ) + method_ext ("filter", &filter, gsi::arg ("filter"), "@brief Applies a generic filter in place (replacing the texts from the Texts collection)\n" diff --git a/src/db/unit_tests/dbTextsTests.cc b/src/db/unit_tests/dbTextsTests.cc index 5bddc26fc..2fc3e652b 100644 --- a/src/db/unit_tests/dbTextsTests.cc +++ b/src/db/unit_tests/dbTextsTests.cc @@ -276,3 +276,34 @@ TEST(8_add_with_properties) EXPECT_EQ (r.to_string (), "('uvw',r0 -10,20){net=>17};('abc',r0 10,20){net=>17}"); EXPECT_EQ ((ro1 + rf2).to_string (), "('uvw',r0 -10,20){net=>17};('abc',r0 10,20){net=>17}"); } + +TEST(9_polygons) +{ + db::DeepShapeStore dss ("TOP", 0.001); + db::Texts rf; + db::Texts rd (dss); + + rf.insert (db::Text ("ABC", db::Trans (db::Vector (10, 20)))); + rf.insert (db::Text ("XZY", db::Trans (db::Vector (-10, -20)))); + + rd.insert (db::Text ("ABC", db::Trans (db::Vector (10, 20)))); + rd.insert (db::Text ("XZY", db::Trans (db::Vector (-10, -20)))); + + db::Region r; + + rf.polygons (r, 1); + EXPECT_EQ (r.to_string (), "(9,19;9,21;11,21;11,19);(-11,-21;-11,-19;-9,-19;-9,-21)"); + + rf.polygons (r, 2); + EXPECT_EQ (r.to_string (), "(8,18;8,22;12,22;12,18);(-12,-22;-12,-18;-8,-18;-8,-22)"); + + rd.polygons (r, 1); + EXPECT_EQ (r.to_string (), "(9,19;9,21;11,21;11,19);(-11,-21;-11,-19;-9,-19;-9,-21)"); + + rf.polygons (r, 1, tl::Variant (17)); + EXPECT_EQ (r.to_string (), "(9,19;9,21;11,21;11,19){17=>ABC};(-11,-21;-11,-19;-9,-19;-9,-21){17=>XZY}"); + + rd.polygons (r, 1, tl::Variant (17)); + EXPECT_EQ (r.to_string (), "(9,19;9,21;11,21;11,19){17=>ABC};(-11,-21;-11,-19;-9,-19;-9,-21){17=>XZY}"); +} + diff --git a/testdata/ruby/dbTextsTest.rb b/testdata/ruby/dbTextsTest.rb index c4e7351ca..145379068 100644 --- a/testdata/ruby/dbTextsTest.rb +++ b/testdata/ruby/dbTextsTest.rb @@ -529,6 +529,19 @@ class DBTexts_TestClass < TestBase end + # polygons + def test_polygons + + r = RBA::Texts::new + r.insert(RBA::Text::new("abc", RBA::Trans::new(10, 20))) + r.insert(RBA::Text::new("uvw", RBA::Trans::new(-10, -20))) + + assert_equal(r.polygons.to_s, "(9,19;9,21;11,21;11,19);(-11,-21;-11,-19;-9,-19;-9,-21)") + assert_equal(r.polygons(2).to_s, "(8,18;8,22;12,22;12,18);(-12,-22;-12,-18;-8,-18;-8,-22)") + assert_equal(r.polygons(1, 17).to_s, "(9,19;9,21;11,21;11,19){17=>abc};(-11,-21;-11,-19;-9,-19;-9,-21){17=>uvw}") + + end + end