OpenRAM/compiler/gdsMill/gdsMill/pdfLayout.py

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)