mirror of https://github.com/KLayout/klayout.git
First implementation of texts collection.
This commit is contained in:
parent
3f8090b3fd
commit
a9cd9ac122
|
|
@ -184,7 +184,16 @@ SOURCES = \
|
|||
dbLayoutVsSchematic.cc \
|
||||
gsiDeclDbNetlistCrossReference.cc \
|
||||
gsiDeclDbLayoutVsSchematic.cc \
|
||||
dbNetlistObject.cc
|
||||
dbNetlistObject.cc \
|
||||
gsiDeclDbTexts.cc \
|
||||
dbTexts.cc \
|
||||
dbDeepTexts.cc \
|
||||
dbAsIfFlatTexts.cc \
|
||||
dbTextsDelegate.cc \
|
||||
dbEmptyTexts.cc \
|
||||
dbFlatTexts.cc \
|
||||
dbTextsUtils.cc \
|
||||
dbOriginalLayerTexts.cc
|
||||
|
||||
HEADERS = \
|
||||
dbArray.h \
|
||||
|
|
@ -331,7 +340,15 @@ HEADERS = \
|
|||
dbLayoutVsSchematicReader.h \
|
||||
dbLayoutVsSchematicFormatDefs.h \
|
||||
dbLayoutVsSchematic.h \
|
||||
dbNetlistObject.h
|
||||
dbNetlistObject.h \
|
||||
dbTexts.h \
|
||||
dbDeepTexts.h \
|
||||
dbAsIfFlatTexts.h \
|
||||
dbTextsDelegate.h \
|
||||
dbEmptyTexts.h \
|
||||
dbFlatTexts.h \
|
||||
dbTextsUtils.h \
|
||||
dbOriginalLayerTexts.h
|
||||
|
||||
!equals(HAVE_QT, "0") {
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,277 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "dbAsIfFlatTexts.h"
|
||||
#include "dbFlatTexts.h"
|
||||
#include "dbFlatRegion.h"
|
||||
#include "dbFlatEdges.h"
|
||||
#include "dbEmptyTexts.h"
|
||||
#include "dbTexts.h"
|
||||
#include "dbBoxConvert.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------
|
||||
// AsIfFlagTexts implementation
|
||||
|
||||
AsIfFlatTexts::AsIfFlatTexts ()
|
||||
: TextsDelegate (), m_bbox_valid (false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
AsIfFlatTexts::~AsIfFlatTexts ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
std::string
|
||||
AsIfFlatTexts::to_string (size_t nmax) const
|
||||
{
|
||||
std::ostringstream os;
|
||||
TextsIterator p (begin ());
|
||||
bool first = true;
|
||||
for ( ; ! p.at_end () && nmax != 0; ++p, --nmax) {
|
||||
if (! first) {
|
||||
os << ";";
|
||||
}
|
||||
first = false;
|
||||
os << p->to_string ();
|
||||
}
|
||||
if (! p.at_end ()) {
|
||||
os << "...";
|
||||
}
|
||||
return os.str ();
|
||||
}
|
||||
|
||||
TextsDelegate *
|
||||
AsIfFlatTexts::in (const Texts &other, bool invert) const
|
||||
{
|
||||
std::set <db::Text> op;
|
||||
for (TextsIterator o (other.begin ()); ! o.at_end (); ++o) {
|
||||
op.insert (*o);
|
||||
}
|
||||
|
||||
std::auto_ptr<FlatTexts> new_texts (new FlatTexts (false));
|
||||
|
||||
for (TextsIterator o (begin ()); ! o.at_end (); ++o) {
|
||||
if ((op.find (*o) == op.end ()) == invert) {
|
||||
new_texts->insert (*o);
|
||||
}
|
||||
}
|
||||
|
||||
return new_texts.release ();
|
||||
}
|
||||
|
||||
size_t
|
||||
AsIfFlatTexts::size () const
|
||||
{
|
||||
size_t n = 0;
|
||||
for (TextsIterator t (begin ()); ! t.at_end (); ++t) {
|
||||
++n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
Box AsIfFlatTexts::bbox () const
|
||||
{
|
||||
if (! m_bbox_valid) {
|
||||
m_bbox = compute_bbox ();
|
||||
m_bbox_valid = true;
|
||||
}
|
||||
return m_bbox;
|
||||
}
|
||||
|
||||
Box AsIfFlatTexts::compute_bbox () const
|
||||
{
|
||||
db::Box b;
|
||||
for (TextsIterator t (begin ()); ! t.at_end (); ++t) {
|
||||
b += t->box ();
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
void AsIfFlatTexts::update_bbox (const db::Box &b)
|
||||
{
|
||||
m_bbox = b;
|
||||
m_bbox_valid = true;
|
||||
}
|
||||
|
||||
void AsIfFlatTexts::invalidate_bbox ()
|
||||
{
|
||||
m_bbox_valid = false;
|
||||
}
|
||||
|
||||
TextsDelegate *
|
||||
AsIfFlatTexts::filtered (const TextFilterBase &filter) const
|
||||
{
|
||||
std::auto_ptr<FlatTexts> new_texts (new FlatTexts ());
|
||||
|
||||
for (TextsIterator p (begin ()); ! p.at_end (); ++p) {
|
||||
if (filter.selected (*p)) {
|
||||
new_texts->insert (*p);
|
||||
}
|
||||
}
|
||||
|
||||
return new_texts.release ();
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
AsIfFlatTexts::polygons (db::Coord e) const
|
||||
{
|
||||
std::auto_ptr<FlatRegion> 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));
|
||||
}
|
||||
|
||||
return output.release ();
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatTexts::edges () const
|
||||
{
|
||||
std::auto_ptr<FlatEdges> output (new FlatEdges ());
|
||||
|
||||
for (TextsIterator tp (begin ()); ! tp.at_end (); ++tp) {
|
||||
db::Box box = tp->box ();
|
||||
output->insert (db::Edge (box.p1 (), box.p2 ()));
|
||||
}
|
||||
|
||||
return output.release ();
|
||||
}
|
||||
|
||||
TextsDelegate *
|
||||
AsIfFlatTexts::add (const Texts &other) const
|
||||
{
|
||||
FlatTexts *other_flat = dynamic_cast<FlatTexts *> (other.delegate ());
|
||||
if (other_flat) {
|
||||
|
||||
std::auto_ptr<FlatTexts> new_texts (new FlatTexts (*other_flat));
|
||||
new_texts->invalidate_cache ();
|
||||
|
||||
size_t n = new_texts->raw_texts ().size () + size ();
|
||||
|
||||
new_texts->reserve (n);
|
||||
|
||||
for (TextsIterator p (begin ()); ! p.at_end (); ++p) {
|
||||
new_texts->raw_texts ().insert (*p);
|
||||
}
|
||||
|
||||
return new_texts.release ();
|
||||
|
||||
} else {
|
||||
|
||||
std::auto_ptr<FlatTexts> new_texts (new FlatTexts ());
|
||||
|
||||
size_t n = size () + other.size ();
|
||||
|
||||
new_texts->reserve (n);
|
||||
|
||||
for (TextsIterator p (begin ()); ! p.at_end (); ++p) {
|
||||
new_texts->raw_texts ().insert (*p);
|
||||
}
|
||||
for (TextsIterator p (other.begin ()); ! p.at_end (); ++p) {
|
||||
new_texts->raw_texts ().insert (*p);
|
||||
}
|
||||
|
||||
return new_texts.release ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AsIfFlatTexts::equals (const Texts &other) const
|
||||
{
|
||||
if (empty () != other.empty ()) {
|
||||
return false;
|
||||
}
|
||||
if (size () != other.size ()) {
|
||||
return false;
|
||||
}
|
||||
TextsIterator o1 (begin ());
|
||||
TextsIterator o2 (other.begin ());
|
||||
while (! o1.at_end () && ! o2.at_end ()) {
|
||||
if (*o1 != *o2) {
|
||||
return false;
|
||||
}
|
||||
++o1;
|
||||
++o2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AsIfFlatTexts::less (const Texts &other) const
|
||||
{
|
||||
if (empty () != other.empty ()) {
|
||||
return empty () < other.empty ();
|
||||
}
|
||||
if (size () != other.size ()) {
|
||||
return (size () < other.size ());
|
||||
}
|
||||
TextsIterator o1 (begin ());
|
||||
TextsIterator o2 (other.begin ());
|
||||
while (! o1.at_end () && ! o2.at_end ()) {
|
||||
if (*o1 != *o2) {
|
||||
return *o1 < *o2;
|
||||
}
|
||||
++o1;
|
||||
++o2;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
AsIfFlatTexts::insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const
|
||||
{
|
||||
// improves performance when inserting an original layout into the same layout
|
||||
db::LayoutLocker locker (layout);
|
||||
|
||||
db::Shapes &shapes = layout->cell (into_cell).shapes (into_layer);
|
||||
for (TextsIterator t (begin ()); ! t.at_end (); ++t) {
|
||||
shapes.insert (*t);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AsIfFlatTexts::insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const
|
||||
{
|
||||
// improves performance when inserting an original layout into the same layout
|
||||
db::LayoutLocker locker (layout);
|
||||
|
||||
db::Shapes &shapes = layout->cell (into_cell).shapes (into_layer);
|
||||
for (TextsIterator t (begin ()); ! t.at_end (); ++t) {
|
||||
db::Box box = t->box ();
|
||||
box.enlarge (db::Vector (enl, enl));
|
||||
shapes.insert (db::SimplePolygon (box));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HDR_dbAsIfFlatTexts
|
||||
#define HDR_dbAsIfFlatTexts
|
||||
|
||||
#include "dbCommon.h"
|
||||
|
||||
#include "dbTextsDelegate.h"
|
||||
|
||||
namespace db {
|
||||
|
||||
/**
|
||||
* @brief Provides default flat implementations
|
||||
*/
|
||||
class DB_PUBLIC AsIfFlatTexts
|
||||
: public TextsDelegate
|
||||
{
|
||||
public:
|
||||
AsIfFlatTexts ();
|
||||
virtual ~AsIfFlatTexts ();
|
||||
|
||||
virtual size_t size () const;
|
||||
virtual std::string to_string (size_t) const;
|
||||
virtual Box bbox () const;
|
||||
|
||||
virtual TextsDelegate *filter_in_place (const TextFilterBase &filter)
|
||||
{
|
||||
return filtered (filter);
|
||||
}
|
||||
|
||||
virtual TextsDelegate *filtered (const TextFilterBase &) const;
|
||||
|
||||
virtual TextsDelegate *add_in_place (const Texts &other)
|
||||
{
|
||||
return add (other);
|
||||
}
|
||||
|
||||
virtual TextsDelegate *add (const Texts &other) const;
|
||||
|
||||
virtual RegionDelegate *polygons (db::Coord e) const;
|
||||
virtual EdgesDelegate *edges () const;
|
||||
|
||||
virtual TextsDelegate *in (const Texts &, bool) const;
|
||||
|
||||
virtual bool equals (const Texts &other) const;
|
||||
virtual bool less (const Texts &other) const;
|
||||
|
||||
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const;
|
||||
virtual void insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const;
|
||||
|
||||
protected:
|
||||
void update_bbox (const db::Box &box);
|
||||
void invalidate_bbox ();
|
||||
|
||||
private:
|
||||
AsIfFlatTexts &operator= (const AsIfFlatTexts &other);
|
||||
|
||||
mutable bool m_bbox_valid;
|
||||
mutable db::Box m_bbox;
|
||||
|
||||
virtual db::Box compute_bbox () const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -807,64 +807,20 @@ DeepLayer DeepShapeStore::create_copy (const DeepLayer &source, HierarchyBuilder
|
|||
|
||||
DeepLayer DeepShapeStore::create_edge_layer (const db::RecursiveShapeIterator &si, bool as_edges, const db::ICplxTrans &trans)
|
||||
{
|
||||
unsigned int layout_index = layout_for_iter (si, trans);
|
||||
|
||||
db::Layout &layout = m_layouts[layout_index]->layout;
|
||||
db::HierarchyBuilder &builder = m_layouts[layout_index]->builder;
|
||||
|
||||
unsigned int layer_index = init_layer (layout, si);
|
||||
builder.set_target_layer (layer_index);
|
||||
|
||||
// The chain of operators for producing edges
|
||||
db::EdgeBuildingHierarchyBuilderShapeReceiver refs (as_edges);
|
||||
|
||||
// Build the working hierarchy from the recursive shape iterator
|
||||
try {
|
||||
|
||||
tl::SelfTimer timer (tl::verbosity () >= 41, tl::to_string (tr ("Building working hierarchy")));
|
||||
db::LayoutLocker ll (&layout, true /*no update*/);
|
||||
|
||||
builder.set_shape_receiver (&refs);
|
||||
db::RecursiveShapeIterator (si).push (& builder);
|
||||
builder.set_shape_receiver (0);
|
||||
|
||||
} catch (...) {
|
||||
builder.set_shape_receiver (0);
|
||||
throw;
|
||||
}
|
||||
|
||||
return DeepLayer (this, layout_index, layer_index);
|
||||
return create_custom_layer (si, &refs, trans);
|
||||
}
|
||||
|
||||
DeepLayer DeepShapeStore::create_edge_pair_layer (const db::RecursiveShapeIterator &si, const db::ICplxTrans &trans)
|
||||
{
|
||||
unsigned int layout_index = layout_for_iter (si, trans);
|
||||
|
||||
db::Layout &layout = m_layouts[layout_index]->layout;
|
||||
db::HierarchyBuilder &builder = m_layouts[layout_index]->builder;
|
||||
|
||||
unsigned int layer_index = init_layer (layout, si);
|
||||
builder.set_target_layer (layer_index);
|
||||
|
||||
// The chain of operators for producing the edge pairs
|
||||
db::EdgePairBuildingHierarchyBuilderShapeReceiver refs;
|
||||
return create_custom_layer (si, &refs, trans);
|
||||
}
|
||||
|
||||
// Build the working hierarchy from the recursive shape iterator
|
||||
try {
|
||||
|
||||
tl::SelfTimer timer (tl::verbosity () >= 41, tl::to_string (tr ("Building working hierarchy")));
|
||||
db::LayoutLocker ll (&layout, true /*no update*/);
|
||||
|
||||
builder.set_shape_receiver (&refs);
|
||||
db::RecursiveShapeIterator (si).push (& builder);
|
||||
builder.set_shape_receiver (0);
|
||||
|
||||
} catch (...) {
|
||||
builder.set_shape_receiver (0);
|
||||
throw;
|
||||
}
|
||||
|
||||
return DeepLayer (this, layout_index, layer_index);
|
||||
DeepLayer DeepShapeStore::create_text_layer (const db::RecursiveShapeIterator &si, const db::ICplxTrans &trans)
|
||||
{
|
||||
db::TextBuildingHierarchyBuilderShapeReceiver refs;
|
||||
return create_custom_layer (si, &refs, trans);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -395,6 +395,15 @@ public:
|
|||
*/
|
||||
DeepLayer create_edge_pair_layer (const db::RecursiveShapeIterator &si, const ICplxTrans &trans = db::ICplxTrans ());
|
||||
|
||||
/**
|
||||
* @brief Inserts an text layer into the deep shape store
|
||||
*
|
||||
* This method will create a new layer inside the deep shape store as a
|
||||
* working copy of the original layer. This method creates a layer
|
||||
* for texts.
|
||||
*/
|
||||
DeepLayer create_text_layer (const db::RecursiveShapeIterator &si, const ICplxTrans &trans = db::ICplxTrans ());
|
||||
|
||||
/**
|
||||
* @brief Inserts a polygon layer into the deep shape store using a custom preparation pipeline
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,316 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "dbDeepTexts.h"
|
||||
#include "dbCellGraphUtils.h"
|
||||
#include "dbDeepEdges.h"
|
||||
#include "dbDeepRegion.h"
|
||||
#include "dbCellMapping.h"
|
||||
#include "dbLayoutUtils.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief An iterator delegate for the deep text collection
|
||||
* TODO: this is kind of redundant with OriginalLayerIterator ..
|
||||
*/
|
||||
class DB_PUBLIC DeepTextsIterator
|
||||
: public TextsIteratorDelegate
|
||||
{
|
||||
public:
|
||||
DeepTextsIterator (const db::RecursiveShapeIterator &iter)
|
||||
: m_iter (iter)
|
||||
{
|
||||
set ();
|
||||
}
|
||||
|
||||
virtual ~DeepTextsIterator () { }
|
||||
|
||||
virtual bool at_end () const
|
||||
{
|
||||
return m_iter.at_end ();
|
||||
}
|
||||
|
||||
virtual void increment ()
|
||||
{
|
||||
++m_iter;
|
||||
set ();
|
||||
}
|
||||
|
||||
virtual const value_type *get () const
|
||||
{
|
||||
return &m_text;
|
||||
}
|
||||
|
||||
virtual TextsIteratorDelegate *clone () const
|
||||
{
|
||||
return new DeepTextsIterator (*this);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Texts;
|
||||
|
||||
db::RecursiveShapeIterator m_iter;
|
||||
mutable value_type m_text;
|
||||
|
||||
void set () const {
|
||||
if (! m_iter.at_end ()) {
|
||||
m_iter.shape ().text (m_text);
|
||||
m_text.transform (m_iter.trans ());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
DeepTexts::DeepTexts ()
|
||||
: AsIfFlatTexts (), m_deep_layer ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
DeepTexts::DeepTexts (const RecursiveShapeIterator &si, DeepShapeStore &dss)
|
||||
: AsIfFlatTexts (), m_deep_layer (dss.create_text_layer (si))
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
DeepTexts::DeepTexts (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans)
|
||||
: AsIfFlatTexts (), m_deep_layer (dss.create_text_layer (si, trans))
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
DeepTexts::DeepTexts (const DeepTexts &other)
|
||||
: AsIfFlatTexts (other),
|
||||
m_deep_layer (other.m_deep_layer.copy ())
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
DeepTexts::DeepTexts (const DeepLayer &dl)
|
||||
: AsIfFlatTexts (), m_deep_layer (dl)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
DeepTexts::~DeepTexts ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
TextsDelegate *DeepTexts::clone () const
|
||||
{
|
||||
return new DeepTexts (*this);
|
||||
}
|
||||
|
||||
TextsIteratorDelegate *DeepTexts::begin () const
|
||||
{
|
||||
return new DeepTextsIterator (begin_iter ().first);
|
||||
}
|
||||
|
||||
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> DeepTexts::begin_iter () const
|
||||
{
|
||||
const db::Layout &layout = m_deep_layer.layout ();
|
||||
if (layout.cells () == 0) {
|
||||
|
||||
return std::make_pair (db::RecursiveShapeIterator (), db::ICplxTrans ());
|
||||
|
||||
} else {
|
||||
|
||||
const db::Cell &top_cell = layout.cell (*layout.begin_top_down ());
|
||||
db::RecursiveShapeIterator iter (m_deep_layer.layout (), top_cell, m_deep_layer.layer ());
|
||||
return std::make_pair (iter, db::ICplxTrans ());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
size_t DeepTexts::size () const
|
||||
{
|
||||
size_t n = 0;
|
||||
|
||||
const db::Layout &layout = m_deep_layer.layout ();
|
||||
db::CellCounter cc (&layout);
|
||||
for (db::Layout::top_down_const_iterator c = layout.begin_top_down (); c != layout.end_top_down (); ++c) {
|
||||
n += cc.weight (*c) * layout.cell (*c).shapes (m_deep_layer.layer ()).size ();
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
std::string DeepTexts::to_string (size_t nmax) const
|
||||
{
|
||||
return db::AsIfFlatTexts::to_string (nmax);
|
||||
}
|
||||
|
||||
Box DeepTexts::bbox () const
|
||||
{
|
||||
return m_deep_layer.initial_cell ().bbox (m_deep_layer.layer ());
|
||||
}
|
||||
|
||||
bool DeepTexts::empty () const
|
||||
{
|
||||
return begin_iter ().first.at_end ();
|
||||
}
|
||||
|
||||
const db::Text *DeepTexts::nth (size_t) const
|
||||
{
|
||||
throw tl::Exception (tl::to_string (tr ("Random access to texts is available only for flat text collections")));
|
||||
}
|
||||
|
||||
bool DeepTexts::has_valid_texts () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const db::RecursiveShapeIterator *DeepTexts::iter () const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
TextsDelegate *
|
||||
DeepTexts::add_in_place (const Texts &other)
|
||||
{
|
||||
if (other.empty ()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const DeepTexts *other_deep = dynamic_cast <const DeepTexts *> (other.delegate ());
|
||||
if (other_deep) {
|
||||
|
||||
deep_layer ().add_from (other_deep->deep_layer ());
|
||||
|
||||
} else {
|
||||
|
||||
// non-deep to deep merge (flat)
|
||||
|
||||
db::Shapes &shapes = deep_layer ().initial_cell ().shapes (deep_layer ().layer ());
|
||||
for (db::Texts::const_iterator p = other.begin (); ! p.at_end (); ++p) {
|
||||
shapes.insert (*p);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
TextsDelegate *DeepTexts::add (const Texts &other) const
|
||||
{
|
||||
if (other.empty ()) {
|
||||
return clone ();
|
||||
} else if (empty ()) {
|
||||
return other.delegate ()->clone ();
|
||||
} else {
|
||||
DeepTexts *new_texts = dynamic_cast<DeepTexts *> (clone ());
|
||||
new_texts->add_in_place (other);
|
||||
return new_texts;
|
||||
}
|
||||
}
|
||||
|
||||
TextsDelegate *DeepTexts::filter_in_place (const TextFilterBase &filter)
|
||||
{
|
||||
// TODO: implement
|
||||
return AsIfFlatTexts::filter_in_place (filter);
|
||||
}
|
||||
|
||||
TextsDelegate *DeepTexts::filtered (const TextFilterBase &filter) const
|
||||
{
|
||||
// TODO: implement
|
||||
return AsIfFlatTexts::filtered (filter);
|
||||
}
|
||||
|
||||
RegionDelegate *DeepTexts::polygons (db::Coord e) const
|
||||
{
|
||||
db::DeepLayer new_layer = m_deep_layer.derived ();
|
||||
db::Layout &layout = const_cast<db::Layout &> (m_deep_layer.layout ());
|
||||
|
||||
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
|
||||
db::Shapes &output = c->shapes (new_layer.layer ());
|
||||
for (db::Shapes::shape_iterator s = c->shapes (m_deep_layer.layer ()).begin (db::ShapeIterator::Texts); ! s.at_end (); ++s) {
|
||||
db::Box box = s->bbox ();
|
||||
box.enlarge (db::Vector (e, e));
|
||||
db::Polygon poly (box);
|
||||
output.insert (db::PolygonRef (poly, layout.shape_repository ()));
|
||||
}
|
||||
}
|
||||
|
||||
return new db::DeepRegion (new_layer);
|
||||
}
|
||||
|
||||
EdgesDelegate *DeepTexts::edges () const
|
||||
{
|
||||
db::DeepLayer new_layer = m_deep_layer.derived ();
|
||||
db::Layout &layout = const_cast<db::Layout &> (m_deep_layer.layout ());
|
||||
|
||||
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
|
||||
db::Shapes &output = c->shapes (new_layer.layer ());
|
||||
for (db::Shapes::shape_iterator s = c->shapes (m_deep_layer.layer ()).begin (db::ShapeIterator::Texts); ! s.at_end (); ++s) {
|
||||
db::Box box = s->bbox ();
|
||||
output.insert (db::Edge (box.p1 (), box.p2 ()));
|
||||
}
|
||||
}
|
||||
|
||||
return new db::DeepEdges (new_layer);
|
||||
}
|
||||
|
||||
TextsDelegate *DeepTexts::in (const Texts &other, bool invert) const
|
||||
{
|
||||
// TODO: implement
|
||||
return AsIfFlatTexts::in (other, invert);
|
||||
}
|
||||
|
||||
bool DeepTexts::equals (const Texts &other) const
|
||||
{
|
||||
const DeepTexts *other_delegate = dynamic_cast<const DeepTexts *> (other.delegate ());
|
||||
if (other_delegate && &other_delegate->m_deep_layer.layout () == &m_deep_layer.layout ()
|
||||
&& other_delegate->m_deep_layer.layer () == m_deep_layer.layer ()) {
|
||||
return true;
|
||||
} else {
|
||||
return AsIfFlatTexts::equals (other);
|
||||
}
|
||||
}
|
||||
|
||||
bool DeepTexts::less (const Texts &other) const
|
||||
{
|
||||
const DeepTexts *other_delegate = dynamic_cast<const DeepTexts *> (other.delegate ());
|
||||
if (other_delegate && &other_delegate->m_deep_layer.layout () == &m_deep_layer.layout ()) {
|
||||
return other_delegate->m_deep_layer.layer () < m_deep_layer.layer ();
|
||||
} else {
|
||||
return AsIfFlatTexts::less (other);
|
||||
}
|
||||
}
|
||||
|
||||
void DeepTexts::insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const
|
||||
{
|
||||
m_deep_layer.insert_into (layout, into_cell, into_layer);
|
||||
}
|
||||
|
||||
void DeepTexts::insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const
|
||||
{
|
||||
m_deep_layer.insert_into_as_polygons (layout, into_cell, into_layer, enl);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HDR_dbDeepTexts
|
||||
#define HDR_dbDeepTexts
|
||||
|
||||
#include "dbCommon.h"
|
||||
|
||||
#include "dbAsIfFlatTexts.h"
|
||||
#include "dbDeepShapeStore.h"
|
||||
#include "dbTexts.h"
|
||||
|
||||
namespace db {
|
||||
|
||||
/**
|
||||
* @brief Provides hierarchical edges implementation
|
||||
*/
|
||||
class DB_PUBLIC DeepTexts
|
||||
: public db::AsIfFlatTexts
|
||||
{
|
||||
public:
|
||||
DeepTexts ();
|
||||
DeepTexts (const RecursiveShapeIterator &si, DeepShapeStore &dss);
|
||||
DeepTexts (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans);
|
||||
|
||||
DeepTexts (const DeepTexts &other);
|
||||
DeepTexts (const DeepLayer &dl);
|
||||
|
||||
virtual ~DeepTexts ();
|
||||
|
||||
TextsDelegate *clone () const;
|
||||
|
||||
virtual TextsIteratorDelegate *begin () const;
|
||||
virtual std::pair<db::RecursiveShapeIterator, db::ICplxTrans> begin_iter () const;
|
||||
|
||||
virtual size_t size () const;
|
||||
virtual std::string to_string (size_t) const;
|
||||
virtual Box bbox () const;
|
||||
virtual bool empty () const;
|
||||
virtual const db::Text *nth (size_t n) const;
|
||||
virtual bool has_valid_texts () const;
|
||||
virtual const db::RecursiveShapeIterator *iter () const;
|
||||
|
||||
virtual TextsDelegate *filter_in_place (const TextFilterBase &filter);
|
||||
virtual TextsDelegate *filtered (const TextFilterBase &) const;
|
||||
|
||||
virtual TextsDelegate *add_in_place (const Texts &other);
|
||||
virtual TextsDelegate *add (const Texts &other) const;
|
||||
|
||||
virtual RegionDelegate *polygons (db::Coord e) const;
|
||||
virtual EdgesDelegate *edges () const;
|
||||
|
||||
virtual TextsDelegate *in (const Texts &, bool) const;
|
||||
|
||||
virtual bool equals (const Texts &other) const;
|
||||
virtual bool less (const Texts &other) const;
|
||||
|
||||
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const;
|
||||
virtual void insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const;
|
||||
|
||||
const DeepLayer &deep_layer () const
|
||||
{
|
||||
return m_deep_layer;
|
||||
}
|
||||
|
||||
DeepLayer &deep_layer ()
|
||||
{
|
||||
return m_deep_layer;
|
||||
}
|
||||
|
||||
private:
|
||||
DeepTexts &operator= (const DeepTexts &other);
|
||||
|
||||
DeepLayer m_deep_layer;
|
||||
|
||||
void init ();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1301,6 +1301,7 @@ public:
|
|||
|
||||
private:
|
||||
friend class EdgePairs;
|
||||
friend class Texts;
|
||||
|
||||
EdgesDelegate *mp_delegate;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "dbEmptyTexts.h"
|
||||
#include "dbEmptyRegion.h"
|
||||
#include "dbEmptyEdges.h"
|
||||
#include "dbTexts.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------
|
||||
|
||||
EmptyTexts::EmptyTexts ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
EmptyTexts::EmptyTexts (const EmptyTexts &other)
|
||||
: TextsDelegate (other)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
TextsDelegate *
|
||||
EmptyTexts::clone () const
|
||||
{
|
||||
return new EmptyTexts (*this);
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
EmptyTexts::polygons (db::Coord) const
|
||||
{
|
||||
return new EmptyRegion ();
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
EmptyTexts::edges () const
|
||||
{
|
||||
return new EmptyEdges ();
|
||||
}
|
||||
|
||||
TextsDelegate *
|
||||
EmptyTexts::add_in_place (const Texts &other)
|
||||
{
|
||||
return add (other);
|
||||
}
|
||||
|
||||
TextsDelegate *
|
||||
EmptyTexts::add (const Texts &other) const
|
||||
{
|
||||
return other.delegate ()->clone ();
|
||||
}
|
||||
|
||||
bool
|
||||
EmptyTexts::equals (const Texts &other) const
|
||||
{
|
||||
return other.empty ();
|
||||
}
|
||||
|
||||
bool
|
||||
EmptyTexts::less (const Texts &other) const
|
||||
{
|
||||
return other.empty () ? false : true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HDR_dbEmptyTexts
|
||||
#define HDR_dbEmptyTexts
|
||||
|
||||
#include "dbCommon.h"
|
||||
|
||||
#include "dbTextsDelegate.h"
|
||||
#include "dbRecursiveShapeIterator.h"
|
||||
|
||||
namespace db {
|
||||
|
||||
/**
|
||||
* @brief The delegate for the actual edge set implementation
|
||||
*/
|
||||
class DB_PUBLIC EmptyTexts
|
||||
: public TextsDelegate
|
||||
{
|
||||
public:
|
||||
EmptyTexts ();
|
||||
EmptyTexts (const EmptyTexts &other);
|
||||
|
||||
virtual TextsDelegate *clone () const;
|
||||
|
||||
virtual std::string to_string (size_t) const { return std::string (); }
|
||||
|
||||
virtual TextsIteratorDelegate *begin () const { return 0; }
|
||||
virtual std::pair<db::RecursiveShapeIterator, db::ICplxTrans> begin_iter () const { return std::make_pair (db::RecursiveShapeIterator (), db::ICplxTrans ()); }
|
||||
|
||||
virtual bool empty () const { return true; }
|
||||
virtual size_t size () const { return 0; }
|
||||
|
||||
virtual Box bbox () const { return Box (); }
|
||||
|
||||
virtual TextsDelegate *filter_in_place (const TextFilterBase &) { return this; }
|
||||
virtual TextsDelegate *filtered (const TextFilterBase &) const { return new EmptyTexts (); }
|
||||
|
||||
virtual RegionDelegate *polygons (db::Coord e) const;
|
||||
virtual EdgesDelegate *edges () const;
|
||||
|
||||
virtual TextsDelegate *add_in_place (const Texts &other);
|
||||
virtual TextsDelegate *add (const Texts &other) const;
|
||||
|
||||
virtual TextsDelegate *in (const Texts &, bool) const { return new EmptyTexts (); }
|
||||
|
||||
virtual const db::Text *nth (size_t) const { tl_assert (false); }
|
||||
virtual bool has_valid_texts () const { return true; }
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const { return 0; }
|
||||
|
||||
virtual bool equals (const Texts &other) const;
|
||||
virtual bool less (const Texts &other) const;
|
||||
|
||||
virtual void insert_into (Layout *, db::cell_index_type, unsigned int) const { }
|
||||
virtual void insert_into_as_polygons (Layout *, db::cell_index_type, unsigned int, db::Coord) const { }
|
||||
|
||||
private:
|
||||
EmptyTexts &operator= (const EmptyTexts &other);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "dbFlatTexts.h"
|
||||
#include "dbEmptyTexts.h"
|
||||
#include "dbTexts.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------
|
||||
// FlatTexts implementation
|
||||
|
||||
FlatTexts::FlatTexts ()
|
||||
: AsIfFlatTexts (), m_texts (false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
FlatTexts::~FlatTexts ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
FlatTexts::FlatTexts (const FlatTexts &other)
|
||||
: AsIfFlatTexts (other), m_texts (false)
|
||||
{
|
||||
m_texts = other.m_texts;
|
||||
}
|
||||
|
||||
FlatTexts::FlatTexts (const db::Shapes &texts)
|
||||
: AsIfFlatTexts (), m_texts (texts)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void FlatTexts::invalidate_cache ()
|
||||
{
|
||||
invalidate_bbox ();
|
||||
}
|
||||
|
||||
void FlatTexts::reserve (size_t n)
|
||||
{
|
||||
m_texts.reserve (db::Text::tag (), n);
|
||||
}
|
||||
|
||||
TextsIteratorDelegate *FlatTexts::begin () const
|
||||
{
|
||||
return new FlatTextsIterator (m_texts.get_layer<db::Text, db::unstable_layer_tag> ().begin (), m_texts.get_layer<db::Text, db::unstable_layer_tag> ().end ());
|
||||
}
|
||||
|
||||
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> FlatTexts::begin_iter () const
|
||||
{
|
||||
return std::make_pair (db::RecursiveShapeIterator (m_texts), db::ICplxTrans ());
|
||||
}
|
||||
|
||||
bool FlatTexts::empty () const
|
||||
{
|
||||
return m_texts.empty ();
|
||||
}
|
||||
|
||||
size_t FlatTexts::size () const
|
||||
{
|
||||
return m_texts.size ();
|
||||
}
|
||||
|
||||
Box FlatTexts::compute_bbox () const
|
||||
{
|
||||
m_texts.update_bbox ();
|
||||
return m_texts.bbox ();
|
||||
}
|
||||
|
||||
TextsDelegate *
|
||||
FlatTexts::filter_in_place (const TextFilterBase &filter)
|
||||
{
|
||||
text_iterator_type pw = m_texts.get_layer<db::Text, db::unstable_layer_tag> ().begin ();
|
||||
for (TextsIterator p (begin ()); ! p.at_end (); ++p) {
|
||||
if (filter.selected (*p)) {
|
||||
if (pw == m_texts.get_layer<db::Text, db::unstable_layer_tag> ().end ()) {
|
||||
m_texts.get_layer<db::Text, db::unstable_layer_tag> ().insert (*p);
|
||||
pw = m_texts.get_layer<db::Text, db::unstable_layer_tag> ().end ();
|
||||
} else {
|
||||
m_texts.get_layer<db::Text, db::unstable_layer_tag> ().replace (pw++, *p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_texts.get_layer<db::Text, db::unstable_layer_tag> ().erase (pw, m_texts.get_layer<db::Text, db::unstable_layer_tag> ().end ());
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
TextsDelegate *FlatTexts::add (const Texts &other) const
|
||||
{
|
||||
std::auto_ptr<FlatTexts> new_texts (new FlatTexts (*this));
|
||||
new_texts->invalidate_cache ();
|
||||
|
||||
FlatTexts *other_flat = dynamic_cast<FlatTexts *> (other.delegate ());
|
||||
if (other_flat) {
|
||||
|
||||
new_texts->raw_texts ().insert (other_flat->raw_texts ().get_layer<db::Text, db::unstable_layer_tag> ().begin (), other_flat->raw_texts ().get_layer<db::Text, db::unstable_layer_tag> ().end ());
|
||||
|
||||
} else {
|
||||
|
||||
size_t n = new_texts->raw_texts ().size ();
|
||||
for (TextsIterator p (other.begin ()); ! p.at_end (); ++p) {
|
||||
++n;
|
||||
}
|
||||
|
||||
new_texts->raw_texts ().reserve (db::Text::tag (), n);
|
||||
|
||||
for (TextsIterator p (other.begin ()); ! p.at_end (); ++p) {
|
||||
new_texts->raw_texts ().insert (*p);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return new_texts.release ();
|
||||
}
|
||||
|
||||
TextsDelegate *FlatTexts::add_in_place (const Texts &other)
|
||||
{
|
||||
invalidate_cache ();
|
||||
|
||||
FlatTexts *other_flat = dynamic_cast<FlatTexts *> (other.delegate ());
|
||||
if (other_flat) {
|
||||
|
||||
m_texts.insert (other_flat->raw_texts ().get_layer<db::Text, db::unstable_layer_tag> ().begin (), other_flat->raw_texts ().get_layer<db::Text, db::unstable_layer_tag> ().end ());
|
||||
|
||||
} else {
|
||||
|
||||
size_t n = m_texts.size ();
|
||||
for (TextsIterator p (other.begin ()); ! p.at_end (); ++p) {
|
||||
++n;
|
||||
}
|
||||
|
||||
m_texts.reserve (db::Text::tag (), n);
|
||||
|
||||
for (TextsIterator p (other.begin ()); ! p.at_end (); ++p) {
|
||||
m_texts.insert (*p);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
const db::Text *FlatTexts::nth (size_t n) const
|
||||
{
|
||||
return n < m_texts.size () ? &m_texts.get_layer<db::Text, db::unstable_layer_tag> ().begin () [n] : 0;
|
||||
}
|
||||
|
||||
bool FlatTexts::has_valid_texts () const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const db::RecursiveShapeIterator *FlatTexts::iter () const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
FlatTexts::insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const
|
||||
{
|
||||
db::Shapes &out = layout->cell (into_cell).shapes (into_layer);
|
||||
for (TextsIterator p (begin ()); ! p.at_end (); ++p) {
|
||||
db::Box box = p->box ();
|
||||
box.enlarge (db::Vector (enl, enl));
|
||||
out.insert (db::SimplePolygon (box));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FlatTexts::insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const
|
||||
{
|
||||
layout->cell (into_cell).shapes (into_layer).insert (m_texts);
|
||||
}
|
||||
|
||||
void
|
||||
FlatTexts::insert (const db::Text &t)
|
||||
{
|
||||
m_texts.insert (t);
|
||||
invalidate_cache ();
|
||||
}
|
||||
|
||||
void
|
||||
FlatTexts::insert (const db::Shape &shape)
|
||||
{
|
||||
if (shape.is_edge_pair ()) {
|
||||
|
||||
db::Text t;
|
||||
shape.text (t);
|
||||
insert (t);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HDR_dbFlatTexts
|
||||
#define HDR_dbFlatTexts
|
||||
|
||||
#include "dbCommon.h"
|
||||
|
||||
#include "dbAsIfFlatTexts.h"
|
||||
#include "dbShapes.h"
|
||||
|
||||
namespace db {
|
||||
|
||||
/**
|
||||
* @brief An iterator delegate for the flat text set
|
||||
*/
|
||||
class DB_PUBLIC FlatTextsIterator
|
||||
: public TextsIteratorDelegate
|
||||
{
|
||||
public:
|
||||
typedef db::layer<db::Text, db::unstable_layer_tag> edge_pair_layer_type;
|
||||
typedef edge_pair_layer_type::iterator iterator_type;
|
||||
|
||||
FlatTextsIterator (iterator_type from, iterator_type to)
|
||||
: m_from (from), m_to (to)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual bool at_end () const
|
||||
{
|
||||
return m_from == m_to;
|
||||
}
|
||||
|
||||
virtual void increment ()
|
||||
{
|
||||
++m_from;
|
||||
}
|
||||
|
||||
virtual const value_type *get () const
|
||||
{
|
||||
return m_from.operator-> ();
|
||||
}
|
||||
|
||||
virtual TextsIteratorDelegate *clone () const
|
||||
{
|
||||
return new FlatTextsIterator (*this);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Texts;
|
||||
|
||||
iterator_type m_from, m_to;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The delegate for the actual text set implementation
|
||||
*/
|
||||
class DB_PUBLIC FlatTexts
|
||||
: public AsIfFlatTexts
|
||||
{
|
||||
public:
|
||||
typedef db::layer<db::Text, db::unstable_layer_tag> text_layer_type;
|
||||
typedef text_layer_type::iterator text_iterator_type;
|
||||
|
||||
FlatTexts ();
|
||||
FlatTexts (const db::Shapes &texts);
|
||||
|
||||
FlatTexts (const FlatTexts &other);
|
||||
|
||||
virtual ~FlatTexts ();
|
||||
|
||||
TextsDelegate *clone () const
|
||||
{
|
||||
return new FlatTexts (*this);
|
||||
}
|
||||
|
||||
void reserve (size_t);
|
||||
|
||||
virtual TextsIteratorDelegate *begin () const;
|
||||
virtual std::pair<db::RecursiveShapeIterator, db::ICplxTrans> begin_iter () const;
|
||||
|
||||
virtual bool empty () const;
|
||||
virtual size_t size () const;
|
||||
|
||||
virtual TextsDelegate *filter_in_place (const TextFilterBase &filter);
|
||||
|
||||
virtual TextsDelegate *add_in_place (const Texts &other);
|
||||
virtual TextsDelegate *add (const Texts &other) const;
|
||||
|
||||
virtual const db::Text *nth (size_t n) const;
|
||||
virtual bool has_valid_texts () const;
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const;
|
||||
|
||||
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const;
|
||||
virtual void insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const;
|
||||
|
||||
void insert (const db::Text &text);
|
||||
void insert (const db::Shape &shape);
|
||||
|
||||
template <class T>
|
||||
void insert (const db::Shape &shape, const T &trans)
|
||||
{
|
||||
if (shape.is_edge_pair ()) {
|
||||
|
||||
db::Text t;
|
||||
shape.text (t);
|
||||
t.transform (trans);
|
||||
insert (t);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
template <class Iter>
|
||||
void insert_seq (const Iter &seq)
|
||||
{
|
||||
for (Iter i = seq; ! i.at_end (); ++i) {
|
||||
insert (*i);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Trans>
|
||||
void transform (const Trans &trans)
|
||||
{
|
||||
if (! trans.is_unity ()) {
|
||||
for (text_iterator_type p = m_texts.template get_layer<db::Text, db::unstable_layer_tag> ().begin (); p != m_texts.template get_layer<db::Text, db::unstable_layer_tag> ().end (); ++p) {
|
||||
m_texts.get_layer<db::Text, db::unstable_layer_tag> ().replace (p, p->transformed (trans));
|
||||
}
|
||||
invalidate_cache ();
|
||||
}
|
||||
}
|
||||
|
||||
db::Shapes &raw_texts () { return m_texts; }
|
||||
|
||||
protected:
|
||||
virtual Box compute_bbox () const;
|
||||
void invalidate_cache ();
|
||||
|
||||
private:
|
||||
friend class AsIfFlatTexts;
|
||||
|
||||
FlatTexts &operator= (const FlatTexts &other);
|
||||
|
||||
mutable db::Shapes m_texts;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -704,4 +704,18 @@ void EdgePairBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape
|
|||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
TextBuildingHierarchyBuilderShapeReceiver::TextBuildingHierarchyBuilderShapeReceiver ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void TextBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box & /*region*/, const db::RecursiveShapeReceiver::box_tree_type * /*complex_region*/, db::Shapes *target)
|
||||
{
|
||||
if (shape.is_text ()) {
|
||||
target->insert (shape.text ().transformed (trans));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,6 +189,20 @@ public:
|
|||
virtual void push (const db::Polygon &, const db::ICplxTrans &, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *) { }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An text-generating shape receiver that feeds a shapes array after turning the shapes into texts
|
||||
*/
|
||||
class DB_PUBLIC TextBuildingHierarchyBuilderShapeReceiver
|
||||
: public HierarchyBuilderShapeReceiver
|
||||
{
|
||||
public:
|
||||
TextBuildingHierarchyBuilderShapeReceiver ();
|
||||
|
||||
virtual void push (const db::Shape &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
|
||||
virtual void push (const db::Box &, const db::ICplxTrans &, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *) { }
|
||||
virtual void push (const db::Polygon &, const db::ICplxTrans &, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *) { }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A class building a hierarchy from a recursive shape iterator in push mode
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,197 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "dbOriginalLayerTexts.h"
|
||||
#include "dbTexts.h"
|
||||
#include "tlInternational.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------
|
||||
// OriginalLayerTexts implementation
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class OriginalLayerTextsIterator
|
||||
: public TextsIteratorDelegate
|
||||
{
|
||||
public:
|
||||
OriginalLayerTextsIterator (const db::RecursiveShapeIterator &iter, const db::ICplxTrans &trans)
|
||||
: m_rec_iter (iter), m_iter_trans (trans)
|
||||
{
|
||||
set ();
|
||||
}
|
||||
|
||||
virtual bool at_end () const
|
||||
{
|
||||
return m_rec_iter.at_end ();
|
||||
}
|
||||
|
||||
virtual void increment ()
|
||||
{
|
||||
inc ();
|
||||
set ();
|
||||
}
|
||||
|
||||
virtual const value_type *get () const
|
||||
{
|
||||
return &m_text;
|
||||
}
|
||||
|
||||
virtual TextsIteratorDelegate *clone () const
|
||||
{
|
||||
return new OriginalLayerTextsIterator (*this);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Texts;
|
||||
|
||||
db::RecursiveShapeIterator m_rec_iter;
|
||||
db::ICplxTrans m_iter_trans;
|
||||
db::Text m_text;
|
||||
|
||||
void set ()
|
||||
{
|
||||
while (! m_rec_iter.at_end () && ! m_rec_iter.shape ().is_text ()) {
|
||||
++m_rec_iter;
|
||||
}
|
||||
if (! m_rec_iter.at_end ()) {
|
||||
m_rec_iter.shape ().text (m_text);
|
||||
m_text.transform (m_iter_trans * m_rec_iter.trans ());
|
||||
}
|
||||
}
|
||||
|
||||
void inc ()
|
||||
{
|
||||
if (! m_rec_iter.at_end ()) {
|
||||
++m_rec_iter;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
OriginalLayerTexts::OriginalLayerTexts ()
|
||||
: AsIfFlatTexts ()
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
||||
OriginalLayerTexts::OriginalLayerTexts (const OriginalLayerTexts &other)
|
||||
: AsIfFlatTexts (other),
|
||||
m_iter (other.m_iter),
|
||||
m_iter_trans (other.m_iter_trans)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
OriginalLayerTexts::OriginalLayerTexts (const RecursiveShapeIterator &si)
|
||||
: AsIfFlatTexts (), m_iter (si)
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
||||
OriginalLayerTexts::OriginalLayerTexts (const RecursiveShapeIterator &si, const db::ICplxTrans &trans)
|
||||
: AsIfFlatTexts (), m_iter (si), m_iter_trans (trans)
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
||||
OriginalLayerTexts::~OriginalLayerTexts ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
TextsDelegate *
|
||||
OriginalLayerTexts::clone () const
|
||||
{
|
||||
return new OriginalLayerTexts (*this);
|
||||
}
|
||||
|
||||
TextsIteratorDelegate *
|
||||
OriginalLayerTexts::begin () const
|
||||
{
|
||||
return new OriginalLayerTextsIterator (m_iter, m_iter_trans);
|
||||
}
|
||||
|
||||
std::pair<db::RecursiveShapeIterator, db::ICplxTrans>
|
||||
OriginalLayerTexts::begin_iter () const
|
||||
{
|
||||
return std::make_pair (m_iter, m_iter_trans);
|
||||
}
|
||||
|
||||
bool
|
||||
OriginalLayerTexts::empty () const
|
||||
{
|
||||
return m_iter.at_end ();
|
||||
}
|
||||
|
||||
const db::Text *
|
||||
OriginalLayerTexts::nth (size_t) const
|
||||
{
|
||||
throw tl::Exception (tl::to_string (tr ("Random access to texts is available only for flat collections")));
|
||||
}
|
||||
|
||||
bool
|
||||
OriginalLayerTexts::has_valid_texts () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const db::RecursiveShapeIterator *
|
||||
OriginalLayerTexts::iter () const
|
||||
{
|
||||
return &m_iter;
|
||||
}
|
||||
|
||||
bool
|
||||
OriginalLayerTexts::equals (const Texts &other) const
|
||||
{
|
||||
const OriginalLayerTexts *other_delegate = dynamic_cast<const OriginalLayerTexts *> (other.delegate ());
|
||||
if (other_delegate && other_delegate->m_iter == m_iter && other_delegate->m_iter_trans == m_iter_trans) {
|
||||
return true;
|
||||
} else {
|
||||
return AsIfFlatTexts::equals (other);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
OriginalLayerTexts::less (const Texts &other) const
|
||||
{
|
||||
const OriginalLayerTexts *other_delegate = dynamic_cast<const OriginalLayerTexts *> (other.delegate ());
|
||||
if (other_delegate && other_delegate->m_iter == m_iter && other_delegate->m_iter_trans == m_iter_trans) {
|
||||
return false;
|
||||
} else {
|
||||
return AsIfFlatTexts::less (other);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OriginalLayerTexts::init ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HDR_dbOriginalLayerTexts
|
||||
#define HDR_dbOriginalLayerTexts
|
||||
|
||||
#include "dbCommon.h"
|
||||
|
||||
#include "dbAsIfFlatTexts.h"
|
||||
#include "dbShapes.h"
|
||||
#include "dbRecursiveShapeIterator.h"
|
||||
|
||||
namespace db {
|
||||
|
||||
/**
|
||||
* @brief An original layer text collection based on a RecursiveShapeIterator
|
||||
*/
|
||||
class DB_PUBLIC OriginalLayerTexts
|
||||
: public AsIfFlatTexts
|
||||
{
|
||||
public:
|
||||
OriginalLayerTexts ();
|
||||
OriginalLayerTexts (const OriginalLayerTexts &other);
|
||||
OriginalLayerTexts (const RecursiveShapeIterator &si);
|
||||
OriginalLayerTexts (const RecursiveShapeIterator &si, const db::ICplxTrans &trans);
|
||||
virtual ~OriginalLayerTexts ();
|
||||
|
||||
TextsDelegate *clone () const;
|
||||
|
||||
virtual TextsIteratorDelegate *begin () const;
|
||||
virtual std::pair<db::RecursiveShapeIterator, db::ICplxTrans> begin_iter () const;
|
||||
|
||||
virtual bool empty () const;
|
||||
|
||||
virtual const db::Text *nth (size_t n) const;
|
||||
virtual bool has_valid_texts () const;
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const;
|
||||
|
||||
virtual bool equals (const Texts &other) const;
|
||||
virtual bool less (const Texts &other) const;
|
||||
|
||||
private:
|
||||
OriginalLayerTexts &operator= (const OriginalLayerTexts &other);
|
||||
|
||||
mutable db::RecursiveShapeIterator m_iter;
|
||||
db::ICplxTrans m_iter_trans;
|
||||
|
||||
void init ();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1612,6 +1612,7 @@ public:
|
|||
private:
|
||||
friend class Edges;
|
||||
friend class EdgePairs;
|
||||
friend class Texts;
|
||||
|
||||
RegionDelegate *mp_delegate;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,207 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "dbCommon.h"
|
||||
|
||||
#include "dbTexts.h"
|
||||
#include "dbEmptyTexts.h"
|
||||
#include "dbFlatTexts.h"
|
||||
#include "dbDeepTexts.h"
|
||||
#include "dbOriginalLayerTexts.h"
|
||||
#include "dbEdges.h"
|
||||
#include "dbRegion.h"
|
||||
|
||||
#include "tlVariant.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
Texts::Texts ()
|
||||
: mp_delegate (new EmptyTexts ())
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Texts::~Texts ()
|
||||
{
|
||||
delete mp_delegate;
|
||||
mp_delegate = 0;
|
||||
}
|
||||
|
||||
Texts::Texts (TextsDelegate *delegate)
|
||||
: mp_delegate (delegate)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Texts::Texts (const Texts &other)
|
||||
: gsi::ObjectBase (), mp_delegate (other.mp_delegate->clone ())
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Texts &Texts::operator= (const Texts &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
set_delegate (other.mp_delegate->clone ());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Texts::Texts (const RecursiveShapeIterator &si)
|
||||
{
|
||||
mp_delegate = new OriginalLayerTexts (si);
|
||||
}
|
||||
|
||||
Texts::Texts (const RecursiveShapeIterator &si, const db::ICplxTrans &trans)
|
||||
{
|
||||
mp_delegate = new OriginalLayerTexts (si, trans);
|
||||
}
|
||||
|
||||
Texts::Texts (const RecursiveShapeIterator &si, DeepShapeStore &dss)
|
||||
{
|
||||
mp_delegate = new DeepTexts (si, dss);
|
||||
}
|
||||
|
||||
Texts::Texts (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans)
|
||||
{
|
||||
mp_delegate = new DeepTexts (si, dss, trans);
|
||||
}
|
||||
|
||||
template <class Sh>
|
||||
void Texts::insert (const Sh &shape)
|
||||
{
|
||||
flat_texts ()->insert (shape);
|
||||
}
|
||||
|
||||
template DB_PUBLIC void Texts::insert (const db::Text &);
|
||||
|
||||
void Texts::insert (const db::Shape &shape)
|
||||
{
|
||||
flat_texts ()->insert (shape);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void Texts::insert (const db::Shape &shape, const T &trans)
|
||||
{
|
||||
flat_texts ()->insert (shape, trans);
|
||||
}
|
||||
|
||||
template DB_PUBLIC void Texts::insert (const db::Shape &, const db::ICplxTrans &);
|
||||
template DB_PUBLIC void Texts::insert (const db::Shape &, const db::Trans &);
|
||||
template DB_PUBLIC void Texts::insert (const db::Shape &, const db::Disp &);
|
||||
|
||||
void Texts::clear ()
|
||||
{
|
||||
set_delegate (new EmptyTexts ());
|
||||
}
|
||||
|
||||
void Texts::reserve (size_t n)
|
||||
{
|
||||
flat_texts ()->reserve (n);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Texts &Texts::transform (const T &trans)
|
||||
{
|
||||
flat_texts ()->transform (trans);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// explicit instantiations
|
||||
template DB_PUBLIC Texts &Texts::transform (const db::ICplxTrans &);
|
||||
template DB_PUBLIC Texts &Texts::transform (const db::Trans &);
|
||||
template DB_PUBLIC Texts &Texts::transform (const db::Disp &);
|
||||
|
||||
const db::RecursiveShapeIterator &
|
||||
Texts::iter () const
|
||||
{
|
||||
static db::RecursiveShapeIterator def_iter;
|
||||
const db::RecursiveShapeIterator *i = mp_delegate->iter ();
|
||||
return *(i ? i : &def_iter);
|
||||
}
|
||||
|
||||
void Texts::polygons (Region &output, db::Coord e) const
|
||||
{
|
||||
output.set_delegate (mp_delegate->polygons (e));
|
||||
}
|
||||
|
||||
void Texts::edges (Edges &output) const
|
||||
{
|
||||
output.set_delegate (mp_delegate->edges ());
|
||||
}
|
||||
|
||||
void Texts::set_delegate (TextsDelegate *delegate)
|
||||
{
|
||||
if (delegate != mp_delegate) {
|
||||
delete mp_delegate;
|
||||
mp_delegate = delegate;
|
||||
}
|
||||
}
|
||||
|
||||
FlatTexts *Texts::flat_texts ()
|
||||
{
|
||||
FlatTexts *texts = dynamic_cast<FlatTexts *> (mp_delegate);
|
||||
if (! texts) {
|
||||
texts = new FlatTexts ();
|
||||
if (mp_delegate) {
|
||||
texts->TextsDelegate::operator= (*mp_delegate);
|
||||
texts->insert_seq (begin ());
|
||||
}
|
||||
set_delegate (texts);
|
||||
}
|
||||
|
||||
return texts;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace tl
|
||||
{
|
||||
template<> DB_PUBLIC bool test_extractor_impl (tl::Extractor &ex, db::Texts &b)
|
||||
{
|
||||
db::Text ep;
|
||||
|
||||
if (! ex.try_read (ep)) {
|
||||
return false;
|
||||
}
|
||||
b.insert (ep);
|
||||
|
||||
while (ex.test (";")) {
|
||||
ex.read (ep);
|
||||
b.insert (ep);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<> DB_PUBLIC void extractor_impl (tl::Extractor &ex, db::Texts &b)
|
||||
{
|
||||
if (! test_extractor_impl (ex, b)) {
|
||||
ex.error (tl::to_string (tr ("Expected an edge pair collection specification")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,670 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HDR_dbTexts
|
||||
#define HDR_dbTexts
|
||||
|
||||
#include "dbTextsDelegate.h"
|
||||
#include "dbShape.h"
|
||||
#include "dbRecursiveShapeIterator.h"
|
||||
|
||||
#include "gsiObject.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
class TextFilterBase;
|
||||
class FlatTexts;
|
||||
class EmptyTexts;
|
||||
class Edges;
|
||||
class Region;
|
||||
class DeepShapeStore;
|
||||
class TransformationReducer;
|
||||
|
||||
/**
|
||||
* @brief An text set iterator
|
||||
*
|
||||
* The iterator delivers the texts of the text set
|
||||
*/
|
||||
class DB_PUBLIC TextsIterator
|
||||
{
|
||||
public:
|
||||
typedef TextsIteratorDelegate::value_type value_type;
|
||||
typedef const value_type &reference;
|
||||
typedef const value_type *pointer;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef void difference_type;
|
||||
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*/
|
||||
TextsIterator ()
|
||||
: mp_delegate (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructor from a delegate
|
||||
* The iterator will take ownership over the delegate
|
||||
*/
|
||||
TextsIterator (TextsIteratorDelegate *delegate)
|
||||
: mp_delegate (delegate)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~TextsIterator ()
|
||||
{
|
||||
delete mp_delegate;
|
||||
mp_delegate = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy constructor and assignment
|
||||
*/
|
||||
TextsIterator (const TextsIterator &other)
|
||||
: mp_delegate (0)
|
||||
{
|
||||
operator= (other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assignment
|
||||
*/
|
||||
TextsIterator &operator= (const TextsIterator &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
delete mp_delegate;
|
||||
mp_delegate = other.mp_delegate ? other.mp_delegate->clone () : 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Returns true, if the iterator is at the end
|
||||
*/
|
||||
bool at_end () const
|
||||
{
|
||||
return mp_delegate == 0 || mp_delegate->at_end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Increment
|
||||
*/
|
||||
TextsIterator &operator++ ()
|
||||
{
|
||||
if (mp_delegate) {
|
||||
mp_delegate->increment ();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Access
|
||||
*/
|
||||
reference operator* () const
|
||||
{
|
||||
const value_type *value = operator-> ();
|
||||
tl_assert (value != 0);
|
||||
return *value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Access
|
||||
*/
|
||||
pointer operator-> () const
|
||||
{
|
||||
return mp_delegate ? mp_delegate->get () : 0;
|
||||
}
|
||||
|
||||
private:
|
||||
TextsIteratorDelegate *mp_delegate;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A helper class allowing delivery of addressable texts
|
||||
*
|
||||
* In some applications (i.e. box scanner), texts need to be taken
|
||||
* by address. The text set cannot always deliver adressable edges.
|
||||
* This class help providing this ability by keeping a temporary copy
|
||||
* if required.
|
||||
*/
|
||||
|
||||
class DB_PUBLIC AddressableTextDelivery
|
||||
{
|
||||
public:
|
||||
AddressableTextDelivery ()
|
||||
: m_iter (), m_valid (false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
AddressableTextDelivery (const TextsIterator &iter, bool valid)
|
||||
: m_iter (iter), m_valid (valid)
|
||||
{
|
||||
if (! m_valid && ! m_iter.at_end ()) {
|
||||
m_heap.push_back (*m_iter);
|
||||
}
|
||||
}
|
||||
|
||||
bool at_end () const
|
||||
{
|
||||
return m_iter.at_end ();
|
||||
}
|
||||
|
||||
AddressableTextDelivery &operator++ ()
|
||||
{
|
||||
++m_iter;
|
||||
if (! m_valid && ! m_iter.at_end ()) {
|
||||
m_heap.push_back (*m_iter);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const db::Text *operator-> () const
|
||||
{
|
||||
if (m_valid) {
|
||||
return m_iter.operator-> ();
|
||||
} else {
|
||||
return &m_heap.back ();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
TextsIterator m_iter;
|
||||
bool m_valid;
|
||||
std::list<db::Text> m_heap;
|
||||
};
|
||||
|
||||
class Texts;
|
||||
|
||||
/**
|
||||
* @brief A base class for text filters
|
||||
*/
|
||||
class DB_PUBLIC TextFilterBase
|
||||
{
|
||||
public:
|
||||
TextFilterBase () { }
|
||||
virtual ~TextFilterBase () { }
|
||||
|
||||
virtual bool selected (const db::Text &text) const = 0;
|
||||
virtual const TransformationReducer *vars () const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A set of texts
|
||||
*
|
||||
* Texts are convenient objects describing labels (a point and a text).
|
||||
*
|
||||
* Text sets are created from a text-delivering recursive shape iterator for example. Text sets
|
||||
* can be converted to polygons (representing a small box around the text's point) or to dot-like
|
||||
* edges representing the point of the text.
|
||||
*/
|
||||
class DB_PUBLIC Texts
|
||||
: public gsi::ObjectBase
|
||||
{
|
||||
public:
|
||||
typedef db::Coord coord_type;
|
||||
typedef db::coord_traits<db::Coord> coord_traits;
|
||||
typedef db::Text edge_pair_type;
|
||||
typedef db::Vector vector_type;
|
||||
typedef db::Point point_type;
|
||||
typedef db::Box box_type;
|
||||
typedef coord_traits::distance_type distance_type;
|
||||
typedef TextsIterator const_iterator;
|
||||
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*
|
||||
* This constructor creates an empty text set.
|
||||
*/
|
||||
Texts ();
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~Texts ();
|
||||
|
||||
/**
|
||||
* @brief Constructor from a delegate
|
||||
*
|
||||
* The region will take ownership of the delegate.
|
||||
*/
|
||||
Texts (TextsDelegate *delegate);
|
||||
|
||||
/**
|
||||
* @brief Copy constructor
|
||||
*/
|
||||
Texts (const Texts &other);
|
||||
|
||||
/**
|
||||
* @brief Assignment
|
||||
*/
|
||||
Texts &operator= (const Texts &other);
|
||||
|
||||
/**
|
||||
* @brief Constructor from an object
|
||||
*
|
||||
* Creates an text set representing a single instance of that object
|
||||
*/
|
||||
explicit Texts (const db::Text &s)
|
||||
: mp_delegate (0)
|
||||
{
|
||||
insert (s);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructor from an object
|
||||
*
|
||||
* Creates an text set representing a single instance of that object
|
||||
*/
|
||||
explicit Texts (const db::Shape &s)
|
||||
: mp_delegate (0)
|
||||
{
|
||||
insert (s);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sequence constructor
|
||||
*
|
||||
* Creates an edge set from a sequence of objects. The objects need to be texts.
|
||||
* This version accepts iterators of the begin ... end style.
|
||||
*/
|
||||
template <class Iter>
|
||||
explicit Texts (const Iter &b, const Iter &e)
|
||||
: mp_delegate (0)
|
||||
{
|
||||
reserve (e - b);
|
||||
for (Iter i = b; i != e; ++i) {
|
||||
insert (*i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructor from a RecursiveShapeIterator
|
||||
*
|
||||
* Creates an text set from a recursive shape iterator. This allows one to feed an text set
|
||||
* from a hierarchy of cells.
|
||||
*/
|
||||
explicit Texts (const RecursiveShapeIterator &si);
|
||||
|
||||
/**
|
||||
* @brief Constructor from a RecursiveShapeIterator with a transformation
|
||||
*
|
||||
* Creates an text set from a recursive shape iterator. This allows one to feed an text set
|
||||
* from a hierarchy of cells. The transformation is useful to scale to a specific
|
||||
* DBU for example.
|
||||
*/
|
||||
explicit Texts (const RecursiveShapeIterator &si, const db::ICplxTrans &trans);
|
||||
|
||||
/**
|
||||
* @brief Constructor from a RecursiveShapeIterator providing a deep representation
|
||||
*
|
||||
* This version will create a hierarchical text collection. The DeepShapeStore needs to be provided
|
||||
* during the lifetime of the collection and acts as a heap for optimized data.
|
||||
*/
|
||||
explicit Texts (const RecursiveShapeIterator &si, DeepShapeStore &dss);
|
||||
|
||||
/**
|
||||
* @brief Constructor from a RecursiveShapeIterator providing a deep representation with transformation
|
||||
*/
|
||||
explicit Texts (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans);
|
||||
|
||||
/**
|
||||
* @brief Gets the underlying delegate object
|
||||
*/
|
||||
TextsDelegate *delegate () const
|
||||
{
|
||||
return mp_delegate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterator of the text set
|
||||
*
|
||||
* The iterator delivers the edges of the text set.
|
||||
* It follows the at_end semantics.
|
||||
*/
|
||||
const_iterator begin () const
|
||||
{
|
||||
return TextsIterator (mp_delegate->begin ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delivers a RecursiveShapeIterator pointing to the texts plus the necessary transformation
|
||||
*/
|
||||
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> begin_iter () const
|
||||
{
|
||||
return mp_delegate->begin_iter ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Inserts the given shape (working object) into the text set
|
||||
*/
|
||||
template <class Sh>
|
||||
void insert (const Sh &shape);
|
||||
|
||||
/**
|
||||
* @brief Insert a shape reference into the text set
|
||||
*/
|
||||
void insert (const db::Shape &shape);
|
||||
|
||||
/**
|
||||
* @brief Insert a transformed shape into the text set
|
||||
*/
|
||||
template <class T>
|
||||
void insert (const db::Shape &shape, const T &trans);
|
||||
|
||||
/**
|
||||
* @brief Returns true if the edge pair set is empty
|
||||
*/
|
||||
bool empty () const
|
||||
{
|
||||
return mp_delegate->empty ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the number of texts in the text set
|
||||
*/
|
||||
size_t size () const
|
||||
{
|
||||
return mp_delegate->size ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a string representing the text set
|
||||
*
|
||||
* nmax specifies how many texts are included (set to std::numeric_limits<size_t>::max() for "all".
|
||||
*/
|
||||
std::string to_string (size_t nmax = 10) const
|
||||
{
|
||||
return mp_delegate->to_string (nmax);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears the text set
|
||||
*/
|
||||
void clear ();
|
||||
|
||||
/**
|
||||
* @brief Reserve memory for the given number of texts
|
||||
*/
|
||||
void reserve (size_t n);
|
||||
|
||||
/**
|
||||
* @brief Returns the bounding box of the text set
|
||||
*/
|
||||
Box bbox () const
|
||||
{
|
||||
return mp_delegate->bbox ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Filters the texts
|
||||
*
|
||||
* This method will keep all texts for which the filter returns true.
|
||||
*/
|
||||
Texts &filter (const TextFilterBase &filter)
|
||||
{
|
||||
set_delegate (mp_delegate->filter_in_place (filter));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the filtered texts
|
||||
*
|
||||
* This method will return a new text set with only those texts which
|
||||
* conform to the filter criterion.
|
||||
*/
|
||||
Texts filtered (const TextFilterBase &filter) const
|
||||
{
|
||||
return Texts (mp_delegate->filtered (filter));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transforms the text set
|
||||
*/
|
||||
template <class T>
|
||||
Texts &transform (const T &trans);
|
||||
|
||||
/**
|
||||
* @brief Returns the transformed text set
|
||||
*/
|
||||
template <class T>
|
||||
Texts transformed (const T &trans) const
|
||||
{
|
||||
Texts d (*this);
|
||||
d.transform (trans);
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Swaps with the other text set
|
||||
*/
|
||||
void swap (db::Texts &other)
|
||||
{
|
||||
std::swap (other.mp_delegate, mp_delegate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Joining of text set
|
||||
*
|
||||
* This method joins the text sets.
|
||||
*/
|
||||
Texts operator+ (const Texts &other) const
|
||||
{
|
||||
return Texts (mp_delegate->add (other));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief In-place text set joining
|
||||
*/
|
||||
Texts &operator+= (const Texts &other)
|
||||
{
|
||||
set_delegate (mp_delegate->add_in_place (other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns all texts which are in the other text set
|
||||
*
|
||||
* This method will return all texts which are part of another text set.
|
||||
* The match is done exactly.
|
||||
* The "invert" flag can be used to invert the sense, i.e. with
|
||||
* "invert" set to true, this method will return all texts not
|
||||
* in the other text set.
|
||||
*/
|
||||
Texts in (const Texts &other, bool invert = false) const
|
||||
{
|
||||
return Texts (mp_delegate->in (other, invert));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the nth text
|
||||
*
|
||||
* This operation is available only for flat regions - i.e. such for which
|
||||
* "has_valid_texts" is true.
|
||||
*/
|
||||
const db::Text *nth (size_t n) const
|
||||
{
|
||||
return mp_delegate->nth (n);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Forces flattening of the text collection
|
||||
*
|
||||
* This method will turn any edge pair collection into a flat one.
|
||||
*/
|
||||
void flatten ()
|
||||
{
|
||||
flat_texts ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the text set has valid texts stored within itself
|
||||
*
|
||||
* If the region has valid texts, it is permissable to use the text's addresses
|
||||
* from the iterator. Furthermore, the random access operator nth() is available.
|
||||
*/
|
||||
bool has_valid_texts () const
|
||||
{
|
||||
return mp_delegate->has_valid_texts ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns an addressable delivery for texts
|
||||
*
|
||||
* This object allows accessing the texts by address, even if they
|
||||
* are not delivered from a container. The magic is a heap object
|
||||
* inside the delivery object. Hence, the deliver object must persist
|
||||
* as long as the addresses are required.
|
||||
*/
|
||||
AddressableTextDelivery addressable_texts () const
|
||||
{
|
||||
return AddressableTextDelivery (begin (), has_valid_texts ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the internal iterator
|
||||
*
|
||||
* This method is intended for users who know what they are doing
|
||||
*/
|
||||
const db::RecursiveShapeIterator &iter () const;
|
||||
|
||||
/**
|
||||
* @brief Equality
|
||||
*/
|
||||
bool operator== (const db::Texts &other) const
|
||||
{
|
||||
return mp_delegate->equals (other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Inequality
|
||||
*/
|
||||
bool operator!= (const db::Texts &other) const
|
||||
{
|
||||
return ! mp_delegate->equals (other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Less operator
|
||||
*/
|
||||
bool operator< (const db::Texts &other) const
|
||||
{
|
||||
return mp_delegate->less (other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts to polygons
|
||||
*
|
||||
* Note: because of the include hierarchy we can't use a direct return value.
|
||||
*
|
||||
* The output container is not cleared by this method but polygons are rather
|
||||
* appended.
|
||||
*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @brief Returns individual, dot-like edges
|
||||
*
|
||||
* Note: because of the include hierarchy we can't use a direct return value.
|
||||
*
|
||||
* The returned edges will be dot-like (identical points) and represent the
|
||||
* position of the text.
|
||||
*/
|
||||
void edges (Edges &output) const;
|
||||
|
||||
/**
|
||||
* @brief Enable progress reporting
|
||||
*
|
||||
* @param progress_text The description text of the progress object
|
||||
*/
|
||||
void enable_progress (const std::string &progress_desc = std::string ())
|
||||
{
|
||||
mp_delegate->enable_progress (progress_desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable progress reporting
|
||||
*/
|
||||
void disable_progress ()
|
||||
{
|
||||
mp_delegate->disable_progress ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Inserts the edge pair collection into the given layout, cell and layer
|
||||
* If the text collection is a hierarchical region, the hierarchy is copied into the
|
||||
* layout's hierarchy.
|
||||
*/
|
||||
void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const
|
||||
{
|
||||
return mp_delegate->insert_into (layout, into_cell, into_layer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Inserts the edge pair collection into the given layout, cell and layer as polygons with the given enlargement
|
||||
* If the text collection is a hierarchical region, the hierarchy is copied into the
|
||||
* layout's hierarchy.
|
||||
*/
|
||||
void insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const
|
||||
{
|
||||
return mp_delegate->insert_into_as_polygons (layout, into_cell, into_layer, enl);
|
||||
}
|
||||
|
||||
private:
|
||||
TextsDelegate *mp_delegate;
|
||||
|
||||
void set_delegate (TextsDelegate *delegate);
|
||||
FlatTexts *flat_texts ();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace tl
|
||||
{
|
||||
/**
|
||||
* @brief The type traits for the box type
|
||||
*/
|
||||
template <>
|
||||
struct type_traits <db::Texts> : public type_traits<void>
|
||||
{
|
||||
typedef true_tag supports_extractor;
|
||||
typedef true_tag supports_to_string;
|
||||
typedef true_tag has_less_operator;
|
||||
typedef true_tag has_equal_operator;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "dbTextsDelegate.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------
|
||||
|
||||
TextsDelegate::TextsDelegate ()
|
||||
{
|
||||
m_report_progress = false;
|
||||
}
|
||||
|
||||
TextsDelegate::TextsDelegate (const TextsDelegate &other)
|
||||
: tl::UniqueId ()
|
||||
{
|
||||
operator= (other);
|
||||
}
|
||||
|
||||
TextsDelegate &
|
||||
TextsDelegate::operator= (const TextsDelegate &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
m_report_progress = other.m_report_progress;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
TextsDelegate::~TextsDelegate ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void TextsDelegate::enable_progress (const std::string &progress_desc)
|
||||
{
|
||||
m_report_progress = true;
|
||||
m_progress_desc = progress_desc;
|
||||
}
|
||||
|
||||
void TextsDelegate::disable_progress ()
|
||||
{
|
||||
m_report_progress = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HDR_dbTextsDelegate
|
||||
#define HDR_dbTextsDelegate
|
||||
|
||||
#include "dbCommon.h"
|
||||
|
||||
#include "dbText.h"
|
||||
#include "tlUniqueId.h"
|
||||
|
||||
namespace db {
|
||||
|
||||
class RecursiveShapeIterator;
|
||||
class Texts;
|
||||
class TextFilterBase;
|
||||
class RegionDelegate;
|
||||
class EdgesDelegate;
|
||||
class Layout;
|
||||
|
||||
/**
|
||||
* @brief The edge pair set iterator delegate
|
||||
*/
|
||||
class DB_PUBLIC TextsIteratorDelegate
|
||||
{
|
||||
public:
|
||||
TextsIteratorDelegate () { }
|
||||
virtual ~TextsIteratorDelegate () { }
|
||||
|
||||
typedef db::Text value_type;
|
||||
|
||||
virtual bool at_end () const = 0;
|
||||
virtual void increment () = 0;
|
||||
virtual const value_type *get () const = 0;
|
||||
virtual TextsIteratorDelegate *clone () const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The delegate for the actual edge set implementation
|
||||
*/
|
||||
class DB_PUBLIC TextsDelegate
|
||||
: public tl::UniqueId
|
||||
{
|
||||
public:
|
||||
typedef db::Coord coord_type;
|
||||
typedef db::coord_traits<db::Coord> coord_traits;
|
||||
typedef db::Text edge_pair_type;
|
||||
typedef db::Vector vector_type;
|
||||
typedef db::Point point_type;
|
||||
typedef db::Box box_type;
|
||||
|
||||
TextsDelegate ();
|
||||
virtual ~TextsDelegate ();
|
||||
|
||||
TextsDelegate (const TextsDelegate &other);
|
||||
TextsDelegate &operator= (const TextsDelegate &other);
|
||||
|
||||
virtual TextsDelegate *clone () const = 0;
|
||||
|
||||
void enable_progress (const std::string &progress_desc);
|
||||
void disable_progress ();
|
||||
|
||||
// dummy features to harmonize the interface of region, edges and edge pair delegates
|
||||
void set_merged_semantics (bool) { }
|
||||
bool merged_semantics () const { return false; }
|
||||
void set_is_merged (bool) { }
|
||||
bool is_merged () const { return false; }
|
||||
|
||||
virtual std::string to_string (size_t nmax) const = 0;
|
||||
|
||||
virtual TextsIteratorDelegate *begin () const = 0;
|
||||
virtual std::pair<db::RecursiveShapeIterator, db::ICplxTrans> begin_iter () const = 0;
|
||||
|
||||
virtual bool empty () const = 0;
|
||||
virtual size_t size () const = 0;
|
||||
|
||||
virtual Box bbox () const = 0;
|
||||
|
||||
virtual TextsDelegate *filter_in_place (const TextFilterBase &filter) = 0;
|
||||
virtual TextsDelegate *filtered (const TextFilterBase &filter) const = 0;
|
||||
|
||||
virtual RegionDelegate *polygons (db::Coord e) const = 0;
|
||||
virtual EdgesDelegate *edges () const = 0;
|
||||
|
||||
virtual TextsDelegate *add_in_place (const Texts &other) = 0;
|
||||
virtual TextsDelegate *add (const Texts &other) const = 0;
|
||||
|
||||
virtual TextsDelegate *in (const Texts &other, bool invert) const = 0;
|
||||
|
||||
virtual const db::Text *nth (size_t n) const = 0;
|
||||
virtual bool has_valid_texts () const = 0;
|
||||
|
||||
virtual const db::RecursiveShapeIterator *iter () const = 0;
|
||||
|
||||
virtual bool equals (const Texts &other) const = 0;
|
||||
virtual bool less (const Texts &other) const = 0;
|
||||
|
||||
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const = 0;
|
||||
virtual void insert_into_as_polygons (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer, db::Coord enl) const = 0;
|
||||
|
||||
protected:
|
||||
const std::string &progress_desc () const
|
||||
{
|
||||
return m_progress_desc;
|
||||
}
|
||||
|
||||
bool report_progress () const
|
||||
{
|
||||
return m_report_progress;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_report_progress;
|
||||
std::string m_progress_desc;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include "dbTextsUtils.h"
|
||||
#include "dbRegion.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
// .. nothing yet ..
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef HDR_dbTextsUtils
|
||||
#define HDR_dbTextsUtils
|
||||
|
||||
#include "dbCommon.h"
|
||||
#include "dbTexts.h"
|
||||
#include "tlGlobPattern.h"
|
||||
|
||||
namespace db {
|
||||
|
||||
/**
|
||||
* @brief An text filter filtering by a string
|
||||
*
|
||||
* It will filter all texts for which the string is equal to "text".
|
||||
* There is an "invert" flag which allows selecting all texts not
|
||||
* matching the criterion.
|
||||
*/
|
||||
|
||||
struct DB_PUBLIC TextStringFilter
|
||||
: public TextFilterBase
|
||||
{
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param text The text string to match
|
||||
* @param inverse If set to true, only polygons not matching this criterion will be filtered
|
||||
*/
|
||||
TextStringFilter (const std::string &text, bool inverse)
|
||||
: m_text (text), m_inverse (inverse)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the text matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Text &text) const
|
||||
{
|
||||
return (text.string () == m_text) != m_inverse;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This filter is not sensitive to hierarchy
|
||||
*/
|
||||
virtual const TransformationReducer *vars () const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Requires merged input
|
||||
*/
|
||||
virtual bool requires_raw_input () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wants to build variants
|
||||
*/
|
||||
virtual bool wants_variants () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_text;
|
||||
bool m_inverse;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An text filter filtering by a glob-style pattern
|
||||
*
|
||||
* It will filter all texts for which the string matches the given glob-style pattern.
|
||||
* There is an "invert" flag which allows selecting all texts not
|
||||
* matching the criterion.
|
||||
*/
|
||||
|
||||
struct DB_PUBLIC TextPatternFilter
|
||||
: public TextFilterBase
|
||||
{
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param text The text pattern to match
|
||||
* @param inverse If set to true, only polygons not matching this criterion will be filtered
|
||||
*/
|
||||
TextPatternFilter (const std::string &text, bool inverse)
|
||||
: m_pattern (text), m_inverse (inverse)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the text matches the criterion
|
||||
*/
|
||||
virtual bool selected (const db::Text &text) const
|
||||
{
|
||||
return m_pattern.match (text.string ()) != m_inverse;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This filter is not sensitive to hierarchy
|
||||
*/
|
||||
virtual const TransformationReducer *vars () const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Requires merged input
|
||||
*/
|
||||
virtual bool requires_raw_input () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wants to build variants
|
||||
*/
|
||||
virtual bool wants_variants () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
tl::GlobPattern m_pattern;
|
||||
bool m_inverse;
|
||||
};
|
||||
|
||||
} // namespace db
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,470 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "gsiDecl.h"
|
||||
|
||||
#include "dbTexts.h"
|
||||
#include "dbRegion.h"
|
||||
#include "dbDeepTexts.h"
|
||||
#include "dbTextsUtils.h"
|
||||
|
||||
namespace gsi
|
||||
{
|
||||
|
||||
static db::Texts *new_v ()
|
||||
{
|
||||
return new db::Texts ();
|
||||
}
|
||||
|
||||
static db::Texts *new_a (const std::vector<db::Text> &t)
|
||||
{
|
||||
return new db::Texts (t.begin (), t.end ());
|
||||
}
|
||||
|
||||
static db::Texts *new_text (const db::Text &t)
|
||||
{
|
||||
return new db::Texts (t);
|
||||
}
|
||||
|
||||
static db::Texts *new_shapes (const db::Shapes &s)
|
||||
{
|
||||
db::Texts *r = new db::Texts ();
|
||||
for (db::Shapes::shape_iterator i = s.begin (db::ShapeIterator::Texts); !i.at_end (); ++i) {
|
||||
r->insert (*i);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static db::Texts *new_si (const db::RecursiveShapeIterator &si)
|
||||
{
|
||||
return new db::Texts (si);
|
||||
}
|
||||
|
||||
static db::Texts *new_si2 (const db::RecursiveShapeIterator &si, const db::ICplxTrans &trans)
|
||||
{
|
||||
return new db::Texts (si, trans);
|
||||
}
|
||||
|
||||
static db::Texts *new_sid (const db::RecursiveShapeIterator &si, db::DeepShapeStore &dss)
|
||||
{
|
||||
return new db::Texts (si, dss);
|
||||
}
|
||||
|
||||
static db::Texts *new_si2d (const db::RecursiveShapeIterator &si, db::DeepShapeStore &dss, const db::ICplxTrans &trans)
|
||||
{
|
||||
return new db::Texts (si, dss, trans);
|
||||
}
|
||||
|
||||
static std::string to_string0 (const db::Texts *r)
|
||||
{
|
||||
return r->to_string ();
|
||||
}
|
||||
|
||||
static std::string to_string1 (const db::Texts *r, size_t n)
|
||||
{
|
||||
return r->to_string (n);
|
||||
}
|
||||
|
||||
static db::Texts &move_p (db::Texts *r, const db::Vector &p)
|
||||
{
|
||||
r->transform (db::Disp (p));
|
||||
return *r;
|
||||
}
|
||||
|
||||
static db::Texts &move_xy (db::Texts *r, db::Coord x, db::Coord y)
|
||||
{
|
||||
r->transform (db::Disp (db::Vector (x, y)));
|
||||
return *r;
|
||||
}
|
||||
|
||||
static db::Texts moved_p (const db::Texts *r, const db::Vector &p)
|
||||
{
|
||||
return r->transformed (db::Disp (p));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
db::Region r;
|
||||
e->polygons (r, d);
|
||||
return r;
|
||||
}
|
||||
|
||||
static db::Region extents1 (const db::Texts *r, db::Coord dx, db::Coord dy)
|
||||
{
|
||||
db::Region e;
|
||||
e.reserve (r->size ());
|
||||
for (db::Texts::const_iterator i = r->begin (); ! i.at_end (); ++i) {
|
||||
e.insert (i->box ().enlarged (db::Vector (dx, dy)));
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
static db::Region extents0 (const db::Texts *r, db::Coord d)
|
||||
{
|
||||
return extents1 (r, d, d);
|
||||
}
|
||||
|
||||
static db::Edges edges (const db::Texts *ep)
|
||||
{
|
||||
db::Edges e;
|
||||
ep->edges (e);
|
||||
return e;
|
||||
}
|
||||
|
||||
static void insert_t (db::Texts *t, const db::Texts &a)
|
||||
{
|
||||
for (db::Texts::const_iterator p = a.begin (); ! p.at_end (); ++p) {
|
||||
t->insert (*p);
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_deep (const db::Texts *t)
|
||||
{
|
||||
return dynamic_cast<const db::DeepTexts *> (t->delegate ()) != 0;
|
||||
}
|
||||
|
||||
static size_t id (const db::Texts *t)
|
||||
{
|
||||
return tl::id_of (t->delegate ());
|
||||
}
|
||||
|
||||
static db::Texts with_text (const db::Texts *r, const std::string &text, bool inverse)
|
||||
{
|
||||
db::TextStringFilter f (text, inverse);
|
||||
return r->filtered (f);
|
||||
}
|
||||
|
||||
static db::Texts with_pattern (const db::Texts *r, const std::string &pattern, bool inverse)
|
||||
{
|
||||
db::TextPatternFilter f (pattern, inverse);
|
||||
return r->filtered (f);
|
||||
}
|
||||
|
||||
Class<db::Texts> decl_Texts ("db", "Texts",
|
||||
constructor ("new", &new_v,
|
||||
"@brief Default constructor\n"
|
||||
"\n"
|
||||
"This constructor creates an empty text collection.\n"
|
||||
) +
|
||||
constructor ("new", &new_a, gsi::arg ("array"),
|
||||
"@brief Constructor from an text array\n"
|
||||
"\n"
|
||||
"This constructor creates an text collection from an array of \\Text objects.\n"
|
||||
) +
|
||||
constructor ("new", &new_text, gsi::arg ("text"),
|
||||
"@brief Constructor from a single edge pair object\n"
|
||||
"\n"
|
||||
"This constructor creates an text collection with a single text.\n"
|
||||
) +
|
||||
constructor ("new", &new_shapes, gsi::arg ("shapes"),
|
||||
"@brief Shapes constructor\n"
|
||||
"\n"
|
||||
"This constructor creates an text collection from a \\Shapes collection.\n"
|
||||
) +
|
||||
constructor ("new", &new_si, gsi::arg ("shape_iterator"),
|
||||
"@brief Constructor from a hierarchical shape set\n"
|
||||
"\n"
|
||||
"This constructor creates a text collection from the shapes delivered by the given recursive shape iterator.\n"
|
||||
"Only texts are taken from the shape set and other shapes are ignored.\n"
|
||||
"This method allows feeding the text collection from a hierarchy of cells.\n"
|
||||
"\n"
|
||||
"@code\n"
|
||||
"layout = ... # a layout\n"
|
||||
"cell = ... # the index of the initial cell\n"
|
||||
"layer = ... # the index of the layer from where to take the shapes from\n"
|
||||
"r = RBA::Texts::new(layout.begin_shapes(cell, layer))\n"
|
||||
"@/code\n"
|
||||
) +
|
||||
constructor ("new", &new_si2, gsi::arg ("shape_iterator"), gsi::arg ("trans"),
|
||||
"@brief Constructor from a hierarchical shape set with a transformation\n"
|
||||
"\n"
|
||||
"This constructor creates a text collection from the shapes delivered by the given recursive shape iterator.\n"
|
||||
"Only texts are taken from the shape set and other shapes are ignored.\n"
|
||||
"The given transformation is applied to each text taken.\n"
|
||||
"This method allows feeding the text collection from a hierarchy of cells.\n"
|
||||
"The transformation is useful to scale to a specific database unit for example.\n"
|
||||
"\n"
|
||||
"@code\n"
|
||||
"layout = ... # a layout\n"
|
||||
"cell = ... # the index of the initial cell\n"
|
||||
"layer = ... # the index of the layer from where to take the shapes from\n"
|
||||
"dbu = 0.1 # the target database unit\n"
|
||||
"r = RBA::Texts::new(layout.begin_shapes(cell, layer), RBA::ICplxTrans::new(layout.dbu / dbu))\n"
|
||||
"@/code\n"
|
||||
) +
|
||||
constructor ("new", &new_sid, gsi::arg ("shape_iterator"), gsi::arg ("dss"),
|
||||
"@brief Creates a hierarchical text collection from an original layer\n"
|
||||
"\n"
|
||||
"This constructor creates a text collection from the shapes delivered by the given recursive shape iterator.\n"
|
||||
"This version will create a hierarchical text collection which supports hierarchical operations.\n"
|
||||
"\n"
|
||||
"@code\n"
|
||||
"dss = RBA::DeepShapeStore::new\n"
|
||||
"layout = ... # a layout\n"
|
||||
"cell = ... # the index of the initial cell\n"
|
||||
"layer = ... # the index of the layer from where to take the shapes from\n"
|
||||
"r = RBA::Texts::new(layout.begin_shapes(cell, layer))\n"
|
||||
"@/code\n"
|
||||
) +
|
||||
constructor ("new", &new_si2d, gsi::arg ("shape_iterator"), gsi::arg ("dss"), gsi::arg ("trans"),
|
||||
"@brief Creates a hierarchical text collection from an original layer with a transformation\n"
|
||||
"\n"
|
||||
"This constructor creates a text collection from the shapes delivered by the given recursive shape iterator.\n"
|
||||
"This version will create a hierarchical text collection which supports hierarchical operations.\n"
|
||||
"The transformation is useful to scale to a specific database unit for example.\n"
|
||||
"\n"
|
||||
"@code\n"
|
||||
"dss = RBA::DeepShapeStore::new\n"
|
||||
"layout = ... # a layout\n"
|
||||
"cell = ... # the index of the initial cell\n"
|
||||
"layer = ... # the index of the layer from where to take the shapes from\n"
|
||||
"dbu = 0.1 # the target database unit\n"
|
||||
"r = RBA::Texts::new(layout.begin_shapes(cell, layer), RBA::ICplxTrans::new(layout.dbu / dbu))\n"
|
||||
"@/code\n"
|
||||
) +
|
||||
method ("insert_into", &db::Texts::insert_into, gsi::arg ("layout"), gsi::arg ("cell_index"), gsi::arg ("layer"),
|
||||
"@brief Inserts this texts into the given layout, below the given cell and into the given layer.\n"
|
||||
"If the text collection is a hierarchical one, a suitable hierarchy will be built below the top cell or "
|
||||
"and existing hierarchy will be reused.\n"
|
||||
) +
|
||||
method ("insert_into_as_polygons", &db::Texts::insert_into_as_polygons, gsi::arg ("layout"), gsi::arg ("cell_index"), gsi::arg ("layer"), gsi::arg ("e"),
|
||||
"@brief Inserts this texts into the given layout, below the given cell and into the given layer.\n"
|
||||
"If the text collection is a hierarchical one, a suitable hierarchy will be built below the top cell or "
|
||||
"and existing hierarchy will be reused.\n"
|
||||
"\n"
|
||||
"The texts will be converted to polygons with the enlargement value given be 'e'. See \\polygon or \\extents for details.\n"
|
||||
) +
|
||||
method ("insert", (void (db::Texts::*) (const db::Text &)) &db::Texts::insert, gsi::arg ("text"),
|
||||
"@brief Inserts a text into the collection\n"
|
||||
) +
|
||||
method_ext ("is_deep?", &is_deep,
|
||||
"@brief Returns true if the edge pair collection is a deep (hierarchical) one\n"
|
||||
) +
|
||||
method_ext ("data_id", &id,
|
||||
"@brief Returns the data ID (a unique identifier for the underlying data storage)\n"
|
||||
) +
|
||||
method ("+", &db::Texts::operator+, gsi::arg ("other"),
|
||||
"@brief Returns the combined text collection of self and the other one\n"
|
||||
"\n"
|
||||
"@return The resulting text collection\n"
|
||||
"\n"
|
||||
"This operator adds the texts of the other collection to self and returns a new combined set.\n"
|
||||
) +
|
||||
method ("+=", &db::Texts::operator+=, gsi::arg ("other"),
|
||||
"@brief Adds the texts of the other text collection to self\n"
|
||||
"\n"
|
||||
"@return The text collection after modification (self)\n"
|
||||
"\n"
|
||||
"This operator adds the texts of the other collection to self.\n"
|
||||
) +
|
||||
method_ext ("move", &move_p, gsi::arg ("p"),
|
||||
"@brief Moves the text collection\n"
|
||||
"\n"
|
||||
"Moves the texts by the given offset and returns the \n"
|
||||
"moved text collection. The text collection is overwritten.\n"
|
||||
"\n"
|
||||
"@param p The distance to move the texts.\n"
|
||||
"\n"
|
||||
"@return The moved texts (self).\n"
|
||||
) +
|
||||
method_ext ("move", &move_xy, gsi::arg ("x"), gsi::arg ("y"),
|
||||
"@brief Moves the text collection\n"
|
||||
"\n"
|
||||
"Moves the edge pairs by the given offset and returns the \n"
|
||||
"moved texts. The edge pair collection is overwritten.\n"
|
||||
"\n"
|
||||
"@param x The x distance to move the texts.\n"
|
||||
"@param y The y distance to move the texts.\n"
|
||||
"\n"
|
||||
"@return The moved texts (self).\n"
|
||||
) +
|
||||
method_ext ("moved", &moved_p, gsi::arg ("p"),
|
||||
"@brief Returns the moved text collection (does not modify self)\n"
|
||||
"\n"
|
||||
"Moves the texts by the given offset and returns the \n"
|
||||
"moved texts. The text collection is not modified.\n"
|
||||
"\n"
|
||||
"@param p The distance to move the texts.\n"
|
||||
"\n"
|
||||
"@return The moved texts.\n"
|
||||
) +
|
||||
method_ext ("moved", &moved_xy, gsi::arg ("x"), gsi::arg ("y"),
|
||||
"@brief Returns the moved edge pair collection (does not modify self)\n"
|
||||
"\n"
|
||||
"Moves the texts by the given offset and returns the \n"
|
||||
"moved texts. The text collection is not modified.\n"
|
||||
"\n"
|
||||
"@param x The x distance to move the texts.\n"
|
||||
"@param y The y distance to move the texts.\n"
|
||||
"\n"
|
||||
"@return The moved texts.\n"
|
||||
) +
|
||||
method ("transformed", (db::Texts (db::Texts::*)(const db::Trans &) const) &db::Texts::transformed, gsi::arg ("t"),
|
||||
"@brief Transform the edge pair collection\n"
|
||||
"\n"
|
||||
"Transforms the texts with the given transformation.\n"
|
||||
"Does not modify the edge pair collection but returns the transformed texts.\n"
|
||||
"\n"
|
||||
"@param t The transformation to apply.\n"
|
||||
"\n"
|
||||
"@return The transformed texts.\n"
|
||||
) +
|
||||
method ("transformed|#transformed_icplx", (db::Texts (db::Texts::*)(const db::ICplxTrans &) const) &db::Texts::transformed, gsi::arg ("t"),
|
||||
"@brief Transform the text collection with a complex transformation\n"
|
||||
"\n"
|
||||
"Transforms the text with the given complex transformation.\n"
|
||||
"Does not modify the text collection but returns the transformed texts.\n"
|
||||
"\n"
|
||||
"@param t The transformation to apply.\n"
|
||||
"\n"
|
||||
"@return The transformed texts.\n"
|
||||
) +
|
||||
method ("transform", (db::Texts &(db::Texts::*)(const db::Trans &)) &db::Texts::transform, gsi::arg ("t"),
|
||||
"@brief Transform the text collection (modifies self)\n"
|
||||
"\n"
|
||||
"Transforms the text collection with the given transformation.\n"
|
||||
"This version modifies the text collection and returns a reference to self.\n"
|
||||
"\n"
|
||||
"@param t The transformation to apply.\n"
|
||||
"\n"
|
||||
"@return The transformed text collection.\n"
|
||||
) +
|
||||
method ("transform|#transform_icplx", (db::Texts &(db::Texts::*)(const db::ICplxTrans &)) &db::Texts::transform, gsi::arg ("t"),
|
||||
"@brief Transform the text collection with a complex transformation (modifies self)\n"
|
||||
"\n"
|
||||
"Transforms the text collection with the given transformation.\n"
|
||||
"This version modifies the text collection and returns a reference to self.\n"
|
||||
"\n"
|
||||
"@param t The transformation to apply.\n"
|
||||
"\n"
|
||||
"@return The transformed text collection.\n"
|
||||
) +
|
||||
method_ext ("insert", &insert_t, gsi::arg ("texts"),
|
||||
"@brief Inserts all texts from the other text collection into this collection\n"
|
||||
) +
|
||||
method_ext ("edges", &edges,
|
||||
"@brief Returns dot-like edges for the texts\n"
|
||||
"@return An edge collection containing the individual, dot-like edges\n"
|
||||
) +
|
||||
method_ext ("extents", &extents0, gsi::arg ("d", db::Coord (1)),
|
||||
"@brief Returns a region with the enlarged bounding boxes of the texts\n"
|
||||
"Text bounding boxes are point-like boxes which vanish unless an enlargement of >0 is specified.\n"
|
||||
"The bounding box is centered at the text's location.\n"
|
||||
"The boxes will not be merged, so it is possible to determine overlaps "
|
||||
"of these boxes for example.\n"
|
||||
) +
|
||||
method_ext ("extents", &extents1, gsi::arg ("dx"), gsi::arg ("dy"),
|
||||
"@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)),
|
||||
"@brief Converts the edge pairs to polygons\n"
|
||||
"This method creates polygons from the texts. This is equivalent to calling \\extents."
|
||||
) +
|
||||
method_ext ("with_text", with_text, gsi::arg ("text"), gsi::arg ("inverse"),
|
||||
"@brief Filter the text by text string\n"
|
||||
"If \"inverse\" is false, this method returns the texts with the given string.\n"
|
||||
"If \"inverse\" is true, this method returns the texts not having the given string.\n"
|
||||
) +
|
||||
method_ext ("with_match", with_pattern, gsi::arg ("pattern"), gsi::arg ("inverse"),
|
||||
"@brief Filter the text by glob pattern\n"
|
||||
"\"pattern\" is a glob-style pattern (e.g. \"A*\" will select all texts starting with a capital \"A\").\n"
|
||||
"If \"inverse\" is false, this method returns the texts matching the pattern.\n"
|
||||
"If \"inverse\" is true, this method returns the texts not matching the pattern.\n"
|
||||
) +
|
||||
method ("clear", &db::Texts::clear,
|
||||
"@brief Clears the text collection\n"
|
||||
) +
|
||||
method ("swap", &db::Texts::swap, gsi::arg ("other"),
|
||||
"@brief Swap the contents of this collection with the contents of another collection\n"
|
||||
"This method is useful to avoid excessive memory allocation in some cases. "
|
||||
"For managed memory languages such as Ruby, those cases will be rare. "
|
||||
) +
|
||||
method ("bbox", &db::Texts::bbox,
|
||||
"@brief Return the bounding box of the text collection\n"
|
||||
"The bounding box is the box enclosing all origins of all texts.\n"
|
||||
) +
|
||||
method ("is_empty?", &db::Texts::empty,
|
||||
"@brief Returns true if the collection is empty\n"
|
||||
) +
|
||||
method ("size", &db::Texts::size,
|
||||
"@brief Returns the number of texts in this collection\n"
|
||||
) +
|
||||
gsi::iterator ("each", &db::Texts::begin,
|
||||
"@brief Returns each text of the text collection\n"
|
||||
) +
|
||||
method ("[]", &db::Texts::nth, gsi::arg ("n"),
|
||||
"@brief Returns the nth text\n"
|
||||
"\n"
|
||||
"This method returns nil if the index is out of range. It is available for flat texts only - i.e. "
|
||||
"those for which \\has_valid_texts? is true. Use \\flatten to explicitly flatten an text collection.\n"
|
||||
"\n"
|
||||
"The \\each iterator is the more general approach to access the texts."
|
||||
) +
|
||||
method ("flatten", &db::Texts::flatten,
|
||||
"@brief Explicitly flattens an text collection\n"
|
||||
"\n"
|
||||
"If the collection is already flat (i.e. \\has_valid_texts? returns true), this method will "
|
||||
"not change the collection.\n"
|
||||
) +
|
||||
method ("has_valid_texts?", &db::Texts::has_valid_texts,
|
||||
"@brief Returns true if the text collection is flat and individual texts can be accessed randomly\n"
|
||||
) +
|
||||
method ("enable_progress", &db::Texts::enable_progress, gsi::arg ("label"),
|
||||
"@brief Enable progress reporting\n"
|
||||
"After calling this method, the text collection will report the progress through a progress bar while "
|
||||
"expensive operations are running.\n"
|
||||
"The label is a text which is put in front of the progress bar.\n"
|
||||
"Using a progress bar will imply a performance penalty of a few percent typically.\n"
|
||||
) +
|
||||
method ("disable_progress", &db::Texts::disable_progress,
|
||||
"@brief Disable progress reporting\n"
|
||||
"Calling this method will disable progress reporting. See \\enable_progress.\n"
|
||||
) +
|
||||
method_ext ("to_s", &to_string0,
|
||||
"@brief Converts the text collection to a string\n"
|
||||
"The length of the output is limited to 20 edge pairs to avoid giant strings on large collections. "
|
||||
"For full output use \"to_s\" with a maximum count parameter.\n"
|
||||
) +
|
||||
method_ext ("to_s", &to_string1, gsi::arg ("max_count"),
|
||||
"@brief Converts the text collection to a string\n"
|
||||
"This version allows specification of the maximum number of texts contained in the string."
|
||||
),
|
||||
"@brief Texts (a collection of texts)\n"
|
||||
"\n"
|
||||
"Text objects are useful as labels for net names, to identify certain regions and to specify specific locations in general. "
|
||||
"Text collections provide a way to store - also in a hierarchical fashion - and manipulate collection of text objects. "
|
||||
"Text objects can be turned into polygons by creating small boxes around the texts. Texts can also be turned into dot-like "
|
||||
"edges. Texts can be filtered by string, either by matching against a fixed string or a glob-style pattern.\n"
|
||||
"\n"
|
||||
"Beside that, text collections can be transformed and combined, similar to \\EdgePairs.\n"
|
||||
"\n"
|
||||
"This class has been introduced in version 0.27.\n"
|
||||
);
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue