klayout/src/unit_tests/dbOASISWriter.cc

1732 lines
42 KiB
C++
Raw Normal View History

/*
KLayout Layout Viewer
Copyright (C) 2006-2016 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 "dbOASISWriter.h"
#include "dbGDS2Writer.h"
#include "dbOASISReader.h"
#include "dbGDS2Reader.h"
#include "dbLayoutDiff.h"
#include "dbWriter.h"
#include "dbTextWriter.h"
#include "utHead.h"
#include <cstdlib>
#include <QDir>
void run_test (ut::TestBase *_this, const char *file, bool scaling_test, int compr, bool recompress)
{
{
db::Manager m;
db::Layout layout_org (&m);
std::string fn (ut::testsrc ());
fn += "/testdata/oasis/";
fn += file;
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.set_warnings_as_errors (true);
reader.read (layout_org);
// in between test the capabilities of a layout to copy itself
db::Layout layout;
layout = layout_org;
layout_org.clear ();
std::string tmp_file = _this->tmp_file ("tmp_1.oas");
{
tl::OutputStream stream (tmp_file);
db::OASISWriter writer;
db::SaveLayoutOptions options;
writer.write (layout, stream, options);
}
db::Layout layout2 (&m);
{
tl::InputStream stream2 (tmp_file);
db::Reader reader2 (stream2);
db::LoadLayoutOptions options;
db::OASISReaderOptions oasis_options;
options.set_options (oasis_options);
reader2.set_warnings_as_errors (true);
reader2.read (layout2);
}
CHECKPOINT ();
bool equal = db::compare_layouts (layout, layout2, db::layout_diff::f_verbose | db::layout_diff::f_flatten_array_insts, 0);
if (! equal) {
_this->raise (tl::sprintf ("Compare failed - see %s vs %s\n", fn, tmp_file));
}
}
{
db::Manager m;
db::Layout layout_org (&m);
std::string fn (ut::testsrc ());
fn += "/testdata/oasis/";
fn += file;
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.set_warnings_as_errors (true);
reader.read (layout_org);
// in between test the capabilities of a layout to copy itself
db::Layout layout;
layout = layout_org;
layout_org.clear ();
// generate a "unique" name ...
unsigned int hash = 0;
for (const char *cp = file; *cp; ++cp) {
hash = (hash << 4) ^ (hash >> 4) ^ ((unsigned int) *cp);
}
std::string tmp_file = _this->tmp_file ("tmp_2.oas");
{
tl::OutputStream stream (tmp_file);
db::OASISWriter writer;
db::SaveLayoutOptions options;
db::OASISWriterOptions oasis_options;
oasis_options.write_cblocks = true;
oasis_options.strict_mode = true;
options.set_options (oasis_options);
writer.write (layout, stream, options);
}
db::Layout layout2 (&m);
{
tl::InputStream stream2 (tmp_file);
db::Reader reader2 (stream2);
db::LoadLayoutOptions options;
db::OASISReaderOptions oasis_options;
oasis_options.expect_strict_mode = 1;
options.set_options (oasis_options);
reader2.set_warnings_as_errors (true);
reader2.read (layout2, options);
}
CHECKPOINT ();
bool equal = db::compare_layouts (layout, layout2, db::layout_diff::f_verbose | db::layout_diff::f_flatten_array_insts, 0);
if (! equal) {
_this->raise (tl::sprintf ("Compare failed - see %s vs %s\n", fn, tmp_file));
}
}
{
db::Manager m;
db::Layout layout_org (&m);
std::string fn (ut::testsrc ());
fn += "/testdata/oasis/";
fn += file;
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (layout_org);
// in between test the capabilities of a layout to copy itself
db::Layout layout;
layout = layout_org;
layout_org.clear ();
std::string tmp_file = _this->tmp_file ("tmp_3.oas");
{
tl::OutputStream stream (tmp_file);
db::OASISWriter writer;
db::SaveLayoutOptions options;
db::OASISWriterOptions oasis_options;
oasis_options.strict_mode = false;
oasis_options.write_std_properties = 2;
options.set_options (oasis_options);
writer.write (layout, stream, options);
}
db::Layout layout2 (&m);
{
tl::InputStream stream2 (tmp_file);
db::Reader reader2 (stream2);
db::LoadLayoutOptions options;
db::OASISReaderOptions oasis_options;
oasis_options.expect_strict_mode = 0;
options.set_options (oasis_options);
reader2.set_warnings_as_errors (true);
reader2.read (layout2, options);
}
CHECKPOINT ();
bool equal = db::compare_layouts (layout, layout2, db::layout_diff::f_verbose | db::layout_diff::f_flatten_array_insts, 0);
if (! equal) {
_this->raise (tl::sprintf ("Compare failed - see %s vs %s\n", fn, tmp_file));
}
}
{
db::Manager m;
db::Layout layout_org (&m);
std::string fn (ut::testsrc ());
fn += "/testdata/oasis/";
fn += file;
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (layout_org);
// in between test the capabilities of a layout to copy itself
db::Layout layout;
layout = layout_org;
layout_org.clear ();
std::string tmp_file = _this->tmp_file ("tmp_4.oas");
{
tl::OutputStream stream (tmp_file);
db::OASISWriter writer;
db::SaveLayoutOptions options;
db::OASISWriterOptions oasis_options;
oasis_options.write_cblocks = true;
oasis_options.strict_mode = true;
oasis_options.write_std_properties = 2;
options.set_options (oasis_options);
writer.write (layout, stream, options);
}
db::Layout layout2 (&m);
{
tl::InputStream stream2 (tmp_file);
db::Reader reader2 (stream2);
db::LoadLayoutOptions options;
db::OASISReaderOptions oasis_options;
oasis_options.expect_strict_mode = 1;
options.set_options (oasis_options);
reader2.set_warnings_as_errors (true);
reader2.read (layout2, options);
}
CHECKPOINT ();
bool equal = db::compare_layouts (layout, layout2, db::layout_diff::f_verbose | db::layout_diff::f_flatten_array_insts, 0);
if (! equal) {
_this->raise (tl::sprintf ("Compare failed - see %s vs %s\n", fn, tmp_file));
}
}
if (scaling_test) {
db::Manager m;
db::Layout layout (&m);
std::string fn (ut::testsrc ());
fn += "/testdata/oasis/";
fn += file;
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (layout);
db::SaveLayoutOptions options;
db::OASISWriterOptions oasis_options;
oasis_options.compression_level = compr;
oasis_options.recompress = recompress;
options.set_options (oasis_options);
options.set_scale_factor (3.0);
options.set_dbu (0.0005);
// generate a "unique" name ...
unsigned int hash = 0;
for (const char *cp = file; *cp; ++cp) {
hash = (hash << 4) ^ (hash >> 4) ^ ((unsigned int) *cp);
}
std::string tmp1_file = _this->tmp_file ("tmp_s1.gds");
std::string tmp2_file = _this->tmp_file ("tmp_s2.oas");
{
tl::OutputStream stream (tmp1_file);
db::GDS2Writer writer;
writer.write (layout, stream, options);
}
{
tl::OutputStream stream (tmp2_file);
db::OASISWriter writer;
writer.write (layout, stream, options);
}
db::Layout layout1 (&m);
{
tl::InputStream file (tmp1_file);
db::Reader reader (file);
reader.read (layout1);
}
db::Layout layout2 (&m);
{
tl::InputStream file (tmp2_file);
db::Reader reader (file);
reader.read (layout2);
}
CHECKPOINT ();
bool equal = db::compare_layouts (layout1, layout2, db::layout_diff::f_verbose | db::layout_diff::f_flatten_array_insts | db::layout_diff::f_no_properties | db::layout_diff::f_no_layer_names | db::layout_diff::f_boxes_as_polygons, 0);
if (! equal) {
_this->raise (tl::sprintf ("Compare failed - see %s vs %s\n", tmp1_file, tmp2_file));
}
}
}
void run_test (ut::TestBase *_this, const char *file, bool scaling_test = true)
{
for (int recompress = 0; recompress < 2; ++recompress) {
run_test (_this, file, scaling_test, 0, recompress);
run_test (_this, file, scaling_test, 1, recompress);
run_test (_this, file, scaling_test, 2, recompress);
run_test (_this, file, scaling_test, 10, recompress);
}
}
TEST(1)
{
run_test (_this, "t10.1.oas");
}
TEST(2)
{
run_test (_this, "t11.1.oas");
}
TEST(3)
{
run_test (_this, "t11.2.oas");
}
TEST(4)
{
run_test (_this, "t11.3.oas");
}
TEST(4A)
{
run_test (_this, "t11.4.oas");
}
TEST(5)
{
run_test (_this, "t1.1.oas");
}
TEST(6)
{
run_test (_this, "t12.1.oas");
}
TEST(7)
{
run_test (_this, "t1.2.oas");
}
TEST(8)
{
run_test (_this, "t13.1.oas");
}
TEST(9)
{
run_test (_this, "t13.2.oas");
}
TEST(10)
{
run_test (_this, "t13.3.oas");
}
TEST(11)
{
run_test (_this, "t1.3.oas");
}
TEST(12)
{
run_test (_this, "t14.1.oas");
}
TEST(13)
{
run_test (_this, "t1.4.oas");
}
TEST(14)
{
run_test (_this, "t1.5.oas");
}
TEST(15)
{
run_test (_this, "t2.1.oas");
}
TEST(16)
{
run_test (_this, "t2.2.oas");
}
TEST(17)
{
run_test (_this, "t2.4.oas");
}
TEST(19)
{
run_test (_this, "t3.10.oas");
}
TEST(20)
{
run_test (_this, "t3.1.oas");
}
TEST(21)
{
run_test (_this, "t3.2.oas");
}
TEST(22)
{
run_test (_this, "t3.5.oas");
}
TEST(23)
{
run_test (_this, "t3.9.oas");
}
TEST(24)
{
run_test (_this, "t4.1.oas");
}
TEST(25)
{
run_test (_this, "t4.2.oas");
}
TEST(26)
{
run_test (_this, "t5.1.oas");
}
TEST(27)
{
// no scaling test, since this test contains polygons with >8000 points that cannot be written to GDS
run_test (_this, "t5.2.oas", false);
}
TEST(28)
{
run_test (_this, "t5.3.oas");
}
TEST(29)
{
run_test (_this, "t6.1.oas");
}
TEST(30)
{
run_test (_this, "t7.1.oas");
}
TEST(31)
{
run_test (_this, "t8.1.oas");
}
TEST(32)
{
run_test (_this, "t8.2.oas");
}
TEST(33)
{
run_test (_this, "t8.3.oas");
}
TEST(34)
{
run_test (_this, "t8.4.oas");
}
TEST(35)
{
run_test (_this, "t8.5.oas");
}
TEST(36)
{
run_test (_this, "t8.6.oas");
}
TEST(37)
{
run_test (_this, "t8.7.oas");
}
TEST(38)
{
run_test (_this, "t8.8.oas");
}
TEST(39)
{
run_test (_this, "t9.1.oas");
}
TEST(40)
{
run_test (_this, "t9.2.oas");
}
TEST(100)
{
db::Manager m;
db::Layout g (&m);
db::LayerProperties lp0;
lp0.layer = 0;
lp0.datatype = 0;
db::LayerProperties lp1;
lp1.layer = 1;
lp1.datatype = 0;
db::LayerProperties lp2;
lp2.layer = 2;
lp2.datatype = 0;
g.insert_layer (0, lp0);
g.insert_layer (1, lp1);
g.insert_layer (2, lp2);
db::Cell &c1 (g.cell (g.add_cell ()));
db::Cell &c2 (g.cell (g.add_cell ()));
db::Cell &c3 (g.cell (g.add_cell ()));
db::Cell &c4 (g.cell (g.add_cell ()));
db::Box b (0, 100, 1000, 1200);
c1.shapes (1).insert (b);
db::Box bb (0, -100, 2000, 2200);
c2.shapes (2).insert (bb);
// inserting instances ..
db::FTrans f (1, true);
db::Vector p (-10, 20);
db::Trans t (f.rot (), p);
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter100.gds"));
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions options;
options.set_format ("OASIS");
db::Writer writer (options);
writer.write (g, out);
}
tl::InputStream in (tmp_file);
db::Reader reader (in);
db::Layout gg;
reader.set_warnings_as_errors (true);
reader.read (gg);
const char *expected =
"begin_lib 0.001\n"
"begin_cell {$1}\n"
"box 1 0 {0 100} {1000 1200}\n"
"end_cell\n"
"begin_cell {$4}\n"
"end_cell\n"
"begin_cell {$3}\n"
"sref {$4} 90 1 1 {-10 20}\n"
"sref {$1} 90 1 1 {-10 20}\n"
"end_cell\n"
"begin_cell {$2}\n"
"sref {$3} 90 1 1 {-10 20}\n"
"sref {$1} 90 1 1 {-10 20}\n"
"box 2 0 {0 -100} {2000 2200}\n"
"end_cell\n"
"end_lib\n"
;
tl::OutputStringStream os;
tl::OutputStream stream (os);
db::TextWriter textwriter (stream);
textwriter.write (gg);
EXPECT_EQ (std::string (os.string ()), std::string (expected))
}
TEST(101)
{
db::Manager m;
db::Layout g (&m);
db::LayerProperties lp0;
lp0.layer = 0;
lp0.datatype = 0;
db::LayerProperties lp1;
lp1.layer = 1;
lp1.datatype = 0;
db::LayerProperties lp2;
lp2.layer = 2;
lp2.datatype = 0;
g.insert_layer (0, lp0);
g.insert_layer (1, lp1);
g.insert_layer (2, lp2);
db::Cell &c1 (g.cell (g.add_cell ()));
db::Cell &c2 (g.cell (g.add_cell ()));
db::Cell &c3 (g.cell (g.add_cell ()));
db::Cell &c4 (g.cell (g.add_cell ()));
db::Box b (0, 100, 1000, 1200);
c1.shapes (1).insert (b);
db::Box bb (0, -100, 2000, 2200);
c2.shapes (2).insert (bb);
// inserting instances ..
db::FTrans f (1, true);
db::Vector p (-10, 20);
db::Trans t (f.rot (), p);
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter101.gds"));
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions options;
options.set_format ("OASIS");
options.add_layer (0);
options.set_dont_write_empty_cells (true);
db::Writer writer (options);
writer.write (g, out);
}
tl::InputStream in (tmp_file);
db::Reader reader (in);
db::Layout gg;
reader.set_warnings_as_errors (true);
reader.read (gg);
const char *expected =
"begin_lib 0.001\n"
"begin_cell {$2}\n"
"end_cell\n"
"end_lib\n"
;
tl::OutputStringStream os;
tl::OutputStream stream (os);
db::TextWriter textwriter (stream);
textwriter.write (gg);
EXPECT_EQ (std::string (os.string ()), std::string (expected))
}
TEST(102)
{
db::Manager m;
db::Layout g (&m);
db::LayerProperties lp0;
lp0.layer = 0;
lp0.datatype = 0;
db::LayerProperties lp1;
lp1.layer = 1;
lp1.datatype = 0;
db::LayerProperties lp2;
lp2.layer = 2;
lp2.datatype = 0;
g.insert_layer (0, lp0);
g.insert_layer (1, lp1);
g.insert_layer (2, lp2);
db::Cell &c1 (g.cell (g.add_cell ()));
db::Cell &c2 (g.cell (g.add_cell ()));
db::Cell &c3 (g.cell (g.add_cell ()));
db::Cell &c4 (g.cell (g.add_cell ()));
db::Box b (0, 100, 1000, 1200);
c1.shapes (1).insert (b);
db::Box bb (0, -100, 2000, 2200);
c2.shapes (2).insert (bb);
// inserting instances ..
db::FTrans f (1, true);
db::Vector p (-10, 20);
db::Trans t (f.rot (), p);
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter102.gds"));
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions options;
options.set_format ("OASIS");
options.add_layer (1);
options.set_dont_write_empty_cells (true);
db::Writer writer (options);
writer.write (g, out);
}
tl::InputStream in (tmp_file);
db::Reader reader (in);
db::Layout gg;
reader.set_warnings_as_errors (true);
reader.read (gg);
const char *expected =
"begin_lib 0.001\n"
"begin_cell {$1}\n"
"box 1 0 {0 100} {1000 1200}\n"
"end_cell\n"
"begin_cell {$3}\n"
"sref {$1} 90 1 1 {-10 20}\n"
"end_cell\n"
"begin_cell {$2}\n"
"sref {$3} 90 1 1 {-10 20}\n"
"sref {$1} 90 1 1 {-10 20}\n"
"end_cell\n"
"end_lib\n"
;
tl::OutputStringStream os;
tl::OutputStream stream (os);
db::TextWriter textwriter (stream);
textwriter.write (gg);
EXPECT_EQ (std::string (os.string ()), std::string (expected))
}
TEST(103)
{
db::Manager m;
db::Layout g (&m);
db::LayerProperties lp0;
lp0.layer = 0;
lp0.datatype = 0;
db::LayerProperties lp1;
lp1.layer = 1;
lp1.datatype = 0;
db::LayerProperties lp2;
lp2.layer = 2;
lp2.datatype = 0;
g.insert_layer (0, lp0);
g.insert_layer (1, lp1);
g.insert_layer (2, lp2);
db::Cell &c1 (g.cell (g.add_cell ()));
db::Cell &c2 (g.cell (g.add_cell ()));
db::Cell &c3 (g.cell (g.add_cell ()));
db::Cell &c4 (g.cell (g.add_cell ()));
db::Box b (0, 100, 1000, 1200);
c1.shapes (1).insert (b);
db::Box bb (0, -100, 2000, 2200);
c2.shapes (2).insert (bb);
// inserting instances ..
db::FTrans f (1, true);
db::Vector p (-10, 20);
db::Trans t (f.rot (), p);
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter103.gds"));
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions options;
options.set_format ("OASIS");
options.add_layer (2);
options.set_dont_write_empty_cells (true);
db::Writer writer (options);
writer.write (g, out);
}
tl::InputStream in (tmp_file);
db::Reader reader (in);
db::Layout gg;
reader.set_warnings_as_errors (true);
reader.read (gg);
const char *expected =
"begin_lib 0.001\n"
"begin_cell {$2}\n"
"box 2 0 {0 -100} {2000 2200}\n"
"end_cell\n"
"end_lib\n"
;
tl::OutputStringStream os;
tl::OutputStream stream (os);
db::TextWriter textwriter (stream);
textwriter.write (gg);
EXPECT_EQ (std::string (os.string ()), std::string (expected))
}
TEST(110)
{
db::Manager m;
db::Layout g (&m);
db::LayerProperties lp0;
lp0.layer = 0;
lp0.datatype = 0;
db::LayerProperties lp1;
lp1.layer = 1;
lp1.datatype = 0;
db::LayerProperties lp2;
lp2.layer = 2;
lp2.datatype = 0;
g.insert_layer (0, lp0);
g.insert_layer (1, lp1);
g.insert_layer (2, lp2);
db::Cell &c1 (g.cell (g.add_cell ()));
db::Cell &c2 (g.cell (g.add_cell ()));
db::Cell &c3 (g.cell (g.add_cell ()));
db::Cell &c4 (g.cell (g.add_cell ()));
db::Box b (0, 100, 1000, 1200);
c1.shapes (1).insert (b);
db::Box bb (0, -100, 2000, 2200);
c2.shapes (2).insert (bb);
// inserting instances ..
db::FTrans f (1, true);
db::Vector p (-10, 20);
db::Trans t (f.rot (), p);
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter110.gds"));
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions options;
options.set_format ("OASIS");
options.set_dont_write_empty_cells (true);
options.add_cell (c3.cell_index ());
db::Writer writer (options);
writer.write (g, out);
}
tl::InputStream in (tmp_file);
db::Reader reader (in);
db::Layout gg;
reader.set_warnings_as_errors (true);
reader.read (gg);
const char *expected =
"begin_lib 0.001\n"
"begin_cell {$1}\n"
"box 1 0 {0 100} {1000 1200}\n"
"end_cell\n"
"begin_cell {$3}\n"
"sref {$1} 90 1 1 {-10 20}\n"
"end_cell\n"
"end_lib\n"
;
tl::OutputStringStream os;
tl::OutputStream stream (os);
db::TextWriter textwriter (stream);
textwriter.write (gg);
EXPECT_EQ (std::string (os.string ()), std::string (expected))
}
TEST(111)
{
db::Manager m;
db::Layout g (&m);
db::LayerProperties lp0;
lp0.layer = 0;
lp0.datatype = 0;
db::LayerProperties lp1;
lp1.layer = 1;
lp1.datatype = 0;
db::LayerProperties lp2;
lp2.layer = 2;
lp2.datatype = 0;
g.insert_layer (0, lp0);
g.insert_layer (1, lp1);
g.insert_layer (2, lp2);
db::Cell &c1 (g.cell (g.add_cell ()));
db::Cell &c2 (g.cell (g.add_cell ()));
db::Cell &c3 (g.cell (g.add_cell ()));
db::Cell &c4 (g.cell (g.add_cell ()));
db::Box b (0, 100, 1000, 1200);
c1.shapes (1).insert (b);
db::Box bb (0, -100, 2000, 2200);
c2.shapes (2).insert (bb);
// inserting instances ..
db::FTrans f (1, true);
db::Vector p (-10, 20);
db::Trans t (f.rot (), p);
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter111.gds"));
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions options;
options.set_format ("OASIS");
options.add_cell (c3.cell_index ());
options.add_layer (0);
options.set_dont_write_empty_cells (true);
db::Writer writer (options);
writer.write (g, out);
}
tl::InputStream in (tmp_file);
db::Reader reader (in);
db::Layout gg;
reader.set_warnings_as_errors (true);
reader.read (gg);
const char *expected =
"begin_lib 0.001\n"
"begin_cell {$3}\n"
"end_cell\n"
"end_lib\n"
;
tl::OutputStringStream os;
tl::OutputStream stream (os);
db::TextWriter textwriter (stream);
textwriter.write (gg);
EXPECT_EQ (std::string (os.string ()), std::string (expected))
}
TEST(112)
{
db::Manager m;
db::Layout g (&m);
db::LayerProperties lp0;
lp0.layer = 0;
lp0.datatype = 0;
db::LayerProperties lp1;
lp1.layer = 1;
lp1.datatype = 0;
db::LayerProperties lp2;
lp2.layer = 2;
lp2.datatype = 0;
g.insert_layer (0, lp0);
g.insert_layer (1, lp1);
g.insert_layer (2, lp2);
db::Cell &c1 (g.cell (g.add_cell ()));
db::Cell &c2 (g.cell (g.add_cell ()));
db::Cell &c3 (g.cell (g.add_cell ()));
db::Cell &c4 (g.cell (g.add_cell ()));
db::Box b (0, 100, 1000, 1200);
c1.shapes (1).insert (b);
db::Box bb (0, -100, 2000, 2200);
c2.shapes (2).insert (bb);
// inserting instances ..
db::FTrans f (1, true);
db::Vector p (-10, 20);
db::Trans t (f.rot (), p);
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter112.gds"));
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions options;
options.set_format ("OASIS");
options.add_cell (c3.cell_index ());
options.add_layer (1);
options.set_dont_write_empty_cells (true);
db::Writer writer (options);
writer.write (g, out);
}
tl::InputStream in (tmp_file);
db::Reader reader (in);
db::Layout gg;
reader.set_warnings_as_errors (true);
reader.read (gg);
const char *expected =
"begin_lib 0.001\n"
"begin_cell {$1}\n"
"box 1 0 {0 100} {1000 1200}\n"
"end_cell\n"
"begin_cell {$3}\n"
"sref {$1} 90 1 1 {-10 20}\n"
"end_cell\n"
"end_lib\n"
;
tl::OutputStringStream os;
tl::OutputStream stream (os);
db::TextWriter textwriter (stream);
textwriter.write (gg);
EXPECT_EQ (std::string (os.string ()), std::string (expected))
}
TEST(113)
{
db::Manager m;
db::Layout g (&m);
db::LayerProperties lp0;
lp0.layer = 0;
lp0.datatype = 0;
db::LayerProperties lp1;
lp1.layer = 1;
lp1.datatype = 0;
db::LayerProperties lp2;
lp2.layer = 2;
lp2.datatype = 0;
g.insert_layer (0, lp0);
g.insert_layer (1, lp1);
g.insert_layer (2, lp2);
db::Cell &c1 (g.cell (g.add_cell ()));
db::Cell &c2 (g.cell (g.add_cell ()));
db::Cell &c3 (g.cell (g.add_cell ()));
db::Cell &c4 (g.cell (g.add_cell ()));
db::Box b (0, 100, 1000, 1200);
c1.shapes (1).insert (b);
db::Box bb (0, -100, 2000, 2200);
c2.shapes (2).insert (bb);
// inserting instances ..
db::FTrans f (1, true);
db::Vector p (-10, 20);
db::Trans t (f.rot (), p);
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), t));
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c3.cell_index ()), t));
c3.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c4.cell_index ()), t));
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter113.gds"));
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions options;
options.set_format ("OASIS");
options.add_cell (c3.cell_index ());
options.add_layer (2);
options.set_dont_write_empty_cells (true);
db::Writer writer (options);
writer.write (g, out);
}
tl::InputStream in (tmp_file);
db::Reader reader (in);
db::Layout gg;
reader.set_warnings_as_errors (true);
reader.read (gg);
const char *expected =
"begin_lib 0.001\n"
"begin_cell {$3}\n"
"end_cell\n"
"end_lib\n"
;
tl::OutputStringStream os;
tl::OutputStream stream (os);
db::TextWriter textwriter (stream);
textwriter.write (gg);
EXPECT_EQ (std::string (os.string ()), std::string (expected))
}
TEST(114)
{
db::Manager m;
db::Layout g (&m);
db::LayerProperties lp1;
lp1.layer = 1;
lp1.datatype = 0;
g.insert_layer (1, lp1);
db::Cell &c1 (g.cell (g.add_cell ()));
db::Edge e1 (0, 100, 1000, 1200);
c1.shapes (1).insert (e1);
db::Edge e2 (0, 100, 0, 1200);
c1.shapes (1).insert (e2);
db::Edge e3 (0, 1200, 1000, 1200);
c1.shapes (1).insert (e3);
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter114.gds"));
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions options;
options.set_format ("OASIS");
db::Writer writer (options);
writer.write (g, out);
}
tl::InputStream in (tmp_file);
db::Reader reader (in);
db::Layout gg;
reader.set_warnings_as_errors (true);
reader.read (gg);
const char *expected =
"begin_lib 0.001\n"
"begin_cell {$1}\n"
"path 1 0 0 0 0 {0 100} {0 1200}\n"
"path 1 0 0 0 0 {0 1200} {1000 1200}\n"
"path 1 0 0 0 0 {0 100} {1000 1200}\n"
"end_cell\n"
"end_lib\n"
;
tl::OutputStringStream os;
tl::OutputStream stream (os);
db::TextWriter textwriter (stream);
textwriter.write (gg);
EXPECT_EQ (std::string (os.string ()), std::string (expected))
}
TEST(115)
{
db::Manager m;
db::Layout g (&m);
db::property_names_id_type n1, n2, n3;
n1 = g.properties_repository ().prop_name_id (tl::Variant (17));
n2 = g.properties_repository ().prop_name_id (tl::Variant ("name"));
n3 = g.properties_repository ().prop_name_id (tl::Variant ((unsigned int) 42));
db::PropertiesRepository::properties_set s1;
s1.insert (std::make_pair (n1, tl::Variant ("17value")));
s1.insert (std::make_pair (n2, tl::Variant (117)));
db::PropertiesRepository::properties_set s2;
s2.insert (std::make_pair (n3, tl::Variant (42)));
db::properties_id_type p1 = g.properties_repository ().properties_id (s1);
db::properties_id_type p2 = g.properties_repository ().properties_id (s2);
g.prop_id (p1);
db::LayerProperties lp1;
lp1.layer = 1;
lp1.datatype = 0;
g.insert_layer (1, lp1);
db::Cell &c1 (g.cell (g.add_cell ()));
c1.prop_id (p2);
db::Edge e1 (0, 100, 1000, 1200);
c1.shapes (1).insert (e1);
db::Edge e2 (0, 100, 0, 1200);
c1.shapes (1).insert (e2);
db::Edge e3 (0, 1200, 1000, 1200);
c1.shapes (1).insert (e3);
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter115.gds"));
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions options;
options.set_format ("OASIS");
db::Writer writer (options);
writer.write (g, out);
}
tl::InputStream in (tmp_file);
db::Reader reader (in);
db::Layout gg;
reader.set_warnings_as_errors (true);
reader.read (gg);
const char *expected =
"set props {\n"
" {17 {17value}}\n"
" {{name} {117}}\n"
"}\n"
"begin_libp $props 0.001\n"
"set props {\n"
" {42 {42}}\n"
"}\n"
"begin_cellp $props {$1}\n"
"path 1 0 0 0 0 {0 100} {0 1200}\n"
"path 1 0 0 0 0 {0 1200} {1000 1200}\n"
"path 1 0 0 0 0 {0 100} {1000 1200}\n"
"end_cell\n"
"end_lib\n"
;
tl::OutputStringStream os;
tl::OutputStream stream (os);
db::TextWriter textwriter (stream);
textwriter.write (gg);
EXPECT_EQ (std::string (os.string ()), std::string (expected))
}
TEST(118)
{
// 1x1 arrays (#902)
db::Manager m;
db::Layout g (&m);
db::LayerProperties lp1;
lp1.layer = 1;
lp1.datatype = 0;
g.insert_layer (0, lp1);
db::Cell &c1 (g.cell (g.add_cell ()));
c1.shapes (0).insert (db::Box (100, 0, 100, 200));
db::Cell &c2 (g.cell (g.add_cell ()));
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), db::Trans (), db::Vector (0, 1), db::Vector (1, 0), 1, 1));
c2.insert (db::array <db::CellInst, db::Trans> (db::CellInst (c1.cell_index ()), db::Trans (db::Vector (17, -42)), db::Vector (0, 1), db::Vector (1, 0), 1, 1));
std::string tmp_file = ut::TestBase::tmp_file ("tmp.oas");
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions options;
options.set_format ("OASIS");
db::Writer writer (options);
writer.write (g, out);
}
tl::InputStream in (tmp_file);
db::Reader reader (in);
db::Layout gg;
reader.set_warnings_as_errors (true);
reader.read (gg);
const char *expected =
"begin_lib 0.001\n"
"begin_cell {$1}\n"
"box 1 0 {100 0} {100 200}\n"
"end_cell\n"
"begin_cell {$2}\n"
"sref {$1} 0 0 1 {17 -42}\n"
"sref {$1} 0 0 1 {0 0}\n"
"end_cell\n"
"end_lib\n"
;
tl::OutputStringStream os;
tl::OutputStream stream (os);
db::TextWriter textwriter (stream);
textwriter.write (gg);
EXPECT_EQ (std::string (os.string ()), std::string (expected))
}
TEST(116)
{
db::Manager m;
db::Layout g (&m);
db::property_names_id_type n1, n2, n3;
n1 = g.properties_repository ().prop_name_id (tl::Variant (17));
n2 = g.properties_repository ().prop_name_id (tl::Variant ("name"));
n3 = g.properties_repository ().prop_name_id (tl::Variant ((unsigned int) 42));
db::PropertiesRepository::properties_set s1;
s1.insert (std::make_pair (n1, tl::Variant ("17value")));
s1.insert (std::make_pair (n2, tl::Variant (117)));
db::PropertiesRepository::properties_set s2;
s2.insert (std::make_pair (n3, tl::Variant (42)));
db::properties_id_type p1 = g.properties_repository ().properties_id (s1);
db::properties_id_type p2 = g.properties_repository ().properties_id (s2);
g.prop_id (p1);
db::LayerProperties lp1;
lp1.layer = 1;
lp1.datatype = 0;
g.insert_layer (1, lp1);
db::Cell &c1 (g.cell (g.add_cell ()));
c1.prop_id (p2);
db::Edge e1 (0, 100, 1000, 1200);
c1.shapes (1).insert (e1);
db::Cell &c2 (g.cell (g.add_cell ()));
{
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter116a.gds"));
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions write_options;
write_options.set_format ("OASIS");
db::Writer writer (write_options);
writer.write (g, out);
}
tl::InputStream in (tmp_file);
db::OASISReaderOptions oas_options;
oas_options.read_all_properties = true;
db::LoadLayoutOptions options;
options.set_options (oas_options);
db::Reader reader (in);
db::Layout gg;
reader.set_warnings_as_errors (true);
reader.read (gg, options);
const char *expected =
"set props {\n"
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
" {{S_TOP_CELL} {$2}}\n"
" {{S_TOP_CELL} {$1}}\n"
" {17 {17value}}\n"
" {{name} {117}}\n"
"}\n"
"begin_libp $props 0.001\n"
"set props {\n"
" {42 {42}}\n"
"}\n"
"begin_cellp $props {$1}\n"
"path 1 0 0 0 0 {0 100} {1000 1200}\n"
"end_cell\n"
"begin_cell {$2}\n"
"end_cell\n"
"end_lib\n"
;
tl::OutputStringStream os;
tl::OutputStream stream (os);
db::TextWriter textwriter (stream);
textwriter.write (gg);
EXPECT_EQ (std::string (os.string ()), std::string (expected))
}
{
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter116b.gds"));
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions write_options;
write_options.set_format ("OASIS");
db::OASISWriterOptions oas_write_options;
oas_write_options.write_std_properties = 0;
write_options.set_options (oas_write_options);
db::Writer writer (write_options);
writer.write (g, out);
}
tl::InputStream in (tmp_file);
db::OASISReaderOptions oas_options;
oas_options.read_all_properties = true;
oas_options.expect_strict_mode = 0;
db::LoadLayoutOptions options;
options.set_options (oas_options);
db::Reader reader (in);
db::Layout gg;
reader.set_warnings_as_errors (true);
reader.read (gg, options);
const char *expected =
"set props {\n"
" {17 {17value}}\n"
" {{name} {117}}\n"
"}\n"
"begin_libp $props 0.001\n"
"set props {\n"
" {42 {42}}\n"
"}\n"
"begin_cellp $props {$1}\n"
"path 1 0 0 0 0 {0 100} {1000 1200}\n"
"end_cell\n"
"begin_cell {$2}\n"
"end_cell\n"
"end_lib\n"
;
tl::OutputStringStream os;
tl::OutputStream stream (os);
db::TextWriter textwriter (stream);
textwriter.write (gg);
EXPECT_EQ (std::string (os.string ()), std::string (expected))
}
{
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter116c.gds"));
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions write_options;
write_options.set_format ("OASIS");
db::OASISWriterOptions oas_write_options;
oas_write_options.write_std_properties = 2;
write_options.set_options (oas_write_options);
db::Writer writer (write_options);
writer.write (g, out);
}
tl::InputStream in (tmp_file);
db::OASISReaderOptions oas_options;
oas_options.read_all_properties = true;
oas_options.expect_strict_mode = 0;
db::LoadLayoutOptions options;
options.set_options (oas_options);
db::Reader reader (in);
db::Layout gg;
reader.set_warnings_as_errors (true);
reader.read (gg, options);
const char *expected =
"set props {\n"
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
" {{S_TOP_CELL} {$2}}\n"
" {{S_TOP_CELL} {$1}}\n"
" {{S_BOUNDING_BOXES_AVAILABLE} {2}}\n"
" {17 {17value}}\n"
" {{name} {117}}\n"
"}\n"
"begin_libp $props 0.001\n"
"set props {\n"
" {{S_BOUNDING_BOX} {0,0,100,1000,1100}}\n"
" {42 {42}}\n"
"}\n"
"begin_cellp $props {$1}\n"
"path 1 0 0 0 0 {0 100} {1000 1200}\n"
"end_cell\n"
"set props {\n"
" {{S_BOUNDING_BOX} {2,0,0,0,0}}\n"
"}\n"
"begin_cellp $props {$2}\n"
"end_cell\n"
"end_lib\n"
;
tl::OutputStringStream os;
tl::OutputStream stream (os);
db::TextWriter textwriter (stream);
textwriter.write (gg);
EXPECT_EQ (std::string (os.string ()), std::string (expected))
}
{
std::string tmp_file = ut::TestBase::tmp_file ("tmp_dbOASISWriter116d.gds");
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions write_options;
write_options.set_format ("OASIS");
db::OASISWriterOptions oas_write_options;
oas_write_options.write_std_properties = 2;
oas_write_options.strict_mode = true;
write_options.set_options (oas_write_options);
db::Writer writer (write_options);
writer.write (g, out);
}
tl::InputStream in (tmp_file);
db::OASISReaderOptions oas_options;
oas_options.read_all_properties = true;
oas_options.expect_strict_mode = 1;
db::LoadLayoutOptions options;
options.set_options (oas_options);
db::Reader reader (in);
db::Layout gg;
reader.set_warnings_as_errors (true);
reader.read (gg, options);
const char *expected =
"set props {\n"
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
" {{S_TOP_CELL} {$2}}\n"
" {{S_TOP_CELL} {$1}}\n"
" {{S_BOUNDING_BOXES_AVAILABLE} {2}}\n"
" {{name} {117}}\n"
" {17 {17value}}\n"
"}\n"
"begin_libp $props 0.001\n"
"set props {\n"
" {42 {42}}\n"
" {{S_BOUNDING_BOX} {0,0,100,1000,1100}}\n"
" {{S_CELL_OFFSET} {231}}\n"
"}\n"
"begin_cellp $props {$1}\n"
"path 1 0 0 0 0 {0 100} {1000 1200}\n"
"end_cell\n"
"set props {\n"
" {{S_BOUNDING_BOX} {2,0,0,0,0}}\n"
" {{S_CELL_OFFSET} {229}}\n"
"}\n"
"begin_cellp $props {$2}\n"
"end_cell\n"
"end_lib\n"
;
tl::OutputStringStream os;
tl::OutputStream stream (os);
db::TextWriter textwriter (stream);
textwriter.write (gg);
EXPECT_EQ (std::string (os.string ()), std::string (expected))
}
c1.insert (db::CellInstArray (c2.cell_index (), db::Trans ()));
{
std::string tmp_file = ut::TestBase::tmp_file ("tmp_dbOASISWriter116e.gds");
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions write_options;
write_options.set_format ("OASIS");
db::Writer writer (write_options);
writer.write (g, out);
}
tl::InputStream in (tmp_file);
db::OASISReaderOptions oas_options;
oas_options.read_all_properties = true;
db::LoadLayoutOptions options;
options.set_options (oas_options);
db::Reader reader (in);
db::Layout gg;
reader.set_warnings_as_errors (true);
reader.read (gg, options);
const char *expected =
"set props {\n"
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
" {{S_TOP_CELL} {$1}}\n"
" {17 {17value}}\n"
" {{name} {117}}\n"
"}\n"
"begin_libp $props 0.001\n"
"begin_cell {$2}\n"
"end_cell\n"
"set props {\n"
" {42 {42}}\n"
"}\n"
"begin_cellp $props {$1}\n"
"sref {$2} 0 0 1 {0 0}\n"
"path 1 0 0 0 0 {0 100} {1000 1200}\n"
"end_cell\n"
"end_lib\n"
;
tl::OutputStringStream os;
tl::OutputStream stream (os);
db::TextWriter textwriter (stream);
textwriter.write (gg);
EXPECT_EQ (std::string (os.string ()), std::string (expected))
}
{
std::string tmp_file = ut::TestBase::tmp_file ("tmp_dbOASISWriter116f.gds");
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions write_options;
write_options.select_cell (c2.cell_index ());
write_options.set_format ("OASIS");
db::Writer writer (write_options);
writer.write (g, out);
}
tl::InputStream in (tmp_file);
db::OASISReaderOptions oas_options;
oas_options.read_all_properties = true;
db::LoadLayoutOptions options;
options.set_options (oas_options);
db::Reader reader (in);
db::Layout gg;
reader.set_warnings_as_errors (true);
reader.read (gg, options);
const char *expected =
"set props {\n"
" {{S_MAX_SIGNED_INTEGER_WIDTH} {4}}\n"
" {{S_MAX_UNSIGNED_INTEGER_WIDTH} {4}}\n"
" {{S_TOP_CELL} {$2}}\n"
" {17 {17value}}\n"
" {{name} {117}}\n"
"}\n"
"begin_libp $props 0.001\n"
"begin_cell {$2}\n"
"end_cell\n"
"end_lib\n"
;
tl::OutputStringStream os;
tl::OutputStream stream (os);
db::TextWriter textwriter (stream);
textwriter.write (gg);
EXPECT_EQ (std::string (os.string ()), std::string (expected))
}
}
TEST(117)
{
// polygons and boxes without area
db::Manager m;
db::Layout g (&m);
db::LayerProperties lp1;
lp1.layer = 1;
lp1.datatype = 0;
g.insert_layer (0, lp1);
db::Cell &c1 (g.cell (g.add_cell ()));
c1.shapes (0).insert (db::Box (100, 0, 100, 200));
c1.shapes (0).insert (db::Box (100, -20, 100, -20));
db::Point pts[] = {
db::Point (100, 15),
db::Point (150, 15),
db::Point (120, 15)
};
db::Polygon p;
p.assign_hull (&pts[0], &pts[sizeof (pts) / sizeof(pts[0])], false);
c1.shapes (0).insert (p);
db::SimplePolygon ps;
ps.assign_hull (&pts[0], &pts[sizeof (pts) / sizeof(pts[0])], false);
ps.transform (db::FTrans (db::FTrans::r90), false);
c1.shapes (0).insert (ps);
std::string tmp_file = ut::TestBase::tmp_file (tl::sprintf ("tmp_dbOASISWriter117.gds"));
{
tl::OutputStream out (tmp_file);
db::SaveLayoutOptions options;
options.set_format ("OASIS");
db::Writer writer (options);
writer.write (g, out);
}
tl::InputStream in (tmp_file);
db::Reader reader (in);
db::Layout gg;
reader.set_warnings_as_errors (true);
reader.read (gg);
const char *expected =
"begin_lib 0.001\n"
"begin_cell {$1}\n"
"boundary 1 0 {-15 100} {-15 120} {-15 150} {-15 100}\n"
"boundary 1 0 {100 15} {150 15} {120 15} {100 15}\n"
"box 1 0 {100 -20} {100 -20}\n"
"box 1 0 {100 0} {100 200}\n"
"end_cell\n"
"end_lib\n"
;
tl::OutputStringStream os;
tl::OutputStream stream (os);
db::TextWriter textwriter (stream);
textwriter.write (gg);
EXPECT_EQ (std::string (os.string ()), std::string (expected))
}