Implemented LayerInfo for DRC input/output
- Added a "layers" function too - Updated tests - Updated documentation
|
|
@ -0,0 +1,572 @@
|
|||
|
||||
# Run with:
|
||||
# ./klayout -z -r ./create_drc_samples.rb -t -c klayoutrc_drc_samples
|
||||
|
||||
def run_demo(gen, cmd, out)
|
||||
|
||||
img_path = "src/lay/doc/images"
|
||||
|
||||
mw = RBA::Application::instance::main_window
|
||||
|
||||
cv = mw.create_layout(0)
|
||||
ly = cv.layout
|
||||
view = mw.current_view
|
||||
|
||||
l0 = ly.insert_layer(RBA::LayerInfo::new(0, 0))
|
||||
l1 = ly.insert_layer(RBA::LayerInfo::new(1, 0))
|
||||
l2 = ly.insert_layer(RBA::LayerInfo::new(2, 0))
|
||||
lout_poly = ly.insert_layer(RBA::LayerInfo::new(101, 0))
|
||||
lout = ly.insert_layer(RBA::LayerInfo::new(100, 0))
|
||||
cell = ly.create_cell("TOP")
|
||||
view.select_cell(0, cell.cell_index)
|
||||
|
||||
lp = RBA::LayerProperties::new
|
||||
lp.fill_color = lp.frame_color = 0xffffff
|
||||
lp.source_layer = 0
|
||||
lp.source_datatype = 0
|
||||
lp.dither_pattern = 5
|
||||
lp.width = 0
|
||||
lp.name = "TXT"
|
||||
view.insert_layer(view.end_layers, lp)
|
||||
|
||||
lp = RBA::LayerProperties::new
|
||||
lp.fill_color = lp.frame_color = 0xff8080
|
||||
lp.source_layer = 1
|
||||
lp.source_datatype = 0
|
||||
lp.dither_pattern = 5
|
||||
lp.name = "IN1"
|
||||
view.insert_layer(view.end_layers, lp)
|
||||
|
||||
lp = RBA::LayerProperties::new
|
||||
lp.fill_color = lp.frame_color = 0x8080ff
|
||||
lp.source_layer = 2
|
||||
lp.source_datatype = 0
|
||||
lp.dither_pattern = 9
|
||||
lp.name = "IN2"
|
||||
view.insert_layer(view.end_layers, lp)
|
||||
|
||||
lp = RBA::LayerProperties::new
|
||||
lp.fill_color = lp.frame_color = 0x404040
|
||||
lp.source_layer = 101
|
||||
lp.source_datatype = 0
|
||||
lp.width = 0
|
||||
lp.dither_pattern = 0
|
||||
lp.transparent = true
|
||||
lp.name = "OUT_POLY"
|
||||
view.insert_layer(view.end_layers, lp)
|
||||
|
||||
lp = RBA::LayerProperties::new
|
||||
lp.fill_color = lp.frame_color = 0xffffff
|
||||
lp.source_layer = 100
|
||||
lp.source_datatype = 0
|
||||
lp.width = 3
|
||||
lp.name = "OUT"
|
||||
view.insert_layer(view.end_layers, lp)
|
||||
|
||||
gen.produce(cell.shapes(l1), cell.shapes(l2))
|
||||
|
||||
view.zoom_box(RBA::DBox::new(-2.0, -1.0, 8.0, 9.0))
|
||||
|
||||
t = RBA::Text::new(cmd, -1500, 8500)
|
||||
t.valign = 0
|
||||
t.font = 0
|
||||
t.size = 0.2 / ly.dbu
|
||||
cell.shapes(l0).insert(t)
|
||||
|
||||
eng = DRC::DRCEngine::new
|
||||
data = eng.instance_eval(<<SCRIPT)
|
||||
silent
|
||||
input1 = input(1, 0)
|
||||
input = input1
|
||||
input2 = input(2, 0)
|
||||
#{cmd}.data
|
||||
SCRIPT
|
||||
|
||||
if data.is_a?(RBA::Region)
|
||||
cell.shapes(lout_poly).insert(data)
|
||||
cell.shapes(lout).insert(data)
|
||||
elsif data.is_a?(RBA::Edges)
|
||||
data.each do |e|
|
||||
v = e.p2 - e.p1
|
||||
if v.length > 0
|
||||
a1 = RBA::ICplxTrans::new(300.0 / v.length, 30, false, 0, 0).trans(v)
|
||||
a2 = RBA::ICplxTrans::new(300.0 / v.length, -30, false, 0, 0).trans(v)
|
||||
cell.shapes(lout).insert(RBA::Edge::new(e.p2 - a1, e.p2))
|
||||
cell.shapes(lout).insert(RBA::Edge::new(e.p2 - a2, e.p2))
|
||||
end
|
||||
cell.shapes(lout).insert(e)
|
||||
end
|
||||
elsif data.is_a?(RBA::EdgePairs)
|
||||
cell.shapes(lout_poly).insert_as_polygons(data, 1)
|
||||
cell.shapes(lout).insert(data.edges)
|
||||
end
|
||||
|
||||
view.update_content
|
||||
view.save_image(img_path + "/" + out, 400, 400)
|
||||
|
||||
puts "---> written #{img_path}/#{out}"
|
||||
|
||||
mw.close_all
|
||||
|
||||
end
|
||||
|
||||
class Gen
|
||||
def produce(s1, s2)
|
||||
pts = [
|
||||
RBA::Point::new(0, 0),
|
||||
RBA::Point::new(3000, 0),
|
||||
RBA::Point::new(3000, 4000),
|
||||
RBA::Point::new(5000, 4000),
|
||||
RBA::Point::new(5000, 7000),
|
||||
RBA::Point::new(2000, 7000),
|
||||
RBA::Point::new(2000, 3000),
|
||||
RBA::Point::new(0, 3000)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
end
|
||||
end
|
||||
|
||||
gen = Gen::new
|
||||
|
||||
run_demo gen, "input.width(1.2, euclidian)", "drc_width1.png"
|
||||
run_demo gen, "input.width(1.2, projection)", "drc_width2.png"
|
||||
run_demo gen, "input.width(1.2, square)", "drc_width3.png"
|
||||
run_demo gen, "input.width(1.2, whole_edges)", "drc_width4.png"
|
||||
|
||||
class Gen
|
||||
def produce(s1, s2)
|
||||
pts = [
|
||||
RBA::Point::new(4000, 0),
|
||||
RBA::Point::new(4000, 1000),
|
||||
RBA::Point::new(6000, 1000),
|
||||
RBA::Point::new(6000, 2000),
|
||||
RBA::Point::new(4000, 2000),
|
||||
RBA::Point::new(4000, 6000),
|
||||
RBA::Point::new(7000, 6000),
|
||||
RBA::Point::new(7000, 0)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
pts = [
|
||||
RBA::Point::new(0, 4000),
|
||||
RBA::Point::new(0, 7000),
|
||||
RBA::Point::new(3000, 7000),
|
||||
RBA::Point::new(3000, 4000)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
end
|
||||
end
|
||||
|
||||
gen = Gen::new
|
||||
|
||||
run_demo gen, "input.space(1.2, euclidian)", "drc_space1.png"
|
||||
run_demo gen, "input.notch(1.2, euclidian)", "drc_space2.png"
|
||||
run_demo gen, "input.isolated(1.2, euclidian)", "drc_space3.png"
|
||||
|
||||
class Gen
|
||||
def produce(s1, s2)
|
||||
pts = [
|
||||
RBA::Point::new(4000, 0),
|
||||
RBA::Point::new(4000, 1000),
|
||||
RBA::Point::new(6000, 1000),
|
||||
RBA::Point::new(6000, 2000),
|
||||
RBA::Point::new(4000, 2000),
|
||||
RBA::Point::new(4000, 6000),
|
||||
RBA::Point::new(7000, 6000),
|
||||
RBA::Point::new(7000, 0)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
pts = [
|
||||
RBA::Point::new(0, 0),
|
||||
RBA::Point::new(0, 3000),
|
||||
RBA::Point::new(3000, 3000),
|
||||
RBA::Point::new(3000, 0)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
pts = [
|
||||
RBA::Point::new(0, 4000),
|
||||
RBA::Point::new(0, 7000),
|
||||
RBA::Point::new(3000, 7000),
|
||||
RBA::Point::new(3000, 4000)
|
||||
];
|
||||
s2.insert(RBA::Polygon::new(pts))
|
||||
end
|
||||
end
|
||||
|
||||
gen = Gen::new
|
||||
|
||||
run_demo gen, "input1.separation(input2, 1.2, euclidian)", "drc_separation1.png"
|
||||
|
||||
# ...
|
||||
|
||||
class Gen
|
||||
def produce(s1, s2)
|
||||
pts = [
|
||||
RBA::Point::new(5000, 0),
|
||||
RBA::Point::new(5000, 2000),
|
||||
RBA::Point::new(4000, 2000),
|
||||
RBA::Point::new(4000, 5000),
|
||||
RBA::Point::new(3000, 5000),
|
||||
RBA::Point::new(3000, 7000),
|
||||
RBA::Point::new(6000, 7000),
|
||||
RBA::Point::new(6000, 0)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
pts = [
|
||||
RBA::Point::new(0, 0),
|
||||
RBA::Point::new(0, 7000),
|
||||
RBA::Point::new(2000, 7000),
|
||||
RBA::Point::new(2000, 0)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
end
|
||||
end
|
||||
|
||||
gen = Gen::new
|
||||
|
||||
run_demo gen, "input.sized(1.8, 0.0).raw.merged(2)", "drc_raw1.png"
|
||||
|
||||
class Gen
|
||||
def produce(s1, s2)
|
||||
pts = [
|
||||
RBA::Point::new(0, 0),
|
||||
RBA::Point::new(0, 4000),
|
||||
RBA::Point::new(3000, 7000),
|
||||
RBA::Point::new(3000, 0)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
pts = [
|
||||
RBA::Point::new(3000, 0),
|
||||
RBA::Point::new(3000, 7000),
|
||||
RBA::Point::new(6000, 4000),
|
||||
RBA::Point::new(6000, 0)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
end
|
||||
end
|
||||
|
||||
gen = Gen::new
|
||||
|
||||
run_demo gen, "input.raw.sized(-0.5)", "drc_raw2.png"
|
||||
run_demo gen, "input.sized(-0.5)", "drc_raw3.png"
|
||||
|
||||
|
||||
|
||||
class Gen
|
||||
def produce(s1, s2)
|
||||
s1.insert(RBA::Box::new(0, 1000, 6000, 7000))
|
||||
s2.insert(RBA::Box::new(3000, 0, 6000, 6000))
|
||||
end
|
||||
end
|
||||
|
||||
gen = Gen::new
|
||||
|
||||
run_demo gen, "input1.enclosing(input2, 2.0.um)", "drc_enc1.png"
|
||||
run_demo gen, "input1.enclosing(input2, 2.0.um, projection)", "drc_enc2.png"
|
||||
|
||||
|
||||
class Gen
|
||||
def produce(s1, s2)
|
||||
pts = [
|
||||
RBA::Point::new(0, 1000),
|
||||
RBA::Point::new(0, 7000),
|
||||
RBA::Point::new(7000, 7000),
|
||||
RBA::Point::new(7000, 3000),
|
||||
RBA::Point::new(4000, 3000),
|
||||
RBA::Point::new(4000, 5000),
|
||||
RBA::Point::new(2000, 5000),
|
||||
RBA::Point::new(2000, 2000),
|
||||
RBA::Point::new(1000, 2000),
|
||||
RBA::Point::new(1000, 1000)
|
||||
];
|
||||
s2.insert(RBA::Polygon::new(pts))
|
||||
pts = [
|
||||
RBA::Point::new(2000, 0),
|
||||
RBA::Point::new(2000, 6000),
|
||||
RBA::Point::new(6000, 6000),
|
||||
RBA::Point::new(6000, 0)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
end
|
||||
end
|
||||
|
||||
gen = Gen::new
|
||||
|
||||
run_demo gen, "input1.overlap(input2, 2.0.um)", "drc_overlap1.png"
|
||||
run_demo gen, "input1.overlap(input2, 2.0.um, projection)", "drc_overlap2.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.edges.start_segments(1.um)", "drc_start_segments1.png"
|
||||
run_demo gen, "input.edges.start_segments(0, 0.5)", "drc_start_segments2.png"
|
||||
|
||||
run_demo gen, "input.edges.end_segments(1.um)", "drc_end_segments1.png"
|
||||
run_demo gen, "input.edges.end_segments(0, 0.5)", "drc_end_segments2.png"
|
||||
|
||||
run_demo gen, "input.edges.centers(1.um)", "drc_centers1.png"
|
||||
run_demo gen, "input.edges.centers(0, 0.5)", "drc_centers2.png"
|
||||
|
||||
run_demo gen, "input.edges.with_length(2.0)\n .extended(:out => 1.0)", "drc_extended1.png"
|
||||
run_demo gen, "input.edges.with_length(0, 3.5)\n .extended(:out => 1.0)", "drc_extended2.png"
|
||||
run_demo gen, "input.edges.with_length(0, 3.5)\n .extended(:out => 1.0, :joined => true)", "drc_extended3.png"
|
||||
run_demo gen, "input.edges.with_length(2.0)\n .extended(0.0, -0.5, 1.0, -0.5)", "drc_extended4.png"
|
||||
|
||||
class Gen
|
||||
def produce(s1, s2)
|
||||
pts = [
|
||||
RBA::Point::new(2000, 0),
|
||||
RBA::Point::new(2000, 2000),
|
||||
RBA::Point::new(4000, 2000),
|
||||
RBA::Point::new(4000, 6000),
|
||||
RBA::Point::new(5000, 6000),
|
||||
RBA::Point::new(5000, 0)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
pts = [
|
||||
RBA::Point::new(0, 3000),
|
||||
RBA::Point::new(3000, 3000),
|
||||
RBA::Point::new(3000, 4000),
|
||||
RBA::Point::new(1000, 4000),
|
||||
RBA::Point::new(1000, 7000),
|
||||
RBA::Point::new(0000, 7000)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
end
|
||||
end
|
||||
|
||||
gen = Gen::new
|
||||
|
||||
run_demo gen, "input.extents", "drc_extents1.png"
|
||||
run_demo gen, "input.edges.extents(0.1)", "drc_extents2.png"
|
||||
|
||||
|
||||
class Gen
|
||||
def produce(s1, s2)
|
||||
s1.insert(RBA::Box::new(0, 1000, 2000, 3000))
|
||||
s1.insert(RBA::Box::new(4000, 1000, 6000, 3000))
|
||||
s1.insert(RBA::Box::new(4000, 5000, 6000, 7000))
|
||||
s1.insert(RBA::Box::new(0, 4000, 2000, 6000))
|
||||
s2.insert(RBA::Box::new(1000, 0, 6000, 4000))
|
||||
end
|
||||
end
|
||||
|
||||
gen = Gen::new
|
||||
|
||||
run_demo gen, "input1.inside(input2)", "drc_inside.png"
|
||||
run_demo gen, "input1.not_inside(input2)", "drc_not_inside.png"
|
||||
run_demo gen, "input1.outside(input2)", "drc_outside.png"
|
||||
run_demo gen, "input1.not_outside(input2)", "drc_not_outside.png"
|
||||
run_demo gen, "input1.interacting(input2)", "drc_interacting.png"
|
||||
run_demo gen, "input1.not_interacting(input2)", "drc_not_interacting.png"
|
||||
run_demo gen, "input1.overlapping(input2)", "drc_overlapping.png"
|
||||
run_demo gen, "input1.not_overlapping(input2)", "drc_not_overlapping.png"
|
||||
run_demo gen, "input1.and(input2)", "drc_and1.png"
|
||||
run_demo gen, "input1.or(input2)", "drc_or1.png"
|
||||
run_demo gen, "input1.xor(input2)", "drc_xor1.png"
|
||||
run_demo gen, "input1.not(input2)", "drc_not1.png"
|
||||
run_demo gen, "input1.join(input2)", "drc_join1.png"
|
||||
run_demo gen, "input1.edges.and(input2.edges)", "drc_and2.png"
|
||||
run_demo gen, "input1.edges.or(input2.edges)", "drc_or2.png"
|
||||
run_demo gen, "input1.edges.xor(input2.edges)", "drc_xor2.png"
|
||||
run_demo gen, "input1.edges.not(input2.edges)", "drc_not2.png"
|
||||
run_demo gen, "input1.edges.join(input2.edges)", "drc_join2.png"
|
||||
run_demo gen, "input1.edges.and(input2)", "drc_and3.png"
|
||||
run_demo gen, "input1.edges.not(input2)", "drc_not3.png"
|
||||
run_demo gen, "input1.edges.inside_part(input2)", "drc_inside_part.png"
|
||||
run_demo gen, "input1.edges.outside_part(input2)", "drc_outside_part.png"
|
||||
|
||||
class Gen
|
||||
def produce(s1, s2)
|
||||
s1.insert(RBA::Box::new(0, 1000, 2000, 3000))
|
||||
s1.insert(RBA::Box::new(4000, 1000, 6000, 3000))
|
||||
s1.insert(RBA::Box::new(4000, 5000, 6000, 7000))
|
||||
s1.insert(RBA::Box::new(0, 4000, 2000, 6000))
|
||||
s2.insert(RBA::Box::new(4000, 1000, 6000, 3000))
|
||||
s2.insert(RBA::Box::new(1000, 0, 3000, 2000))
|
||||
end
|
||||
end
|
||||
|
||||
gen = Gen::new
|
||||
|
||||
run_demo gen, "input1.in(input2)", "drc_in.png"
|
||||
run_demo gen, "input1.not_in(input2)", "drc_not_in.png"
|
||||
|
||||
class Gen
|
||||
def produce(s1, s2)
|
||||
pts = [
|
||||
RBA::Point::new(0, 0),
|
||||
RBA::Point::new(0, 4000),
|
||||
RBA::Point::new(2000, 4000),
|
||||
RBA::Point::new(2000, 7000),
|
||||
RBA::Point::new(6000, 7000),
|
||||
RBA::Point::new(6000, 0)
|
||||
];
|
||||
h1 = [
|
||||
RBA::Point::new(1000, 1000),
|
||||
RBA::Point::new(1000, 3000),
|
||||
RBA::Point::new(3000, 3000),
|
||||
RBA::Point::new(3000, 1000)
|
||||
];
|
||||
h2 = [
|
||||
RBA::Point::new(3000, 4000),
|
||||
RBA::Point::new(3000, 6000),
|
||||
RBA::Point::new(5000, 6000),
|
||||
RBA::Point::new(5000, 4000)
|
||||
];
|
||||
poly = RBA::Polygon::new(pts)
|
||||
poly.insert_hole(h1)
|
||||
poly.insert_hole(h2)
|
||||
s1.insert(poly)
|
||||
end
|
||||
end
|
||||
|
||||
gen = Gen::new
|
||||
|
||||
run_demo gen, "input.hulls", "drc_hulls.png"
|
||||
run_demo gen, "input.holes", "drc_holes.png"
|
||||
|
||||
class Gen
|
||||
def produce(s1, s2)
|
||||
pts = [
|
||||
RBA::Point::new(1000, 1000),
|
||||
RBA::Point::new(4000, 1000),
|
||||
RBA::Point::new(4000, 3000),
|
||||
RBA::Point::new(1000, 3000)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
pts = [
|
||||
RBA::Point::new(0, 0),
|
||||
RBA::Point::new(0, 5000),
|
||||
RBA::Point::new(3000, 5000),
|
||||
RBA::Point::new(3000, 0)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
pts = [
|
||||
RBA::Point::new(2000, 2000),
|
||||
RBA::Point::new(6000, 2000),
|
||||
RBA::Point::new(6000, 7000),
|
||||
RBA::Point::new(2000, 7000)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
end
|
||||
end
|
||||
|
||||
gen = Gen::new
|
||||
|
||||
run_demo gen, "input.merged", "drc_merged1.png"
|
||||
run_demo gen, "input.merged(1)", "drc_merged2.png"
|
||||
run_demo gen, "input.merged(2)", "drc_merged3.png"
|
||||
run_demo gen, "input.merged(3)", "drc_merged4.png"
|
||||
|
||||
|
||||
class Gen
|
||||
def produce(s1, s2)
|
||||
pts = [
|
||||
RBA::Point::new(3000, 0),
|
||||
RBA::Point::new(3000, 2000),
|
||||
RBA::Point::new(5000, 2000),
|
||||
RBA::Point::new(5000, 6000),
|
||||
RBA::Point::new(6000, 6000),
|
||||
RBA::Point::new(6000, 0)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
pts = [
|
||||
RBA::Point::new(1000, 3000),
|
||||
RBA::Point::new(4000, 3000),
|
||||
RBA::Point::new(4000, 4000),
|
||||
RBA::Point::new(2000, 4000),
|
||||
RBA::Point::new(2000, 7000),
|
||||
RBA::Point::new(1000, 7000)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
end
|
||||
end
|
||||
|
||||
gen = Gen::new
|
||||
|
||||
run_demo gen, "input.moved(-1.5.um, 0.5.um)", "drc_moved1.png"
|
||||
run_demo gen, "input.rotated(15)", "drc_rotated1.png"
|
||||
run_demo gen, "input.scaled(0.75)", "drc_scaled1.png"
|
||||
run_demo gen, "t = RBA::DCplxTrans::new(0.75, 180.0, true, 7.0, 1.0)\ninput.transformed(t)", "drc_transformed1.png"
|
||||
|
||||
class Gen
|
||||
def produce(s1, s2)
|
||||
pts = [
|
||||
RBA::Point::new(2000, 1000),
|
||||
RBA::Point::new(2000, 1000),
|
||||
RBA::Point::new(4000, 5000),
|
||||
RBA::Point::new(4000, 1000)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
end
|
||||
end
|
||||
|
||||
gen = Gen::new
|
||||
|
||||
run_demo gen, "input.sized(1.um)", "drc_sized1.png"
|
||||
run_demo gen, "input.sized(1.5.um, 0.5.um)", "drc_sized2.png"
|
||||
run_demo gen, "input.sized(1.um, diamond_limit)", "drc_sized3.png"
|
||||
run_demo gen, "input.sized(1.um, octagon_limit)", "drc_sized4.png"
|
||||
run_demo gen, "input.sized(1.um, square_limit)", "drc_sized5.png"
|
||||
run_demo gen, "input.sized(1.um, acute_limit)", "drc_sized6.png"
|
||||
|
||||
class Gen
|
||||
def produce(s1, s2)
|
||||
pts = [
|
||||
RBA::Point::new(0, 0),
|
||||
RBA::Point::new(0, 1000),
|
||||
RBA::Point::new(4000, 5000),
|
||||
RBA::Point::new(4000, 7000),
|
||||
RBA::Point::new(6000, 5000),
|
||||
RBA::Point::new(6000, 0),
|
||||
RBA::Point::new(5000, 0),
|
||||
RBA::Point::new(5000, 4000),
|
||||
RBA::Point::new(1000, 0)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
end
|
||||
end
|
||||
|
||||
gen = Gen::new
|
||||
|
||||
run_demo gen, "input.edges.with_angle(45.degree)", "drc_with_angle1.png"
|
||||
run_demo gen, "h = input.edges.with_angle(0)\nv = input.edges.with_angle(90)\n(h + v)", "drc_with_angle2.png"
|
||||
run_demo gen, "input.with_angle(45.degree)", "drc_with_angle3.png"
|
||||
run_demo gen, "input.without_angle(45.1.degree, 315.degree)", "drc_with_angle4.png"
|
||||
|
||||
class Gen
|
||||
def produce(s1, s2)
|
||||
pts = [
|
||||
RBA::Point::new(0, 0),
|
||||
RBA::Point::new(0, 7000),
|
||||
RBA::Point::new(1000, 7000),
|
||||
RBA::Point::new(1000, 1000),
|
||||
RBA::Point::new(5000, 1000),
|
||||
RBA::Point::new(5000, 7000),
|
||||
RBA::Point::new(6000, 7000),
|
||||
RBA::Point::new(6000, 0)
|
||||
];
|
||||
s1.insert(RBA::Polygon::new(pts))
|
||||
end
|
||||
end
|
||||
|
||||
gen = Gen::new
|
||||
|
||||
run_demo gen, "input.rounded_corners(1.um, 2.um, 16)", "drc_rounded_corners.png"
|
||||
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
#!/usr/bin/ruby
|
||||
|
||||
$script_call = $0 + " " + ARGV.join(" ")
|
||||
|
||||
$key="%DRC%"
|
||||
$infile="src/lay/built_in_macros/drc.lym"
|
||||
$loc = "about/drc_ref"
|
||||
$outfiles="src/lay/doc"
|
||||
$title="DRC Reference"
|
||||
|
||||
def create_ref(s)
|
||||
if s =~ /(.*)#(.*)/
|
||||
"<a href=\"/" + $loc + "_" + $1.downcase + ".xml#" + $2 + "\">#{s}</a>"
|
||||
else
|
||||
"<a href=\"#" + s + "\">#{s}</a>"
|
||||
end
|
||||
end
|
||||
|
||||
def create_class_doc_ref(s)
|
||||
"<class_doc href=\"" + s + "\">#{s}</class_doc>"
|
||||
end
|
||||
|
||||
def escape(s)
|
||||
s.gsub("&", "&").
|
||||
gsub("<", "<").
|
||||
gsub(">", ">").
|
||||
gsub(/\\([\w#]+)/) { create_ref($1) }.
|
||||
gsub(/RBA::([\w#]+)/) { create_class_doc_ref($1) }
|
||||
end
|
||||
|
||||
def unescape(s)
|
||||
s.gsub("&", "&").gsub("<", "<").gsub(">", ">")
|
||||
end
|
||||
|
||||
class DocItem
|
||||
|
||||
attr_accessor :brief
|
||||
attr_accessor :synopsis
|
||||
attr_accessor :name
|
||||
attr_accessor :doc
|
||||
|
||||
def initialize(block)
|
||||
|
||||
@paragraphs = []
|
||||
para = nil
|
||||
self.synopsis = []
|
||||
in_code = false
|
||||
|
||||
block.each do |b|
|
||||
if in_code
|
||||
if b =~ /@\/code/
|
||||
in_code = false
|
||||
end
|
||||
para.push(b)
|
||||
elsif b =~ /^@brief\s+(.*?)\s*$/
|
||||
self.brief = $1
|
||||
elsif b =~ /^@name\s+(.*?)\s*$/
|
||||
self.name = $1
|
||||
elsif b =~ /^@synopsis\s+(.*?)\s*$/
|
||||
self.synopsis.push($1)
|
||||
elsif b =~ /^@scope/
|
||||
# ignore scope commands
|
||||
elsif b =~ /^\s*$/
|
||||
para && @paragraphs.push(para)
|
||||
para = nil
|
||||
else
|
||||
para ||= []
|
||||
para.push(b)
|
||||
if b =~ /@code/
|
||||
in_code = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
para && @paragraphs.push(para)
|
||||
|
||||
end
|
||||
|
||||
def produce_doc
|
||||
|
||||
if @paragraphs.empty?
|
||||
return ""
|
||||
end
|
||||
|
||||
doc = "<p>\n"
|
||||
|
||||
@paragraphs.each_with_index do |p, i|
|
||||
|
||||
i > 0 && doc += "</p><p>\n"
|
||||
|
||||
p.each do |pp|
|
||||
doc += escape(pp).
|
||||
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(/&at;/, "@")
|
||||
doc += "\n"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
doc += "</p>\n"
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Scope < DocItem
|
||||
|
||||
def initialize(block)
|
||||
super(block)
|
||||
@items = {}
|
||||
end
|
||||
|
||||
def add_doc_item(block)
|
||||
item = DocItem::new(block)
|
||||
@items[item.name] = item
|
||||
end
|
||||
|
||||
alias :super_produce_doc :produce_doc
|
||||
|
||||
def produce_doc
|
||||
|
||||
doc = <<HEAD
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE language SYSTEM "klayout_doc.dtd">
|
||||
|
||||
<!-- generated by #{$script_call} -->
|
||||
<!-- DO NOT EDIT! -->
|
||||
|
||||
HEAD
|
||||
|
||||
doc += "<doc>\n"
|
||||
doc += "<title>" + escape(self.brief) + "</title>\n"
|
||||
doc += "<keyword name=\"" + escape(self.name) + "\"/>\n"
|
||||
|
||||
doc += super_produce_doc
|
||||
|
||||
doc += "<h2-index/>\n"
|
||||
|
||||
@items.keys.sort.each do |item_key|
|
||||
|
||||
item = @items[item_key]
|
||||
|
||||
item.name || raise("Missing @name for item #{item_key}")
|
||||
item.brief || raise("Missing @brief for item #{item_key}")
|
||||
|
||||
doc += "<h2>\"" + escape(item.name) + "\" - " + escape(item.brief) + "</h2>\n"
|
||||
doc += "<keyword name=\"" + escape(item.name) + "\"/>\n"
|
||||
doc += "<a name=\"" + escape(item.name) + "\"/>"
|
||||
if ! item.synopsis.empty?
|
||||
doc += "<p>Usage:</p>\n"
|
||||
doc += "<ul>\n"
|
||||
item.synopsis.each do |s|
|
||||
doc += "<li><tt>" + escape(s) + "</tt></li>\n"
|
||||
end
|
||||
doc += "</ul>\n"
|
||||
end
|
||||
|
||||
doc += item.produce_doc
|
||||
|
||||
end
|
||||
|
||||
doc += "</doc>\n"
|
||||
|
||||
doc
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Collector
|
||||
|
||||
def add_block(block)
|
||||
|
||||
if block.find { |l| l =~ /^@scope/ }
|
||||
|
||||
# is a scope block
|
||||
@scopes ||= {}
|
||||
@current_scope = Scope::new(block)
|
||||
@scopes[@current_scope.name] = @current_scope
|
||||
|
||||
else
|
||||
@current_scope && @current_scope.add_doc_item(block)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def produce_doc
|
||||
|
||||
@scopes.keys.sort.each do |k|
|
||||
suffix = k.downcase
|
||||
outfile = $outfiles + "/" + $loc + "_" + suffix + ".xml"
|
||||
File.open(outfile, "w") do |file|
|
||||
file.write(@scopes[k].produce_doc)
|
||||
puts "---> #{outfile} written."
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def produce_index
|
||||
|
||||
outfile = $outfiles + "/" + $loc + ".xml"
|
||||
File.open(outfile, "w") do |file|
|
||||
|
||||
doc = <<HEAD
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE language SYSTEM "klayout_doc.dtd">
|
||||
|
||||
<!-- generated by #{$script_call} -->
|
||||
<!-- DO NOT EDIT! -->
|
||||
|
||||
HEAD
|
||||
|
||||
doc += "<doc>\n"
|
||||
|
||||
doc += "<title>#{escape($title)}</title>\n"
|
||||
|
||||
doc += "<topics>\n"
|
||||
|
||||
@scopes.keys.sort.each do |k|
|
||||
suffix = k.downcase
|
||||
doc += "<topic href=\"/#{$loc}_#{suffix}.xml\"/>\n"
|
||||
end
|
||||
|
||||
doc += "</topics>\n"
|
||||
doc += "</doc>\n"
|
||||
|
||||
file.write(doc)
|
||||
|
||||
end
|
||||
|
||||
puts "---> Index file #{outfile} written."
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
collector = Collector::new
|
||||
|
||||
File.open($infile, "r") do |file|
|
||||
|
||||
block = nil
|
||||
|
||||
file.each_line do |l|
|
||||
l = unescape(l)
|
||||
if l =~ /^\s*#\s*#{$key}/
|
||||
block = []
|
||||
elsif l =~ /^\s*#\s*(.*)\s*$/
|
||||
block && block.push($1)
|
||||
elsif l =~ /^\s*$/
|
||||
block && collector.add_block(block)
|
||||
block = nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
collector.produce_doc
|
||||
collector.produce_index
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
inst=$(realpath $(dirname $0))
|
||||
ld=$(realpath .)
|
||||
|
||||
bin="$ld/klayout"
|
||||
|
||||
export LD_LIBRARY_PATH=$ld
|
||||
|
||||
cd $inst/..
|
||||
|
||||
$bin -z -r $inst/create_drc_samples.rb -t -c $inst/klayoutrc_drc_samples
|
||||
$inst/extract_doc.rb
|
||||
|
||||
|
|
@ -805,16 +805,16 @@ CODE
|
|||
# @name texts
|
||||
# @brief Selects texts from an original layer
|
||||
# @synopsis layer.texts
|
||||
# @synopsis layer.texts(text)
|
||||
# @synopsis layer.texts(text, true)
|
||||
# @synopsis layer.texts(text, false)
|
||||
# @synopsis layer.texts(pattern)
|
||||
# @synopsis layer.texts(pattern, true)
|
||||
# @synopsis layer.texts(string, false)
|
||||
# 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 texts.
|
||||
# selected text.
|
||||
#
|
||||
# Texts can be selected either by exact match or pattern match with a
|
||||
# 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).
|
||||
# or exact match (false). The default is pattern match.
|
||||
#
|
||||
# @code
|
||||
# # Selects all texts
|
||||
|
|
@ -2666,17 +2666,18 @@ CODE
|
|||
|
||||
# %DRC%
|
||||
# @name output
|
||||
# @brief Output the content of the layer
|
||||
# @brief Outputs the content of the layer
|
||||
# @synopsis layer.output(specs)
|
||||
#
|
||||
# This method will output the content of the layer to the specified output.
|
||||
# This method will copy the content of the layer to the specified output.
|
||||
#
|
||||
# If a report database is selected for the output, the specification has to include a
|
||||
# category name and optionally a category description.
|
||||
#
|
||||
# If the layout is selected for the output, the specification can consist of
|
||||
# one to three parameters: a layer number, a data type (optional, default is 0)
|
||||
# and a layer name (optional).
|
||||
# and a layer name (optional). Alternatively, the output can be specified by
|
||||
# a single RBA::LayerInfo object.
|
||||
#
|
||||
# See \global#report and \global#target on how to configure output to a target layout
|
||||
# or report database.
|
||||
|
|
@ -2987,10 +2988,12 @@ CODE
|
|||
# @brief Specifies input from a source
|
||||
# @synopsis source.input(layer)
|
||||
# @synopsis source.input(layer, datatype)
|
||||
# @synopsis source.input(layer_into)
|
||||
# @synopsis source.input(filter, ...)
|
||||
# Creates a layer with the shapes from the given layer of the source.
|
||||
# The layer can be specified by layer and optionally datatype or by
|
||||
# a sequence of filters. Filters are expressions describing ranges
|
||||
# The layer can be specified by layer and optionally datatype, by a RBA::LayerInfo
|
||||
# object or by a sequence of filters.
|
||||
# Filters are expressions describing ranges
|
||||
# of layers and/or datatype numbers or layer names. Multiple filters
|
||||
# can be given and all layers matching at least one of these filter
|
||||
# expressions are joined to render the input layer for the DRC engine.
|
||||
|
|
@ -3015,6 +3018,11 @@ CODE
|
|||
li && layers.push(li)
|
||||
li && @tmp_layers.push(li)
|
||||
|
||||
elsif (args.size == 1 && args[0].is_a?(RBA::LayerInfo))
|
||||
|
||||
li = @layout.find_layer(args[0])
|
||||
li && layers.push(li)
|
||||
|
||||
elsif (args.size == 1 || args.size == 2) && args[0].is_a?(1.class)
|
||||
|
||||
li = @layout.find_layer(args[0], args[1] || 0)
|
||||
|
|
@ -3041,6 +3049,31 @@ CODE
|
|||
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name layers
|
||||
# @brief Gets the layers the source contains
|
||||
# @synopsis source.layers
|
||||
# Delivers a list of RBA::LayerInfo objects representing the layers
|
||||
# inside the source.
|
||||
#
|
||||
# One application is to read all layers from a source. In the following
|
||||
# example, the "and" operation is used to perform a clip with the given
|
||||
# rectangle. Note that this solution is not efficient - it's provided
|
||||
# as an example only:
|
||||
#
|
||||
# @code
|
||||
# output_cell("Clipped")
|
||||
#
|
||||
# clip_box = polygon_layer
|
||||
# clip_box.insert(box(0.um, -4.um, 4.um, 0.um))
|
||||
#
|
||||
# layers.each { |l| (input(l) & clip_box).output(l) }
|
||||
# @/code
|
||||
|
||||
def layers
|
||||
@layout.layer_indices.collect { |li| @layout.get_info(li) }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# The DRC engine
|
||||
|
|
@ -3772,6 +3805,16 @@ CODE
|
|||
layer.output(*args)
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name layers
|
||||
# @brief Gets the layers contained in the default source
|
||||
# @synopsis layers
|
||||
# See \Source#layers for a description of that function.
|
||||
|
||||
def layers
|
||||
layout.layers
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name cell
|
||||
# @brief Selects a cell for input on the default source
|
||||
|
|
@ -4172,6 +4215,8 @@ CODE
|
|||
if args.size == 1
|
||||
if args[0].is_a?(1.class)
|
||||
info = RBA::LayerInfo::new(args[0], 0)
|
||||
elsif args[0].is_a?(RBA::LayerInfo)
|
||||
info = args[0]
|
||||
elsif args[0].is_a?(String)
|
||||
info = RBA::LayerInfo::from_string(args[0])
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE language SYSTEM "klayout_doc.dtd">
|
||||
|
||||
<!-- generated by ./scripts/extract_doc.rb -->
|
||||
<!-- generated by /home/matthias/klayout/master/scripts/extract_doc.rb -->
|
||||
<!-- DO NOT EDIT! -->
|
||||
|
||||
<doc>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE language SYSTEM "klayout_doc.dtd">
|
||||
|
||||
<!-- generated by ./scripts/extract_doc.rb -->
|
||||
<!-- generated by /home/matthias/klayout/master/scripts/extract_doc.rb -->
|
||||
<!-- DO NOT EDIT! -->
|
||||
|
||||
<doc>
|
||||
|
|
@ -152,6 +152,15 @@ See <a href="/about/drc_ref_source.xml#input">Source#input</a> for a description
|
|||
<ul>
|
||||
<li><tt>is_tiled?</tt></li>
|
||||
</ul>
|
||||
<h2>"layers" - Gets the layers contained in the default source</h2>
|
||||
<keyword name="layers"/>
|
||||
<a name="layers"/><p>Usage:</p>
|
||||
<ul>
|
||||
<li><tt>layers</tt></li>
|
||||
</ul>
|
||||
<p>
|
||||
See <a href="/about/drc_ref_source.xml#layers">Source#layers</a> for a description of that function.
|
||||
</p>
|
||||
<h2>"layout" - Specifies an additional layout for the input source.</h2>
|
||||
<keyword name="layout"/>
|
||||
<a name="layout"/><p>Usage:</p>
|
||||
|
|
@ -339,7 +348,7 @@ is used as input.
|
|||
<ul>
|
||||
<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</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>
|
||||
</ul>
|
||||
</p><p>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE language SYSTEM "klayout_doc.dtd">
|
||||
|
||||
<!-- generated by ./scripts/extract_doc.rb -->
|
||||
<!-- generated by /home/matthias/klayout/master/scripts/extract_doc.rb -->
|
||||
<!-- DO NOT EDIT! -->
|
||||
|
||||
<doc>
|
||||
|
|
@ -960,21 +960,22 @@ on polygons and egdes (layer1: red, layer2: blue):
|
|||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
<h2>"output" - Output the content of the layer</h2>
|
||||
<h2>"output" - Outputs the content of the layer</h2>
|
||||
<keyword name="output"/>
|
||||
<a name="output"/><p>Usage:</p>
|
||||
<ul>
|
||||
<li><tt>layer.output(specs)</tt></li>
|
||||
</ul>
|
||||
<p>
|
||||
This method will output the content of the layer to the specified output.
|
||||
This method will copy the content of the layer to the specified output.
|
||||
</p><p>
|
||||
If a report database is selected for the output, the specification has to include a
|
||||
category name and optionally a category description.
|
||||
</p><p>
|
||||
If the layout is selected for the output, the specification can consist of
|
||||
one to three parameters: a layer number, a data type (optional, default is 0)
|
||||
and a layer name (optional).
|
||||
and a layer name (optional). Alternatively, the output can be specified by
|
||||
a single <class_doc href="LayerInfo">LayerInfo</class_doc> object.
|
||||
</p><p>
|
||||
See <a href="/about/drc_ref_global.xml#report">global#report</a> and <a href="/about/drc_ref_global.xml#target">global#target</a> on how to configure output to a target layout
|
||||
or report database.
|
||||
|
|
@ -1211,6 +1212,9 @@ The circles are approximated by polygons. "n" segments are used to approximate a
|
|||
</p><p>
|
||||
This method return a layer wit the modified polygons. Merged semantics applies for this
|
||||
method (see <a href="#raw">raw</a> and <a href="#clean">clean</a>).
|
||||
If used with tiling, the rounded_corners function may render invalid results because
|
||||
in tiling mode, not the whole merged region may be captured. In that case, inner
|
||||
edges may appear as outer ones and their corners will receive rounding.
|
||||
</p><p>
|
||||
The following image shows the effect of the "rounded_corners" method. The upper ends of
|
||||
the vertical bars are rounded with a smaller radius automatically because their width does not allow
|
||||
|
|
@ -1499,6 +1503,20 @@ The following images show the effect of various forms of the "sized" method:
|
|||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
<h2>"smoothed" - Smoothes the polygons of the region</h2>
|
||||
<keyword name="smoothed"/>
|
||||
<a name="smoothed"/><p>Usage:</p>
|
||||
<ul>
|
||||
<li><tt>layer.smoothed(d)</tt></li>
|
||||
</ul>
|
||||
<p>
|
||||
"Smoothing" returns a simplified version of the polygons. Simplification is
|
||||
achieved by removing vertices unless the resulting polygon deviates by more
|
||||
than the given distance d from the original polygon.
|
||||
</p><p>
|
||||
This method return a layer wit the modified polygons. Merged semantics applies for this
|
||||
method (see <a href="#raw">raw</a> and <a href="#clean">clean</a>).
|
||||
</p>
|
||||
<h2>"snap" - Brings each vertex on the given grid (g or gx/gy for x or y direction)</h2>
|
||||
<keyword name="snap"/>
|
||||
<a name="snap"/><p>Usage:</p>
|
||||
|
|
@ -1614,6 +1632,34 @@ See <a href="#strict">strict</a> for a discussion of strict handling.
|
|||
</p><p>
|
||||
This feature has been introduced in version 0.23.2.
|
||||
</p>
|
||||
<h2>"texts" - Selects texts from an original layer</h2>
|
||||
<keyword name="texts"/>
|
||||
<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>
|
||||
</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.
|
||||
</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.
|
||||
</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)
|
||||
# Selects all texts whose string is "A*"
|
||||
t = input(1, 0).texts("A*", false)
|
||||
</pre>
|
||||
</p>
|
||||
<h2>"transform" - Transforms a layer (modifies the layer)</h2>
|
||||
<keyword name="transform"/>
|
||||
<a name="transform"/><p>Usage:</p>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE language SYSTEM "klayout_doc.dtd">
|
||||
|
||||
<!-- generated by ./scripts/extract_doc.rb -->
|
||||
<!-- generated by /home/matthias/klayout/master/scripts/extract_doc.rb -->
|
||||
<!-- DO NOT EDIT! -->
|
||||
|
||||
<doc>
|
||||
|
|
@ -73,12 +73,14 @@ inverse_1 = extent.sized(100.0) - input(1, 0)
|
|||
<ul>
|
||||
<li><tt>source.input(layer)</tt></li>
|
||||
<li><tt>source.input(layer, datatype)</tt></li>
|
||||
<li><tt>source.input(layer_into)</tt></li>
|
||||
<li><tt>source.input(filter, ...)</tt></li>
|
||||
</ul>
|
||||
<p>
|
||||
Creates a layer with the shapes from the given layer of the source.
|
||||
The layer can be specified by layer and optionally datatype or by
|
||||
a sequence of filters. Filters are expressions describing ranges
|
||||
The layer can be specified by layer and optionally datatype, by a <class_doc href="LayerInfo">LayerInfo</class_doc>
|
||||
object or by a sequence of filters.
|
||||
Filters are expressions describing ranges
|
||||
of layers and/or datatype numbers or layer names. Multiple filters
|
||||
can be given and all layers matching at least one of these filter
|
||||
expressions are joined to render the input layer for the DRC engine.
|
||||
|
|
@ -93,6 +95,30 @@ Some filter expressions are:
|
|||
not have names)</li>
|
||||
</ul>
|
||||
</p>
|
||||
<h2>"layers" - Gets the layers the source contains</h2>
|
||||
<keyword name="layers"/>
|
||||
<a name="layers"/><p>Usage:</p>
|
||||
<ul>
|
||||
<li><tt>source.layers</tt></li>
|
||||
</ul>
|
||||
<p>
|
||||
Delivers a list of <class_doc href="LayerInfo">LayerInfo</class_doc> objects representing the layers
|
||||
inside the source.
|
||||
</p><p>
|
||||
One application is to read all layers from a source. In the following
|
||||
example, the "and" operation is used to perform a clip with the given
|
||||
rectangle. Note that this solution is not efficient - it's provided
|
||||
as an example only:
|
||||
</p><p>
|
||||
<pre>
|
||||
output_cell("Clipped")
|
||||
|
||||
clip_box = polygon_layer
|
||||
clip_box.insert(box(0.um, -4.um, 4.um, 0.um))
|
||||
|
||||
layers.each { |l| (input(l) & clip_box).output(l) }
|
||||
</pre>
|
||||
</p>
|
||||
<h2>"layout" - Returns the <class_doc href="Layout">Layout</class_doc> object associated with this source</h2>
|
||||
<keyword name="layout"/>
|
||||
<a name="layout"/><p>Usage:</p>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 3.6 KiB |
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
big_tests = false
|
||||
|
||||
verbose(true)
|
||||
|
||||
source(File.dirname(__FILE__) + "/drctest.gds", "TOPTOP")
|
||||
|
|
@ -23,11 +25,15 @@ def run_testsuite(dm, ic, tiled = false)
|
|||
|
||||
lb = 100
|
||||
|
||||
a = input(1)
|
||||
a = input(RBA::LayerInfo::new(1, 0))
|
||||
b = input(2)
|
||||
c = input(3)
|
||||
x = input(10)
|
||||
y = input(11)
|
||||
|
||||
h = {}
|
||||
layers.each { |l| h[l] = true }
|
||||
h[RBA::LayerInfo::new(1, 0)] || raise("missing layer 1/0 in layers list")
|
||||
|
||||
c.is_merged? == false || raise("unexpected value")
|
||||
|
||||
|
|
@ -40,7 +46,7 @@ def run_testsuite(dm, ic, tiled = false)
|
|||
a.and(b).xor(l1).is_empty? || raise("xor not empty")
|
||||
tiled || (a.and(b).is_merged? == true || raise("unexpected value"))
|
||||
|
||||
a.xor(b).output(lb + 1, dm)
|
||||
a.xor(b).output(RBA::LayerInfo::new(lb + 1, dm))
|
||||
a.xor(b).xor(a ^ b).is_empty? || raise("xor not empty")
|
||||
a.not(b).output(lb + 2, dm)
|
||||
a.not(b).xor(a - b).is_empty? || raise("xor not empty")
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
inst=$(dirname $0)
|
||||
|
||||
export LD_LIBRARY_PATH=.
|
||||
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
|
||||
|
||||
make klayout
|
||||
|
||||
|
|
|
|||