Some enhancements for DRC

- modified definition of texts with the ability to produce
  point-like edge objects
- middle and extent_refs methods for center point and other
  references.
This commit is contained in:
Matthias Koefferlein 2017-07-13 23:38:36 +02:00
parent 4ad20fa4ce
commit cf6aef46e5
26 changed files with 661 additions and 68 deletions

View File

@ -571,3 +571,42 @@ gen = Gen::new
run_demo gen, "input.rounded_corners(1.um, 2.um, 16)", "drc_rounded_corners.png"
class Gen
def produce(s1, s2)
pts = [
RBA::Point::new(1000, 0),
RBA::Point::new(1000, 2000),
RBA::Point::new(4000, 2000),
RBA::Point::new(4000, 5000),
RBA::Point::new(1000, 5000),
RBA::Point::new(1000, 7000),
RBA::Point::new(5000, 7000),
RBA::Point::new(5000, 0)
];
s1.insert(RBA::Polygon::new(pts))
end
end
gen = Gen::new
run_demo gen, "input.middle.sized(0.1)", "drc_middle1.png"
run_demo gen, "input.extent_refs(:center).sized(0.1)", "drc_extent_refs1.png"
run_demo gen, "input.extent_refs(:bottom, as_edges)", "drc_extent_refs10.png"
run_demo gen, "input.extent_refs(:top, as_edges)", "drc_extent_refs11.png"
run_demo gen, "input.extent_refs(:left, as_edges)", "drc_extent_refs12.png"
run_demo gen, "input.extent_refs(:right, as_edges)", "drc_extent_refs13.png"
run_demo gen, "input.extent_refs(:bottom_left).sized(0.1)", "drc_extent_refs20.png"
run_demo gen, "input.extent_refs(:bottom_center).sized(0.1)", "drc_extent_refs21.png"
run_demo gen, "input.extent_refs(:bottom_right).sized(0.1)", "drc_extent_refs22.png"
run_demo gen, "input.extent_refs(:right_center).sized(0.1)", "drc_extent_refs23.png"
run_demo gen, "input.extent_refs(:left_center).sized(0.1)", "drc_extent_refs24.png"
run_demo gen, "input.extent_refs(:top_left).sized(0.1)", "drc_extent_refs25.png"
run_demo gen, "input.extent_refs(:top_center).sized(0.1)", "drc_extent_refs26.png"
run_demo gen, "input.extent_refs(:top_right).sized(0.1)", "drc_extent_refs27.png"
run_demo gen, "input.extent_refs(0.25, 0.75).sized(0.1)", "drc_extent_refs30.png"
run_demo gen, "input.extent_refs(0.25, 0.75, 0.5, 1.0)", "drc_extent_refs31.png"

View File

@ -93,10 +93,10 @@ class DocItem
gsub(/\\@/, "&at;").
gsub(/\s*@code\s*/, "<pre>").
gsub(/\s*@\/code\s*/, "</pre>").
gsub(/\s*@img\((.*)\)\s*/) { "<img src=\"" + $1 + "\"/>" }.
gsub(/\s*@\/img\s*/, "</img>").
gsub(/\s*@(\w+)\s*/) { "<" + $1 + ">" }.
gsub(/\s*@\/(\w+)\s*/) { "</" + $1 + ">" }.
gsub(/@img\((.*)\)\s*/) { "<img src=\"" + $1 + "\"/>" }.
gsub(/@\/img\s*/, "</img>").
gsub(/@(\w+)\s*/) { "<" + $1 + ">" }.
gsub(/@\/(\w+)\s*/) { "</" + $1 + ">" }.
gsub(/&at;/, "@")
doc += "\n"
end

View File

@ -206,6 +206,11 @@ Edges::start_segments (db::Edges::length_type length, double fraction) const
Edges edges;
edges.reserve (m_edges.size ());
// zero-length edges would vanish in merged sematics, so we don't set it now
if (length == 0) {
edges.set_merged_semantics (false);
}
for (const_iterator e = begin_merged (); ! e.at_end (); ++e) {
double l = std::max (e->double_length () * fraction, double (length));
edges.insert (db::Edge (e->p1 (), db::Point (db::DPoint (e->p1 ()) + db::DVector (e->d()) * (l / e->double_length ()))));
@ -220,6 +225,11 @@ Edges::end_segments (db::Edges::length_type length, double fraction) const
Edges edges;
edges.reserve (m_edges.size ());
// zero-length edges would vanish in merged sematics, so we don't set it now
if (length == 0) {
edges.set_merged_semantics (false);
}
for (const_iterator e = begin_merged (); ! e.at_end (); ++e) {
double l = std::max (e->double_length () * fraction, double (length));
edges.insert (db::Edge (db::Point (db::DPoint (e->p2 ()) - db::DVector (e->d()) * (l / e->double_length ())), e->p2 ()));
@ -234,6 +244,11 @@ Edges::centers (db::Edges::length_type length, double fraction) const
Edges edges;
edges.reserve (m_edges.size ());
// zero-length edges would vanish in merged sematics, so we don't set it now
if (length == 0) {
edges.set_merged_semantics (false);
}
for (const_iterator e = begin_merged (); ! e.at_end (); ++e) {
double l = std::max (e->double_length () * fraction, double (length));
db::DVector dl = db::DVector (e->d()) * (0.5 * l / e->double_length ());

View File

@ -72,7 +72,7 @@ static db::Region *new_shapes (const db::Shapes &s)
return r;
}
static db::Region *new_si_texts (const db::RecursiveShapeIterator &si_in, const std::string &pat, bool pattern)
static db::Region *new_texts (const db::RecursiveShapeIterator &si_in, const std::string &pat, bool pattern)
{
db::RecursiveShapeIterator si (si_in);
si.shape_flags (db::ShapeIterator::Texts);
@ -103,9 +103,49 @@ static db::Region *new_si_texts (const db::RecursiveShapeIterator &si_in, const
return r.release ();
}
static db::Edges *new_texts_dots (const db::RecursiveShapeIterator &si_in, const std::string &pat, bool pattern)
{
db::RecursiveShapeIterator si (si_in);
si.shape_flags (db::ShapeIterator::Texts);
tl::GlobPattern glob_pat;
bool all = false;
if (pattern) {
if (pat == "*") {
all = true;
} else {
glob_pat = tl::GlobPattern (pat);
}
}
std::auto_ptr<db::Edges> r (new db::Edges ());
// Dots will vanish when we try to merge them ... hence disable merged semantics
r->set_merged_semantics (false);
while (! si.at_end ()) {
if (si.shape ().is_text () &&
(all || (pattern && glob_pat.match (si.shape ().text_string ())) || (!pattern && si.shape ().text_string () == pat))) {
db::Text t;
si.shape ().text (t);
t.transform (si.trans ());
db::Point c = t.box ().center ();
r->insert (db::Edge (c, c));
}
si.next ();
}
return r.release ();
}
static db::Region texts (const db::Region *r, const std::string &pat, bool pattern)
{
std::auto_ptr<db::Region> o (new_si_texts (r->iter (), pat, pattern));
std::auto_ptr<db::Region> o (new_texts (r->iter (), pat, pattern));
return *o;
}
static db::Edges texts_dots (const db::Region *r, const std::string &pat, bool pattern)
{
std::auto_ptr<db::Edges> o (new_texts_dots (r->iter (), pat, pattern));
return *o;
}
@ -250,6 +290,37 @@ static db::Region extents0 (const db::Region *r)
return extents2 (r, 0, 0);
}
static db::Region extent_refs (const db::Region *r, double fx1, double fy1, double fx2, double fy2, db::Coord dx, db::Coord dy)
{
db::Region e;
e.reserve (r->size ());
for (db::Region::const_iterator i = r->begin_merged (); ! i.at_end (); ++i) {
db::Box b = i->box ();
db::Point p1 (b.left () + db::coord_traits<db::Coord>::rounded (fx1 * b.width ()),
b.bottom () + db::coord_traits<db::Coord>::rounded (fy1 * b.height ()));
db::Point p2 (b.left () + db::coord_traits<db::Coord>::rounded (fx2 * b.width ()),
b.bottom () + db::coord_traits<db::Coord>::rounded (fy2 * b.height ()));
e.insert (db::Box (p1, p2).enlarged (db::Vector (dx, dy)));
}
return e;
}
static db::Edges extent_refs_edges (const db::Region *r, double fx1, double fy1, double fx2, double fy2)
{
db::Edges e;
e.set_merged_semantics (false);
e.reserve (r->size ());
for (db::Region::const_iterator i = r->begin_merged (); ! i.at_end (); ++i) {
db::Box b = i->box ();
db::Point p1 (b.left () + db::coord_traits<db::Coord>::rounded (fx1 * b.width ()),
b.bottom () + db::coord_traits<db::Coord>::rounded (fy1 * b.height ()));
db::Point p2 (b.left () + db::coord_traits<db::Coord>::rounded (fx2 * b.width ()),
b.bottom () + db::coord_traits<db::Coord>::rounded (fy2 * b.height ()));
e.insert (db::Edge (p1, p2));
}
return e;
}
static db::Region with_perimeter1 (const db::Region *r, db::Region::perimeter_type perimeter, bool inverse)
{
db::RegionPerimeterFilter f (perimeter, perimeter + 1, inverse);
@ -635,7 +706,7 @@ Class<db::Region> decl_Region ("Region",
"r = RBA::Region::new(layout.begin_shapes(cell, layer), RBA::ICplxTrans::new(layout.dbu / dbu))\n"
"@/code\n"
) +
constructor ("new", &new_si_texts, gsi::arg("shape_iterator"), gsi::arg ("expr"), gsi::arg ("as_pattern", true),
constructor ("new", &new_texts, gsi::arg("shape_iterator"), gsi::arg ("expr"), gsi::arg ("as_pattern", true),
"@brief Constructor from a text set\n"
"\n"
"@param shape_iterator The iterator from which to derive the texts\n"
@ -659,6 +730,10 @@ Class<db::Region> decl_Region ("Region",
"@hide\n"
"This method is provided for DRC implementation only."
) +
method_ext ("texts_dots", &texts_dots, gsi::arg ("expr", std::string ("*")), gsi::arg ("as_pattern", true),
"@hide\n"
"This method is provided for DRC implementation only."
) +
method ("merged_semantics=", &db::Region::set_merged_semantics,
"@brief Enables or disables merged semantics\n"
"@args f\n"
@ -959,6 +1034,14 @@ Class<db::Region> decl_Region ("Region",
"\n"
"Merged semantics applies for this method (see \\merged_semantics= of merged semantics)\n"
) +
method_ext ("extent_refs", &extent_refs,
"@hide\n"
"This method is provided for DRC implementation.\n"
) +
method_ext ("extent_refs_edges", &extent_refs_edges,
"@hide\n"
"This method is provided for DRC implementation.\n"
) +
method ("merge", (db::Region &(db::Region::*) ()) &db::Region::merge,
"@brief Merge the region\n"
"\n"

View File

@ -193,6 +193,28 @@ module DRC
end
end
# A wrapper for the "as_dots" or "as_boxes" flag for
# some DRC functions. The purpose of this class
# is to identify the value by the class.
class DRCAsDots
attr_accessor :value
def initialize(v)
self.value = v
end
end
# A wrapper for a glob-pattern style text selection for
# some DRC functions. The purpose of this class
# is to identify the value by the class.
class DRCPattern
attr_accessor :as_pattern
attr_accessor :pattern
def initialize(f, p)
self.as_pattern = f
self.pattern = p
end
end
# A wrapper for a pair of limit values
# This class is used to identify projection limits for DRC
# functions
@ -805,29 +827,253 @@ CODE
# @name texts
# @brief Selects texts from an original layer
# @synopsis layer.texts
# @synopsis layer.texts(pattern)
# @synopsis layer.texts(pattern, true)
# @synopsis layer.texts(string, false)
# @synopsis layer.texts(p)
# @synopsis layer.texts([ options ])
# This method can be applied to original layers - i.e. ones that have
# been created with \input. It will produce a small box (2x2 DBU) on each
# selected text.
# been created with \input. By default, a small box (2x2 DBU) will be produced on each
# selected text. By using the "as_dots" option, degenerated point-like edges will be
# produced.
#
# Texts can be selected either by exact match string or a pattern match with a
# glob-style pattern. The second argument selects pattern style (true)
# or exact match (false). The default is pattern match.
# glob-style pattern. By default, glob-style pattern are used.
# The options available are:
#
# @ul
# @li @b pattern(p) @/b: Use a pattern to match the string (this is the default) @/li
# @li @b text(s) @/b: Select the texts that exactly match the given string @/li
# @li @b as_boxes @/b: with this option, small boxes will be produced as markers @/li
# @li @b as_dots @/b: with this option, point-like edges will be produced instead of small boxes @/li
# @/ul
#
# Here are some examples:
#
# @code
# # Selects all texts
# t = input(1, 0).texts
# # Selects all texts beginning with an "A"
# t = input(1, 0).texts("A*")
# t = input(1, 0).texts("A*", true)
# t = input(1, 0).texts(pattern("A*"))
# # Selects all texts whose string is "A*"
# t = input(1, 0).texts("A*", false)
# t = input(1, 0).texts(text("A*"))
# @/code
def texts(expr = "*", as_pattern = true)
DRCLayer::new(@engine, @engine._tcmd(@data, 0, RBA::Region, :texts, expr, as_pattern))
def texts(*args)
requires_region("texts")
as_pattern = true
pattern = "*"
as_dots = false
args.each do |a|
if a.is_a?(String)
as_pattern = true
pattern = a
elsif a.is_a?(DRCPattern)
as_pattern = a.as_pattern
pattern = a.pattern
elsif a.is_a?(DRCAsDots)
as_dots = a.value
else
raise("Invalid argument for 'texts' method")
end
end
if as_dots
DRCLayer::new(@engine, @engine._tcmd(@data, 0, RBA::Region, :texts_dots, pattern, as_pattern))
else
DRCLayer::new(@engine, @engine._tcmd(@data, 0, RBA::Region, :texts, pattern, as_pattern))
end
end
# %DRC%
# @name middle
# @brief Returns the center points of the bounding boxes of the polygons
# @synopsis layer.middle([ options ])
#
# This method produces markers on the centers of the polygon's bounding box centers.
# These markers can be point-like edges or small 2x2 DBU boxes. The latter is the default.
# A more generic function is \extent_refs. "middle" is basically a synonym for "extent_refs(:center)".
#
# The options available are:
#
# @ul
# @li @b as_boxes @/b: with this option, small boxes will be produced as markers @/li
# @li @b as_dots @/b: with this option, point-like edges will be produced instead of small boxes @/li
# @/ul
#
# The following image shows the effect of this method
#
# @table
# @tr
# @td @img(/images/drc_middle1.png) @/td
# @/tr
# @/table
# %DRC%
# @name extent_refs
# @brief Returns partial references to the boundings boxes of the polygons
# @synopsis layer.extent_refs(fx, fy [, options ])
# @synopsis layer.extent_refs(fx1, fy1, fx2, fx2 [, options ])
# @synopsis layer.extent_refs(ref_spec [, options ])
#
# This method produces parts of the bounding box of the polygons. It can select
# either edges, certain points or partial boxes. It can be used the following
# ways:
#
# @ul
# @li @b With a formal specification @/b: This is an identifier like
# ":center" or ":left" to indicate which part will be produced. @/li
# @li @b With two floating-point arguments @/b: These arguments specify
# a point relative to the bounding box. The first argument is a relative
# x coordinate where 0.0 means "left side of the bounding box" and 1.0
# is the right side. The second argument is a relative y coordinate where
# 0.0 means "bottom" and 1.0 means "top". The results will be small
# (2x2 DBU) boxes or point-like edges for edge output @/li
# @li @b With four floating-point arguments @/b: These arguments specify
# a box in relative coordinates: a pair of x/y relative coordinate for
# the first point and another pair for the second point. The results will
# be boxes or a tilted edge in case of edge output. If the range specifies
# a finite-area box (height and width are not zero), no adjustment of
# the boxes will happen for polygon output - i.e. the additional enlargement
# by 1 DBU which is applied for zero-area boxes does not happen.@/li
# @/ul
#
# The formal specifiers are for points:
#
# @ul
# @li @b :center @/b or @b :c @/b: the center point @/li
# @li @b :bottom_center @/b or @b :bc @/b: the bottom center point @/li
# @li @b :bottom_left @/b or @b :bl @/b: the bottom left point @/li
# @li @b :bottom_right @/b or @b :br @/b: the bottom right point @/li
# @li @b :left @/b or @b :l @/b: the left point @/li
# @li @b :right @/b or @b :r @/b: the right point @/li
# @li @b :top_center @/b or @b :tc @/b: the top center point @/li
# @li @b :top_left @/b or @b :tl @/b: the top left point @/li
# @li @b :top_right @/b or @b :tr @/b: the top right point @/li
# @/ul
#
# The formal specifiers for lines are:
#
# @ul
# @li @b :bottom @/b or @b :b @/b: the bottom line @/li
# @li @b :top @/b or @b :t @/b: the top line @/li
# @li @b :left @/b or @b :l @/b: the left line @/li
# @li @b :right @/b or @b :r @/b: the right line @/li
# @/ul
#
# Dots are represented by small (2x2 DBU) boxes or point-like
# edges with edge output. Lines are represented by narrow or
# flat (2 DBU) boxes or edges for edge output. Edges will follow
# the orientation convention for the corresponding edges - i.e.
# "inside" of the bounding box is on the right side of the edge.
#
# The following additional option controls the output format:
#
# @ul
# @li @b as_boxes @/b: with this option, small boxes will be produced as markers @/li
# @li @b as_dots @/b or @b as_edges @/b: with this option, point-like edges will be produced for dots
# and edges will be produced for line-like selections @/li
# @/ul
#
# The following table shows a few applications:
#
# @table
# @tr
# @td @img(/images/drc_extent_refs1.png) @/td
# @/tr
# @tr
# @td @img(/images/drc_extent_refs10.png) @/td
# @td @img(/images/drc_extent_refs11.png) @/td
# @td @img(/images/drc_extent_refs12.png) @/td
# @td @img(/images/drc_extent_refs13.png) @/td
# @/tr
# @tr
# @td @img(/images/drc_extent_refs20.png) @/td
# @td @img(/images/drc_extent_refs21.png) @/td
# @td @img(/images/drc_extent_refs22.png) @/td
# @td @img(/images/drc_extent_refs23.png) @/td
# @td @img(/images/drc_extent_refs24.png) @/td
# @td @img(/images/drc_extent_refs25.png) @/td
# @td @img(/images/drc_extent_refs26.png) @/td
# @td @img(/images/drc_extent_refs27.png) @/td
# @/tr
# @tr
# @td @img(/images/drc_extent_refs30.png) @/td
# @td @img(/images/drc_extent_refs31.png) @/td
# @/tr
# @/table
%w(middle extent_refs).each do |f|
eval &lt;&lt;"CODE"
def #{f}(*args)
requires_region("#{f}")
f = []
as_edges = false
@@std_refs ||= {
:center => [0.5] * 4,
:c => [0.5] * 4,
:bottom_center => [ 0.5, 0.0, 0.5, 0.0 ],
:bc => [ 0.5, 0.0, 0.5, 0.0 ],
:bottom_left => [ 0.0, 0.0, 0.0, 0.0 ],
:bl => [ 0.0, 0.0, 0.0, 0.0 ],
:bottom_right => [ 1.0, 0.0, 1.0, 0.0 ],
:br => [ 1.0, 0.0, 1.0, 0.0 ],
:top_center => [ 0.5, 1.0, 0.5, 1.0 ],
:tc => [ 0.5, 1.0, 0.5, 1.0 ],
:top_left => [ 0.0, 1.0, 0.0, 1.0 ],
:tl => [ 0.0, 1.0, 0.0, 1.0 ],
:top_right => [ 1.0, 1.0, 1.0, 1.0 ],
:tr => [ 1.0, 1.0, 1.0, 1.0 ],
:left_center => [ 0.0, 0.5, 0.0, 0.5 ],
:lc => [ 0.0, 0.5, 0.0, 0.5 ],
:right_center => [ 1.0, 0.5, 1.0, 0.5 ],
:rc => [ 1.0, 0.5, 1.0, 0.5 ],
:south => [ 0.5, 0.0, 0.5, 0.0 ],
:s => [ 0.5, 0.0, 0.5, 0.0 ],
:left => [ 0.0, 0.0, 0.0, 1.0 ],
:l => [ 0.0, 0.0, 0.0, 1.0 ],
:bottom => [ 1.0, 0.0, 0.0, 0.0 ],
:b => [ 1.0, 0.0, 0.0, 0.0 ],
:right => [ 1.0, 1.0, 1.0, 0.0 ],
:r => [ 1.0, 1.0, 1.0, 0.0 ],
:top => [ 0.0, 1.0, 1.0, 1.0 ],
:t => [ 0.0, 1.0, 1.0, 1.0 ]
}
args.each do |a|
if a.is_a?(1.0.class) &amp;&amp; :#{f} != :middle
f &lt;&lt; a
elsif a.is_a?(DRCAsDots)
as_edges = a.value
elsif @@std_refs[a] &amp;&amp; :#{f} != :middle
f = @@std_refs[a]
else
raise("Invalid argument for '#{f}' method")
end
end
if f.size == 2
f = f + f
else
f = (f + [0.5] * 4)[0..3]
end
if as_edges
DRCLayer::new(@engine, @engine._tcmd(@data, 0, RBA::Region, :extent_refs_edges, *f))
else
# add oversize for point- and edge-like regions
zero_area = (f[0] - f[2]).abs &lt; 1e-7 || (f[1] - f[3]).abs &lt; 1e-7
f += [ zero_area ? 1 : 0 ] * 2
DRCLayer::new(@engine, @engine._tcmd(@data, 0, RBA::Region, :extent_refs, *f))
end
end
CODE
end
# %DRC%
@ -2393,13 +2639,13 @@ CODE
# The mode defines how to handle corners. The following modes are available:
#
# @ul
# @li @b diamond_limit: @/b This mode will connect the shifted edges without corner interpolation @/li
# @li @b octagon_limit: @/b This mode will create octagon-shaped corners @/li
# @li @b square_limit: @/b This mode will leave 90 degree corners untouched but
# @li @b diamond_limit @/b: This mode will connect the shifted edges without corner interpolation @/li
# @li @b octagon_limit @/b: This mode will create octagon-shaped corners @/li
# @li @b square_limit @/b: This mode will leave 90 degree corners untouched but
# cut off corners with a sharper angle. This is the default mode. @/li
# @li @b acute_limit: @/b This mode will leave 45 degree corners untouched but
# @li @b acute_limit @/b: This mode will leave 45 degree corners untouched but
# cut off corners with a sharper angle @/li
# @li @b no_limit: @/b This mode will not cut off (only at extremely sharp angles @/li
# @li @b no_limit @/b: This mode will not cut off (only at extremely sharp angles @/li
# @/ul
#
# Merged semantics applies, i.e. polygons will be merged before the sizing is applied
@ -3160,6 +3406,26 @@ CODE
DRCMetrics::new(RBA::Region::Projection)
end
def pattern(p)
DRCPattern::new(true, p)
end
def text(p)
DRCPattern::new(false, p)
end
def as_dots
DRCAsDots::new(true)
end
def as_edges
DRCAsDots::new(true)
end
def as_boxes
DRCAsDots::new(false)
end
# %DRC%
# @name verbose?
# @brief Returns true, if verbose mode is enabled

View File

@ -176,10 +176,10 @@ of that object can be used to get input layers for that layout.
"what" specifies what input to use. "what" be either
</p><p>
<ul>
<li>A string "@n" specifying input from a cellview in the current view</li>
<li>A layout filename plus an optional cell name</li>
<li>A <class_doc href="Layout">Layout</class_doc> object</li>
<li>A <class_doc href="Cell">Cell</class_doc> object</li>
<li>A string "@n" specifying input from a cellview in the current view </li>
<li>A layout filename plus an optional cell name </li>
<li>A <class_doc href="Layout">Layout</class_doc> object </li>
<li>A <class_doc href="Cell">Cell</class_doc> object </li>
</ul>
</p><p>
Without any arguments the default layout is returned.
@ -297,7 +297,7 @@ filled with polygon-like objects using <a href="/about/drc_ref_layer.xml#insert"
<keyword name="report"/>
<a name="report"/><p>Usage:</p>
<ul>
<li><tt>report(description [, filename])</tt></li>
<li><tt>report(description [, filename [, cellname ] ])</tt></li>
</ul>
<p>
After specifying a report database for output, <a href="#output">output</a> method calls are redirected to
@ -310,6 +310,11 @@ Otherwise it will be shown but not written.
</p><p>
If external input is specified with <a href="#source">source</a>,
"report" must be called after "source".
</p><p>
The cellname specifies the top cell used for the report file.
By default this is the cell name of the default source. If there
is no source layout you'll need to give the cell name in the
third parameter.
</p>
<h2>"select" - Specifies cell filters on the default source</h2>
<keyword name="select"/>
@ -341,15 +346,15 @@ This function replaces the default source layout by the specified
file. If this function is not used, the currently active layout
is used as input.
</p><p>
<a href="#layout">layout</a> is a similar method which specifies<i>a additional</i>input layout.
<a href="#layout">layout</a> is a similar method which specifies <i>a additional </i>input layout.
</p><p>
"what" specifies what input to use. "what" be either
</p><p>
<ul>
<li>A string "@n" specifying input from a layout in the current panel</li>
<li>A string "@n" specifying input from a layout in the current panel </li>
<li>A layout filename plus an optional cell name</li>
<li>A <class_doc href="Layout">Layout</class_doc> object plus an optional cell name</li>
<li>A <class_doc href="Cell">Cell</class_doc> object</li>
<li>A <class_doc href="Cell">Cell</class_doc> object </li>
</ul>
</p><p>
Without any arguments the default layout is returned. If a filename is given, a cell name
@ -382,10 +387,10 @@ a new target will be set up.
"what" specifies what input to use. "what" be either
</p><p>
<ul>
<li>A string "@n" specifying output to a layout in the current panel</li>
<li>A layout filename</li>
<li>A <class_doc href="Layout">Layout</class_doc> object</li>
<li>A <class_doc href="Cell">Cell</class_doc> object</li>
<li>A string "@n" specifying output to a layout in the current panel </li>
<li>A layout filename </li>
<li>A <class_doc href="Layout">Layout</class_doc> object </li>
<li>A <class_doc href="Cell">Cell</class_doc> object </li>
</ul>
</p><p>
Except if the argument is a <class_doc href="Cell">Cell</class_doc> object, a cellname can be specified

View File

@ -339,6 +339,102 @@ This method is basically equivalent to the <a href="#extended">extended</a> meth
"extended(0, 0, dist, 0)".
A version extending to the inside is <a href="#extended_in">extended_in</a>.
</p>
<h2>"extent_refs" - Returns partial references to the boundings boxes of the polygons</h2>
<keyword name="extent_refs"/>
<a name="extent_refs"/><p>Usage:</p>
<ul>
<li><tt>layer.extent_refs(fx, fy [, options ])</tt></li>
<li><tt>layer.extent_refs(fx1, fy1, fx2, fx2 [, options ])</tt></li>
<li><tt>layer.extent_refs(ref_spec [, options ])</tt></li>
</ul>
<p>
This method produces parts of the bounding box of the polygons. It can select
either edges, certain points or partial boxes. It can be used the following
ways:
</p><p>
<ul>
<li><b>With a formal specification </b>: This is an identifier like
":center" or ":left" to indicate which part will be produced. </li>
<li><b>With two floating-point arguments </b>: These arguments specify
a point relative to the bounding box. The first argument is a relative
x coordinate where 0.0 means "left side of the bounding box" and 1.0
is the right side. The second argument is a relative y coordinate where
0.0 means "bottom" and 1.0 means "top". The results will be small
(2x2 DBU) boxes or point-like edges for edge output </li>
<li><b>With four floating-point arguments </b>: These arguments specify
a box in relative coordinates: a pair of x/y relative coordinate for
the first point and another pair for the second point. The results will
be boxes or a tilted edge in case of edge output. If the range specifies
a finite-area box (height and width are not zero), no adjustment of
the boxes will happen for polygon output - i.e. the additional enlargement
by 1 DBU which is applied for zero-area boxes does not happen.</li>
</ul>
</p><p>
The formal specifiers are for points:
</p><p>
<ul>
<li><b>:center </b>or <b>:c </b>: the center point </li>
<li><b>:bottom_center </b>or <b>:bc </b>: the bottom center point </li>
<li><b>:bottom_left </b>or <b>:bl </b>: the bottom left point </li>
<li><b>:bottom_right </b>or <b>:br </b>: the bottom right point </li>
<li><b>:left </b>or <b>:l </b>: the left point </li>
<li><b>:right </b>or <b>:r </b>: the right point </li>
<li><b>:top_center </b>or <b>:tc </b>: the top center point </li>
<li><b>:top_left </b>or <b>:tl </b>: the top left point </li>
<li><b>:top_right </b>or <b>:tr </b>: the top right point </li>
</ul>
</p><p>
The formal specifiers for lines are:
</p><p>
<ul>
<li><b>:bottom </b>or <b>:b </b>: the bottom line </li>
<li><b>:top </b>or <b>:t </b>: the top line </li>
<li><b>:left </b>or <b>:l </b>: the left line </li>
<li><b>:right </b>or <b>:r </b>: the right line </li>
</ul>
</p><p>
Dots are represented by small (2x2 DBU) boxes or point-like
edges with edge output. Lines are represented by narrow or
flat (2 DBU) boxes or edges for edge output. Edges will follow
the orientation convention for the corresponding edges - i.e.
"inside" of the bounding box is on the right side of the edge.
</p><p>
The following additional option controls the output format:
</p><p>
<ul>
<li><b>as_boxes </b>: with this option, small boxes will be produced as markers </li>
<li><b>as_dots </b>or <b>as_edges </b>: with this option, point-like edges will be produced for dots
and edges will be produced for line-like selections </li>
</ul>
</p><p>
The following table shows a few applications:
</p><p>
<table>
<tr>
<td><img src="/images/drc_extent_refs1.png"/></td>
</tr>
<tr>
<td><img src="/images/drc_extent_refs10.png"/></td>
<td><img src="/images/drc_extent_refs11.png"/></td>
<td><img src="/images/drc_extent_refs12.png"/></td>
<td><img src="/images/drc_extent_refs13.png"/></td>
</tr>
<tr>
<td><img src="/images/drc_extent_refs20.png"/></td>
<td><img src="/images/drc_extent_refs21.png"/></td>
<td><img src="/images/drc_extent_refs22.png"/></td>
<td><img src="/images/drc_extent_refs23.png"/></td>
<td><img src="/images/drc_extent_refs24.png"/></td>
<td><img src="/images/drc_extent_refs25.png"/></td>
<td><img src="/images/drc_extent_refs26.png"/></td>
<td><img src="/images/drc_extent_refs27.png"/></td>
</tr>
<tr>
<td><img src="/images/drc_extent_refs30.png"/></td>
<td><img src="/images/drc_extent_refs31.png"/></td>
</tr>
</table>
</p>
<h2>"extents" - Returns the bounding box of each input object</h2>
<keyword name="extents"/>
<a name="extents"/><p>Usage:</p>
@ -684,6 +780,32 @@ The following images show the effect of various forms of the "merged" method:
</tr>
</table>
</p>
<h2>"middle" - Returns the center points of the bounding boxes of the polygons</h2>
<keyword name="middle"/>
<a name="middle"/><p>Usage:</p>
<ul>
<li><tt>layer.middle([ options ])</tt></li>
</ul>
<p>
This method produces markers on the centers of the polygon's bounding box centers.
These markers can be point-like edges or small 2x2 DBU boxes. The latter is the default.
A more generic function is <a href="#extent_refs">extent_refs</a>. "middle" is basically a synonym for "extent_refs(:center)".
</p><p>
The options available are:
</p><p>
<ul>
<li><b>as_boxes </b>: with this option, small boxes will be produced as markers </li>
<li><b>as_dots </b>: with this option, point-like edges will be produced instead of small boxes </li>
</ul>
</p><p>
The following image shows the effect of this method
</p><p>
<table>
<tr>
<td><img src="/images/drc_middle1.png"/></td>
</tr>
</table>
</p>
<h2>"move" - Moves (shifts, translates) a layer (modifies the layer)</h2>
<keyword name="move"/>
<a name="move"/><p>Usage:</p>
@ -1463,13 +1585,13 @@ In the two-value form, the horizontal and vertical bias can be specified separat
The mode defines how to handle corners. The following modes are available:
</p><p>
<ul>
<li><b>diamond_limit:</b>This mode will connect the shifted edges without corner interpolation</li>
<li><b>octagon_limit:</b>This mode will create octagon-shaped corners</li>
<li><b>square_limit:</b>This mode will leave 90 degree corners untouched but
cut off corners with a sharper angle. This is the default mode.</li>
<li><b>acute_limit:</b>This mode will leave 45 degree corners untouched but
cut off corners with a sharper angle</li>
<li><b>no_limit:</b>This mode will not cut off (only at extremely sharp angles</li>
<li><b>diamond_limit </b>: This mode will connect the shifted edges without corner interpolation </li>
<li><b>octagon_limit </b>: This mode will create octagon-shaped corners </li>
<li><b>square_limit </b>: This mode will leave 90 degree corners untouched but
cut off corners with a sharper angle. This is the default mode. </li>
<li><b>acute_limit </b>: This mode will leave 45 degree corners untouched but
cut off corners with a sharper angle </li>
<li><b>no_limit </b>: This mode will not cut off (only at extremely sharp angles </li>
</ul>
</p><p>
Merged semantics applies, i.e. polygons will be merged before the sizing is applied
@ -1637,27 +1759,36 @@ This feature has been introduced in version 0.23.2.
<a name="texts"/><p>Usage:</p>
<ul>
<li><tt>layer.texts</tt></li>
<li><tt>layer.texts(pattern)</tt></li>
<li><tt>layer.texts(pattern, true)</tt></li>
<li><tt>layer.texts(string, false)</tt></li>
<li><tt>layer.texts(p)</tt></li>
<li><tt>layer.texts([ options ])</tt></li>
</ul>
<p>
This method can be applied to original layers - i.e. ones that have
been created with <a href="#input">input</a>. It will produce a small box (2x2 DBU) on each
selected text.
been created with <a href="#input">input</a>. By default, a small box (2x2 DBU) will be produced on each
selected text. By using the "as_dots" option, degenerated point-like edges will be
produced.
</p><p>
Texts can be selected either by exact match string or a pattern match with a
glob-style pattern. The second argument selects pattern style (true)
or exact match (false). The default is pattern match.
glob-style pattern. By default, glob-style pattern are used.
The options available are:
</p><p>
<ul>
<li><b>pattern(p) </b>: Use a pattern to match the string (this is the default) </li>
<li><b>text(s) </b>: Select the texts that exactly match the given string </li>
<li><b>as_boxes </b>: with this option, small boxes will be produced as markers </li>
<li><b>as_dots </b>: with this option, point-like edges will be produced instead of small boxes </li>
</ul>
</p><p>
Here are some examples:
</p><p>
<pre>
# Selects all texts
t = input(1, 0).texts
# Selects all texts beginning with an "A"
t = input(1, 0).texts("A*")
t = input(1, 0).texts("A*", true)
t = input(1, 0).texts(pattern("A*"))
# Selects all texts whose string is "A*"
t = input(1, 0).texts("A*", false)
t = input(1, 0).texts(text("A*"))
</pre>
</p>
<h2>"transform" - Transforms a layer (modifies the layer)</h2>
@ -1709,18 +1840,18 @@ width is less than the specified value. In that case, an edge pair error shape i
The options available are:
</p><p>
<ul>
<li><b>euclidian</b>: perform the check using Euclidian metrics (this is the default)</li>
<li><b>square</b>: perform the check using Square metrics</li>
<li><b>projection</b>: perform the check using projection metrics</li>
<li><b>whole_edges</b>: With this option, the check will return all of the edges,
even if the criterion is violated only over a part of the edge</li>
<li><b>angle_limit(a)</b>: Specifies the angle above or equal to which no
<li><b>euclidian </b>: perform the check using Euclidian metrics (this is the default) </li>
<li><b>square </b>: perform the check using Square metrics </li>
<li><b>projection </b>: perform the check using projection metrics </li>
<li><b>whole_edges </b>: With this option, the check will return all of the edges,
even if the criterion is violated only over a part of the edge </li>
<li><b>angle_limit(a) </b>: Specifies the angle above or equal to which no
check is performed. The default value is 90, which means that for edges having
an angle of 90 degree or more, no check is performed. Setting this value to 45 will
make the check only consider edges enclosing angles of less than 45 degree.</li>
<li><b>projection_limits(min, max) or projection_limits(min .. max)</b>:
make the check only consider edges enclosing angles of less than 45 degree. </li>
<li><b>projection_limits(min, max) or projection_limits(min .. max) </b>:
this option makes the check only consider edge pairs whose projected length on
each other is more or equal than min and less than max</li>
each other is more or equal than min and less than max </li>
</ul>
</p><p>
Note that without the angle_limit, acute corners will always be reported, since two

View File

@ -88,10 +88,10 @@ expressions are joined to render the input layer for the DRC engine.
Some filter expressions are:
</p><p>
<ul>
<li><tt>1/0-255</tt>: Datatypes 0 to 255 for layer 1</li>
<li><tt>1-10</tt>: Layers 1 to 10, datatype 0</li>
<li><tt>METAL</tt>: A layer named "METAL"</li>
<li><tt>METAL (17/0)</tt>: A layer named "METAL" or layer 17, datatype 0 (for GDS, which does
<li><tt>1/0-255 </tt>: Datatypes 0 to 255 for layer 1 </li>
<li><tt>1-10 </tt>: Layers 1 to 10, datatype 0 </li>
<li><tt>METAL </tt>: A layer named "METAL" </li>
<li><tt>METAL (17/0) </tt>: A layer named "METAL" or layer 17, datatype 0 (for GDS, which does
not have names)</li>
</ul>
</p>
@ -161,9 +161,9 @@ no specification.
The following options are available:
</p><p>
<ul>
<li><tt>+</tt><i>name_filter</i>: Cells matching the name filter will be enabled</li>
<li><i>name_filter</i>: Same as "+name_filter"</li>
<li><tt>-</tt><i>name_filter</i>: Cells matching the name filter will be disabled</li>
<li><tt>+</tt><i>name_filter </i>: Cells matching the name filter will be enabled </li>
<li><i>name_filter </i>: Same as "+name_filter" </li>
<li><tt>-</tt><i>name_filter </i>: Cells matching the name filter will be disabled </li>
</ul>
</p><p>
To disable the TOP cell but enabled a hypothetical cell B below the top cell, use that

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -76,6 +76,22 @@
<file alias="drc_with_angle3.png">doc/images/drc_with_angle3.png</file>
<file alias="drc_with_angle4.png">doc/images/drc_with_angle4.png</file>
<file alias="drc_rounded_corners.png">doc/images/drc_rounded_corners.png</file>
<file alias="drc_middle1.png">doc/images/drc_middle1.png</file>
<file alias="drc_extent_refs1.png">doc/images/drc_extent_refs1.png</file>
<file alias="drc_extent_refs10.png">doc/images/drc_extent_refs10.png</file>
<file alias="drc_extent_refs11.png">doc/images/drc_extent_refs11.png</file>
<file alias="drc_extent_refs12.png">doc/images/drc_extent_refs12.png</file>
<file alias="drc_extent_refs13.png">doc/images/drc_extent_refs13.png</file>
<file alias="drc_extent_refs20.png">doc/images/drc_extent_refs20.png</file>
<file alias="drc_extent_refs21.png">doc/images/drc_extent_refs21.png</file>
<file alias="drc_extent_refs22.png">doc/images/drc_extent_refs22.png</file>
<file alias="drc_extent_refs23.png">doc/images/drc_extent_refs23.png</file>
<file alias="drc_extent_refs24.png">doc/images/drc_extent_refs24.png</file>
<file alias="drc_extent_refs25.png">doc/images/drc_extent_refs25.png</file>
<file alias="drc_extent_refs26.png">doc/images/drc_extent_refs26.png</file>
<file alias="drc_extent_refs27.png">doc/images/drc_extent_refs27.png</file>
<file alias="drc_extent_refs30.png">doc/images/drc_extent_refs30.png</file>
<file alias="drc_extent_refs31.png">doc/images/drc_extent_refs31.png</file>
</qresource>
<qresource prefix="/help/about">
<file alias="rba_notation.xml">doc/about/rba_notation.xml</file>

View File

@ -1,4 +1,5 @@
# Set to false for a short run
big_tests = false
verbose(true)
@ -500,9 +501,46 @@ cell("TOP")
c1.rounded_corners(0.5, 0.5, 16).output(1010, 0)
c1.smoothed(1.5).output(1011, 0)
a1.texts.output(1020, 0)
a1.texts("A*").output(1021, 0)
a1.texts("A*", false).output(1022, 0)
a1.texts(text("A*")).output(1022, 0)
a1.texts(pattern("A*")).output(1023, 0)
a1.texts(pattern("A*"), as_dots).extended(0.05, 0.05, 0.05, 0.05).output(1024, 0)
a1.texts(pattern("A*"), as_boxes).output(1025, 0)
a1.middle.sized(0.05).output(1030, 0)
a1.middle(as_dots).extended(0.05, 0.05, 0.05, 0.05).output(1031, 0)
a1.middle(as_boxes).sized(0.05).output(1032, 0)
a1.extent_refs(0.5, 0.5).sized(0.05).output(1040, 0)
a1.extent_refs(:center).sized(0.05).output(1040, 1)
a1.extent_refs(:c).sized(0.05).output(1040, 2)
a1.extent_refs(:bottom).sized(0.05).output(1041, 0)
a1.extent_refs(:b).sized(0.05).output(1041, 1)
a1.extent_refs(:b, as_edges).extended(0.05, 0.05, 0.05, 0.05).output(1041, 2)
a1.extent_refs(:top).sized(0.05).output(1042, 0)
a1.extent_refs(:t).sized(0.05).output(1042, 1)
a1.extent_refs(:left).sized(0.05).output(1043, 0)
a1.extent_refs(:l).sized(0.05).output(1043, 1)
a1.extent_refs(:right).sized(0.05).output(1044, 0)
a1.extent_refs(:r).sized(0.05).output(1044, 1)
a1.extent_refs(:bottom_left).sized(0.05).output(1045, 0)
a1.extent_refs(:bl).sized(0.05).output(1045, 1)
a1.extent_refs(:bottom_center).sized(0.05).output(1046, 0)
a1.extent_refs(:bc).sized(0.05).output(1046, 1)
a1.extent_refs(:bottom_right).sized(0.05).output(1047, 0)
a1.extent_refs(:br).sized(0.05).output(1047, 1)
a1.extent_refs(:top_left).sized(0.05).output(1048, 0)
a1.extent_refs(:tl).sized(0.05).output(1048, 1)
a1.extent_refs(:top_center).sized(0.05).output(1049, 0)
a1.extent_refs(:tc).sized(0.05).output(1049, 1)
a1.extent_refs(:top_right).sized(0.05).output(1050, 0)
a1.extent_refs(:tr).sized(0.05).output(1050, 1)
a1.extent_refs(:left_center).sized(0.05).output(1051, 0)
a1.extent_refs(:lc).sized(0.05).output(1051, 1)
a1.extent_refs(:right_center).sized(0.05).output(1052, 0)
a1.extent_refs(:rc).sized(0.05).output(1052, 1)
a1.extent_refs(0.25, 0.5, 0.5, 0.75).output(1053, 0)
puts "=== Single-cell testsuite ==="