mirror of https://github.com/VLSIDA/OpenRAM.git
95 lines
4.3 KiB
Python
95 lines
4.3 KiB
Python
import pyx
|
|
import math
|
|
from numpy import matrix
|
|
from gdsPrimitives import *
|
|
import random
|
|
|
|
class pdfLayout:
|
|
"""Class representing a view for a layout as a PDF"""
|
|
def __init__(self,theLayout):
|
|
self.canvas = pyx.canvas.canvas()
|
|
self.layout = theLayout
|
|
self.layerColors=dict()
|
|
self.scale = 1.0
|
|
|
|
def setScale(self,newScale):
|
|
self.scale = float(newScale)
|
|
|
|
def hexToRgb(self,hexColor):
|
|
"""
|
|
Takes a hexadecimal color string i.e. "#219E1C" and converts it to an rgb float triplet ranging 0->1
|
|
"""
|
|
red = int(hexColor[1:3],16)
|
|
green = int(hexColor[3:5],16)
|
|
blue = int(hexColor[5:7],16)
|
|
return (float(red)/255,float(green)/255,float(blue)/255)
|
|
|
|
def randomHexColor(self):
|
|
"""
|
|
Generates a random color in hex using the format #ABC123
|
|
"""
|
|
red = hex(random.randint(0,255)).lstrip("0x")
|
|
green = hex(random.randint(0,255)).lstrip("0x")
|
|
blue = hex(random.randint(0,255)).lstrip("0x")
|
|
return "#"+red+green+blue
|
|
|
|
def transformCoordinates(self,uvCoordinates,origin,uVector,vVector):
|
|
"""
|
|
This helper method will convert coordinates from a UV space to the cartesian XY space
|
|
"""
|
|
xyCoordinates = []
|
|
#setup a translation matrix
|
|
tMatrix = matrix([[1.0,0.0,origin[0]],[0.0,1.0,origin[1]],[0.0,0.0,1.0]])
|
|
#and a rotation matrix
|
|
rMatrix = matrix([[uVector[0],vVector[0],0.0],[uVector[1],vVector[1],0.0],[0.0,0.0,1.0]])
|
|
for coordinate in uvCoordinates:
|
|
#grab the point in UV space
|
|
uvPoint = matrix([coordinate[0],coordinate[1],1.0])
|
|
#now rotate and translate it back to XY space
|
|
xyPoint = rMatrix * uvPoint
|
|
xyPoint = tMatrix * xyPoint
|
|
xyCoordinates += [(xyPoint[0],xyPoint[1])]
|
|
return xyCoordinates
|
|
|
|
def drawBoundary(self,boundary,origin,uVector,vVector):
|
|
#get the coordinates in the correct coordinate space
|
|
coordinates = self.transformCoordinates(boundary.coordinates,origin,uVector,vVector)
|
|
#method to draw a boundary with an XY offset
|
|
x=(coordinates[0][0])/self.scale
|
|
y=(coordinates[0][1])/self.scale
|
|
shape = pyx.path.path(pyx.path.moveto(x, y))
|
|
for index in range(1,len(coordinates)):
|
|
x=(coordinates[index][0])/self.scale
|
|
y=(coordinates[index][1])/self.scale
|
|
shape.append(pyx.path.lineto(x,y))
|
|
self.canvas.stroke(shape, [pyx.style.linewidth.thick])
|
|
if(boundary.drawingLayer in self.layerColors):
|
|
layerColor = self.hexToRgb(self.layerColors[boundary.drawingLayer])
|
|
self.canvas.fill(shape, [pyx.color.rgb(layerColor[0],layerColor[1],layerColor[2]), pyx.color.transparency(0.5)])
|
|
|
|
def drawPath(self,path,origin,uVector,vVector):
|
|
#method to draw a path with an XY offset
|
|
boundaryCoordinates = self.transformCoordinates(path.equivalentBoundaryCoordinates(),origin,uVector,vVector)
|
|
shape = pyx.path.path(pyx.path.moveto((boundaryCoordinates[0][0])/self.scale,(boundaryCoordinates[0][1])/self.scale))
|
|
for coordinate in boundaryCoordinates[1::]:
|
|
shape.append(pyx.path.lineto((coordinate[0])/self.scale,(coordinate[1])/self.scale))
|
|
self.canvas.stroke(shape, [pyx.style.linewidth.thick])
|
|
if(path.drawingLayer in self.layerColors):
|
|
layerColor = self.hexToRgb(self.layerColors[path.drawingLayer])
|
|
self.canvas.fill(shape, [pyx.color.rgb(layerColor[0],layerColor[1],layerColor[2]), pyx.color.transparency(0.5)])
|
|
|
|
def drawLayout(self):
|
|
#use the layout xyTree and structureList
|
|
#to draw ONLY the geometry in each structure
|
|
#SREFS and AREFS are handled in the tree
|
|
for element in self.layout.xyTree:
|
|
#each element is (name,offsetTuple,rotate)
|
|
structureToDraw = self.layout.structures[element[0]]
|
|
for boundary in structureToDraw.boundaries:
|
|
self.drawBoundary(boundary,element[1],element[2], element[3])
|
|
for path in structureToDraw.paths:
|
|
self.drawPath(path,element[1],element[2], element[3])
|
|
|
|
def writeToFile(self,filename):
|
|
self.canvas.writePDFfile(filename)
|