/* KLayout Layout Viewer Copyright (C) 2006-2017 Matthias Koefferlein This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef HDR_dbBoxConvert #define HDR_dbBoxConvert #include "dbText.h" #include "dbPolygon.h" #include "dbEdge.h" #include "dbEdgePair.h" #include "dbUserObject.h" #include "dbBox.h" #include "dbPath.h" #include "dbArray.h" #include "dbObjectWithProperties.h" namespace db { class Cell; class CellInst; class Layout; /** * @brief A tag class to indicate "simple" box computation * * Using this tag as a typedef for box_convert::complexity * enables algorithms to simply use the box without caching it. */ struct DB_PUBLIC simple_bbox_tag { }; /** * @brief A tag class to indicate "complex" box computation * * Using this tag as a typedef for box_convert::complexity * enables algorithms to use cached bboxes, i.e. for the dbBoxTree. */ struct DB_PUBLIC complex_bbox_tag { }; /** * @brief The generic box converter for the shapes * * The box converter is supposed to convert a given * shape (i.e. edge, polygon etc) into a box covering * the shape as close as possible). * This is just the template declaration. The specializations * provide the correct implementation. * * The AllowEmpty flag is ignored currently. */ template struct box_convert { }; /** * @brief The shape-with-properties box converter * * The AllowEmpty flag is ignored currently. */ template struct box_convert< db::object_with_properties, AllowEmpty > { typedef db::box_convert base_convert; typedef typename base_convert::complexity complexity; typedef typename base_convert::box_type box_type; box_type operator() (const db::object_with_properties &s) const { return bconvert (s); } base_convert bconvert; }; /** * @brief The text box converter * * The text is just a point, so the box returned is * degenerated, but usable. * * The AllowEmpty flag is ignored currently. */ template struct box_convert< db::text, AllowEmpty > { typedef db::text text_type; typedef db::box box_type; typedef simple_bbox_tag complexity; box_type operator() (const text_type &t) const { return t.box (); } }; /** * @brief The text reference box converter * * The text is just a point, so the box returned is * degenerated, but usable. * * The AllowEmpty flag is ignored currently. */ template struct box_convert< db::text_ref, AllowEmpty > { typedef db::text_ref text_ref_type; typedef typename Text::coord_type coord_type; typedef db::box box_type; typedef simple_bbox_tag complexity; box_type operator() (const text_ref_type &t) const { return t.box (); } }; /** * @brief The text reference array box converter * * The text is just a point, so the box returned is * degenerated, but usable. * * The AllowEmpty flag is ignored currently. */ template struct box_convert< db::array< db::text_ref, ArrayTrans>, AllowEmpty > { typedef db::text_ref text_ref_type; typedef db::array text_ref_array_type; typedef typename Text::coord_type coord_type; typedef db::box box_type; typedef simple_bbox_tag complexity; box_type operator() (const text_ref_array_type &t) const { box_convert< db::text_ref > bc; return t.bbox (bc); } }; /** * @brief The path box converter * * This maps the box to the bounding box of the polygon. * * The AllowEmpty flag is ignored currently. */ template struct box_convert < db::path, AllowEmpty > { typedef db::path path_type; typedef db::box box_type; typedef complex_bbox_tag complexity; box_type operator() (const path_type &p) const { return p.box (); } }; /** * @brief The path reference box converter * * This maps the box to the bounding box of the polygon. * * The AllowEmpty flag is ignored currently. */ template struct box_convert < db::path_ref, AllowEmpty > { typedef db::path_ref path_ref_type; typedef typename Path::coord_type coord_type; typedef db::box box_type; typedef complex_bbox_tag complexity; box_type operator() (const path_ref_type &p) const { return p.box (); } }; /** * @brief The path reference array box converter * * This maps the box to the bounding box of the polygon. * * The AllowEmpty flag is ignored currently. */ template struct box_convert < db::array< db::path_ref, ArrayTrans >, AllowEmpty > { typedef db::path_ref path_ref_type; typedef db::array path_ref_array_type; typedef typename Path::coord_type coord_type; typedef db::box box_type; typedef complex_bbox_tag complexity; box_type operator() (const path_ref_array_type &p) const { box_convert< db::path_ref > bc; return p.bbox (bc); } }; /** * @brief The polygon box converter * * This maps the box to the bounding box of the polygon. * * The AllowEmpty flag is ignored currently. */ template struct box_convert< db::polygon, AllowEmpty > { typedef db::polygon polygon_type; typedef db::box box_type; typedef simple_bbox_tag complexity; const box_type &operator() (const polygon_type &p) const { return p.box (); } }; /** * @brief The simple polygon box converter * * This maps the box to the bounding box of the polygon. * * The AllowEmpty flag is ignored currently. */ template struct box_convert< db::simple_polygon, AllowEmpty > { typedef db::simple_polygon simple_polygon_type; typedef db::box box_type; typedef simple_bbox_tag complexity; const box_type &operator() (const simple_polygon_type &p) const { return p.box (); } }; /** * @brief The polygon reference box converter * * This maps the box to the bounding box of the polygon. * * The AllowEmpty flag is ignored currently. */ template struct box_convert< db::polygon_ref, AllowEmpty > { typedef db::polygon_ref polygon_ref_type; typedef typename Poly::coord_type coord_type; typedef db::box box_type; typedef simple_bbox_tag complexity; box_type operator() (const polygon_ref_type &p) const { return p.box (); } }; /** * @brief The polygon reference box converter * * This maps the box to the bounding box of the polygon. * * The AllowEmpty flag is ignored currently. */ template struct box_convert< db::array< db::polygon_ref, ArrayTrans >, AllowEmpty > { typedef db::polygon_ref polygon_ref_type; typedef db::array polygon_ref_array_type; typedef typename Poly::coord_type coord_type; typedef db::box box_type; typedef simple_bbox_tag complexity; box_type operator() (const polygon_ref_array_type &p) const { box_convert< db::polygon_ref > bc; return p.bbox (bc); } }; /** * @brief The point box converter * * This maps the box to a degenerated box with just one point. * * The AllowEmpty flag is ignored currently. */ template struct box_convert< db::point, AllowEmpty > { typedef db::point point_type; typedef db::box box_type; typedef simple_bbox_tag complexity; box_type operator() (const point_type &p) const { return box_type (p, p); } }; /** * @brief The vector box converter * * This maps the box to a degenerated box with just one point. * * The AllowEmpty flag is ignored currently. */ template struct box_convert< db::vector, AllowEmpty > { typedef db::vector vector_type; typedef db::point point_type; typedef db::box box_type; typedef simple_bbox_tag complexity; box_type operator() (const vector_type &p) const { return box_type (point_type () + p, point_type () + p); } }; /** * @brief The edge pair box converter * * This maps the box to the bounding box of the edge pair, which may * be degenerate, i.e. for horizontal edges. * * The AllowEmpty flag is ignored currently. */ template struct box_convert< db::edge_pair, AllowEmpty > { typedef db::edge_pair edge_pair_type; typedef db::box box_type; typedef simple_bbox_tag complexity; box_type operator() (const edge_pair_type &e) const { return e.bbox (); } }; /** * @brief The edge box converter * * This maps the box to the bounding box of the edge, which may * be degenerate, i.e. for horizontal edges. * * The AllowEmpty flag is ignored currently. */ template struct box_convert< db::edge, AllowEmpty > { typedef db::edge edge_type; typedef db::box box_type; typedef simple_bbox_tag complexity; box_type operator() (const edge_type &e) const { return box_type (e.p1 (), e.p2 ()); } }; /** * @brief The user object box converter * * The AllowEmpty flag is ignored currently. */ template struct box_convert< db::user_object, AllowEmpty > { typedef db::user_object user_object_type; typedef db::box box_type; typedef complex_bbox_tag complexity; box_type operator() (const user_object_type &r) const { return r.box (); } }; /** * @brief The box-to-box converter * * This is the trivial case where a box becomes a box. * * The AllowEmpty flag is ignored currently. */ template struct box_convert , AllowEmpty > { typedef db::box box_type; typedef simple_bbox_tag complexity; const box_type &operator() (const box_type &b) const { return b; } }; /** * @brief The box array box converter * * The AllowEmpty flag is ignored currently. */ template struct box_convert< db::array< db::box, ArrayTrans >, AllowEmpty > { typedef C coord_type; typedef db::box box_type; typedef db::array box_array_type; typedef simple_bbox_tag complexity; box_type operator() (const box_array_type &a) const { box_convert bc; return a.bbox (bc); } }; /** * @brief The box-to-box converter for the case of boxes with special internal representation * * This is the trivial case where a box becomes a box. * * The AllowEmpty flag is ignored currently. */ template struct box_convert , AllowEmpty > { typedef db::box box_type; typedef simple_bbox_tag complexity; box_type operator() (const db::box &b) const { return box_type (b); } }; /** * @brief The box array box converter for boxes with special internal representation * * The AllowEmpty flag is ignored currently. */ template struct box_convert< db::array< db::box, ArrayTrans >, AllowEmpty > { typedef db::box box_type; typedef db::array< db::box, ArrayTrans> box_array_type; typedef simple_bbox_tag complexity; box_type operator() (const box_array_type &a) const { box_convert< box > bc; return a.bbox (bc); } }; // Note: the implementation is delegated, so we don't need to make box_convert dllexport. DB_PUBLIC db::Box cell_box_convert_impl (const db::Cell &c, int layer, bool allow_empty); /** * @brief The cell box converter * * This class is used as a function to obtain the bounding box of * a cell, whether layer-wise or global. * * If AllowEmpty is false, the box converter treats empty cells as single points at 0, 0. */ template struct DB_PUBLIC box_convert { typedef db::Cell cell_type; typedef db::Box box_type; typedef complex_bbox_tag complexity; box_convert () : m_layer (-1) { } box_convert (unsigned int l) : m_layer (l) { } box_type operator() (const cell_type &c) const { return cell_box_convert_impl (c, m_layer, AllowEmpty); } private: int m_layer; }; // Note: the implementation is delegated, so we don't need to make box_convert dllexport. DB_PUBLIC db::Box cellinst_box_convert_impl (const db::CellInst &inst, const db::Layout *layout, int layer, bool allow_empty); /** * @brief The cell inst box converter * * This class is used as a function to convert a cell instance * to a box for a given layer. This requires that the per-layer * bounding boxes of the cell have been computed already. * * If AllowEmpty is false, the box converter treats empty cells as single points at 0, 0. */ template struct box_convert { typedef db::CellInst cell_inst_type; typedef db::Layout layout_type; typedef db::Box box_type; typedef complex_bbox_tag complexity; box_convert () : mp_layout (0), m_layer (-1) { } box_convert (const layout_type &ly, unsigned int l) : mp_layout (&ly), m_layer (l) { } box_convert (const layout_type &ly) : mp_layout (&ly), m_layer (-1) { } box_type operator() (const cell_inst_type &t) const { return cellinst_box_convert_impl (t, mp_layout, m_layer, AllowEmpty); } private: const layout_type *mp_layout; int m_layer; }; /** * @brief The cell inst array box converter * * This class is used as a function to convert a cell instance array * to a box for a given layer or for all layers. This requires that * the per-layer or overall bounding boxes of the cell have been * computed already. * * If AllowEmpty is false, the box converter treats empty cells as single points at 0, 0. */ template struct box_convert , AllowEmpty> { typedef db::CellInst cell_inst_type; typedef db::Layout layout_type; typedef db::Box box_type; typedef complex_bbox_tag complexity; box_convert () : m_bc () { } box_convert (const layout_type &g, unsigned int l) : m_bc (g, l) { } box_convert (const layout_type &g) : m_bc (g) { } box_type operator() (const db::array &t) const { return t.bbox (m_bc); } private: box_convert m_bc; }; /** * @brief The cell-inst-array-with-properties box converter * * If AllowEmpty is false, the box converter treats empty cells as single points at 0, 0. */ template struct box_convert< db::object_with_properties< db::array >, AllowEmpty> { typedef db::array cell_inst_array; typedef db::box_convert base_convert; typedef db::Layout layout_type; typedef typename base_convert::complexity complexity; typedef typename base_convert::box_type box_type; box_convert () : bconvert () { } box_convert (const layout_type &g, unsigned int l) : bconvert (g, l) { } box_convert (const layout_type &g) : bconvert (g) { } box_type operator() (const db::object_with_properties &s) const { return bconvert (s); } base_convert bconvert; }; } #endif