blob: ef7909bc5fd827a8a6ada81b944f62b315d7e95a [file] [log] [blame]
// *****************************************************************************
// *****************************************************************************
// Copyright 2013 - 2015, Cadence Design Systems
//
// This file is part of the Cadence LEF/DEF Open Source
// Distribution, Product Version 5.8.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License.
//
// For updates, support, or to become part of the LEF/DEF Community,
// check www.openeda.org for details.
//
// $Author: dell $
// $Revision: #1 $
// $Date: 2017/06/06 $
// $State: $
// *****************************************************************************
// *****************************************************************************
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "lex.h"
#include "defiFill.hpp"
#include "defiDebug.hpp"
BEGIN_LEFDEF_PARSER_NAMESPACE
////////////////////////////////////////////////////
////////////////////////////////////////////////////
//
// defiFill
//
////////////////////////////////////////////////////
////////////////////////////////////////////////////
defiFill::defiFill(defrData *data)
: defData(data)
{
Init();
}
void defiFill::Init() {
numPolys_ = 0;
numPts_ = 0;
clear();
layerNameLength_ = 0;
xl_ = (int*)malloc(sizeof(int)*1);
yl_ = (int*)malloc(sizeof(int)*1);
xh_ = (int*)malloc(sizeof(int)*1);
yh_ = (int*)malloc(sizeof(int)*1);
rectsAllocated_ = 1; // At least 1 rectangle will define
polysAllocated_ = 0;
polygons_ = 0;
layerName_ = 0;
viaName_ = 0;
viaNameLength_ = 0;
viaPts_ = 0;
ptsAllocated_ = 0;
viaPts_ = 0;
}
defiFill::~defiFill() {
Destroy();
}
void defiFill::clear() {
hasLayer_ = 0;
layerOpc_ = 0;
numRectangles_ = 0;
hasVia_ = 0;
viaOpc_ = 0;
mask_ = 0;
}
void defiFill::clearPoly() {
struct defiPoints* p;
int i;
for (i = 0; i < numPolys_; i++) {
p = polygons_[i];
free((char*)(p->x));
free((char*)(p->y));
free((char*)(polygons_[i]));
}
numPolys_ = 0;
}
void defiFill::clearPts() {
struct defiPoints* p;
int i;
for (i = 0; i < numPts_; i++) {
p = viaPts_[i];
free((char*)(p->x));
free((char*)(p->y));
free((char*)(viaPts_[i]));
}
numPts_ = 0;
}
void defiFill::Destroy() {
if (layerName_) free(layerName_);
if (viaName_) free(viaName_);
free((char*)(xl_));
free((char*)(yl_));
free((char*)(xh_));
free((char*)(yh_));
rectsAllocated_ = 0;
xl_ = 0;
yl_ = 0;
xh_ = 0;
yh_ = 0;
clearPoly();
if (polygons_) free((char*)(polygons_));
polygons_ = 0;
clearPts();
if (viaPts_) free((char*)(viaPts_));
viaPts_ = 0;
clear();
}
void defiFill::setLayer(const char* name) {
int len = strlen(name) + 1;
if (layerNameLength_ < len) {
if (layerName_) free(layerName_);
layerName_ = (char*)malloc(len);
layerNameLength_ = len;
}
strcpy(layerName_, defData->DEFCASE(name));
hasLayer_ = 1;
}
// 5.7
void defiFill::setLayerOpc() {
layerOpc_ = 1;
}
void defiFill::addRect(int xl, int yl, int xh, int yh) {
if (numRectangles_ == rectsAllocated_) {
int i;
int max = rectsAllocated_ = rectsAllocated_ * 2;
int* newxl = (int*)malloc(sizeof(int)*max);
int* newyl = (int*)malloc(sizeof(int)*max);
int* newxh = (int*)malloc(sizeof(int)*max);
int* newyh = (int*)malloc(sizeof(int)*max);
for (i = 0; i < numRectangles_; i++) {
newxl[i] = xl_[i];
newyl[i] = yl_[i];
newxh[i] = xh_[i];
newyh[i] = yh_[i];
}
free((char*)(xl_));
free((char*)(yl_));
free((char*)(xh_));
free((char*)(yh_));
xl_ = newxl;
yl_ = newyl;
xh_ = newxh;
yh_ = newyh;
}
xl_[numRectangles_] = xl;
yl_[numRectangles_] = yl;
xh_[numRectangles_] = xh;
yh_[numRectangles_] = yh;
numRectangles_ += 1;
}
// 5.6
void defiFill::addPolygon(defiGeometries* geom) {
struct defiPoints* p;
int x, y;
int i;
if (numPolys_ == polysAllocated_) {
struct defiPoints** poly;
polysAllocated_ = (polysAllocated_ == 0) ?
2 : polysAllocated_ * 2;
poly = (struct defiPoints**)malloc(sizeof(struct defiPoints*) *
polysAllocated_);
for (i = 0; i < numPolys_; i++)
poly[i] = polygons_[i];
if (polygons_)
free((char*)(polygons_));
polygons_ = poly;
}
p = (struct defiPoints*)malloc(sizeof(struct defiPoints));
p->numPoints = geom->numPoints();
p->x = (int*)malloc(sizeof(int)*p->numPoints);
p->y = (int*)malloc(sizeof(int)*p->numPoints);
for (i = 0; i < p->numPoints; i++) {
geom->points(i, &x, &y);
p->x[i] = x;
p->y[i] = y;
}
polygons_[numPolys_] = p;
numPolys_ += 1;
}
int defiFill::hasLayer() const {
return hasLayer_;
}
const char* defiFill::layerName() const {
return layerName_;
}
// 5.7
int defiFill::hasLayerOpc() const {
return layerOpc_;
}
int defiFill::numRectangles() const {
return numRectangles_;
}
int defiFill::xl(int index) const {
if (index < 0 || index >= numRectangles_) {
defiError(1, 0, "bad index for Fill xl", defData);
return 0;
}
return xl_[index];
}
int defiFill::yl(int index) const {
if (index < 0 || index >= numRectangles_) {
defiError(1, 0, "bad index for Fill yl", defData);
return 0;
}
return yl_[index];
}
int defiFill::xh(int index) const {
if (index < 0 || index >= numRectangles_) {
defiError(1, 0, "bad index for Fill xh", defData);
return 0;
}
return xh_[index];
}
int defiFill::yh(int index) const {
if (index < 0 || index >= numRectangles_) {
defiError(1, 0, "bad index for Fill yh", defData);
return 0;
}
return yh_[index];
}
// 5.6
int defiFill::numPolygons() const {
return numPolys_;
}
// 5.6
struct defiPoints defiFill::getPolygon(int index) const {
return *(polygons_[index]);
}
// 5.7
void defiFill::setVia(const char* name) {
int len = strlen(name) + 1;
if (viaNameLength_ < len) {
if (viaName_) free(viaName_);
viaName_ = (char*)malloc(len);
viaNameLength_ = len;
}
strcpy(viaName_, defData->DEFCASE(name));
hasVia_ = 1;
}
// 5.7
void defiFill::setViaOpc() {
viaOpc_ = 1;
}
// 5.8
void defiFill::setMask(int colorMask) {
mask_ = colorMask;
}
// 5.7
void defiFill::addPts(defiGeometries* geom) {
struct defiPoints* p;
int x, y;
int i;
if (numPts_ == ptsAllocated_) {
struct defiPoints** pts;
ptsAllocated_ = (ptsAllocated_ == 0) ?
2 : ptsAllocated_ * 2;
pts= (struct defiPoints**)malloc(sizeof(struct defiPoints*) *
ptsAllocated_);
for (i = 0; i < numPts_; i++)
pts[i] = viaPts_[i];
if (viaPts_)
free((char*)(viaPts_));
viaPts_ = pts;
}
p = (struct defiPoints*)malloc(sizeof(struct defiPoints));
p->numPoints = geom->numPoints();
p->x = (int*)malloc(sizeof(int)*p->numPoints);
p->y = (int*)malloc(sizeof(int)*p->numPoints);
for (i = 0; i < p->numPoints; i++) {
geom->points(i, &x, &y);
p->x[i] = x;
p->y[i] = y;
}
viaPts_[numPts_] = p;
numPts_ += 1;
}
// 5.7
int defiFill::hasVia() const {
return hasVia_;
}
// 5.7
const char* defiFill::viaName() const {
return viaName_;
}
// 5.7
int defiFill::hasViaOpc() const {
return viaOpc_;
}
// 5.7
int defiFill::numViaPts() const {
return numPts_;
}
// 5.8
int defiFill::layerMask() const {
return mask_;
}
// 5.8
int defiFill::viaTopMask() const {
return mask_ / 100;
}
// 5.8
int defiFill::viaCutMask() const {
return mask_ / 10 % 10;
}
// 5.8
int defiFill::viaBottomMask() const {
return mask_ % 10;
}
// 5.7
struct defiPoints defiFill::getViaPts(int index) const {
return *(viaPts_[index]);
}
void defiFill::print(FILE* f) const {
int i, j;
struct defiPoints points;
if (hasLayer())
fprintf(f, "- LAYER %s", layerName());
if (layerMask())
fprintf(f, " + Mask %d", layerMask());
if (hasLayerOpc())
fprintf(f, " + OPC");
fprintf(f, "\n");
for (i = 0; i < numRectangles(); i++) {
fprintf(f, " RECT %d %d %d %d\n", xl(i),
yl(i), xh(i),
yh(i));
}
for (i = 0; i < numPolygons(); i++) {
fprintf(f, " POLYGON ");
points = getPolygon(i);
for (j = 0; j < points.numPoints; j++)
fprintf(f, "%d %d ", points.x[j], points.y[j]);
fprintf(f, "\n");
}
fprintf(f,"\n");
if (hasVia())
fprintf(f, "- VIA %s", viaName());
if (mask_) {
fprintf(f, " + MASK %d%d%d", viaTopMask(),
viaCutMask(),
viaBottomMask());
}
if (hasViaOpc())
fprintf(f, " + OPC");
fprintf(f, "\n");
for (i = 0; i < numViaPts(); i++) {
fprintf(f, " ");
points = getViaPts(i);
for (j = 0; j < points.numPoints; j++)
fprintf(f, "%d %d ", points.x[j], points.y[j]);
fprintf(f, "\n");
}
fprintf(f,"\n");
}
END_LEFDEF_PARSER_NAMESPACE