#!/usr/bin/awk -f # Conversion script from LayoutEditor's svg to ps by Petr Mikulik # It can be used for conversion of GDS files to postscript or EPS. # # Author: Petr Mikulik # Date: 22.5.2009 # License: GNU GPL # # Usage: # 1. You have a GDS or similar file. # 2. Load it into LayoutEditor. # 3. "Save as" SVG file, e.g. circuit.svg. # 4. Run # dos2unix circuit.svg # (wrong output from LayoutEditor on Linux) # awk -f LESVG2ps.awk circuit.svg >circuit.ps # (conversion SVG -> EPS) # # Notes: # - Position of the SVG drawing is moved to center of A4 paper. # - Bounding box is not computed ... you have to use fixbb script or # ps2eps or something similar to get precise bounding box. # - User can change manually the following properties in the header of # the output postscript file: # BLACK: false|true # WHITE: false|true # FONT_SCALE: font scaling # SCALE: drawing scale # POSITION: relative position of the drawing on the paper # # Imperfections of LayoutEditor's SVG output: # - Bug: It outputs CRLF instead of LF on Linux. # - Polygons: it is not written whether they are line bordered or filled. # This script thus fills all of them. # - Text: scaling is fixed because LayoutEditor doesn't write it to SVG file. BEGIN { print "%!PS-Adobe-2.0\n\ %%Title: gds to svg to ps\n\ %%Creator: Conversion script from LayoutEditor's svg to ps by Petr Mikulik\n\ %%CreationDate: today\n\ %%BoundingBox: 50 50 554 770\n\ %%Orientation: Portrait\n\ %%DocumentFonts: Helvetica\n\ %%Pages: 1\n\ %%EndComments\n\ %%BeginProlog\n\ /gds2svg2ps_dict 2048 dict def\n\ gds2svg2ps_dict begin\n\ \n\ % Optional user setup:\n\ /BLACK false def % no colors, black on white\n\ /WHITE false def % no colours, white on black\n\ /FONT_SCALE { 10.0 } def % relative scale for fonts\n\ /SCALE { 1.0 1.0 } def % change your scale here\n\ /POSITION { 0 0 } def % change position of the center (mm)\n\ % End of optional user setup.\n\ \n\ /M {moveto} bind def\n\ /L {lineto} bind def\n\ /R {rmoveto} bind def\n\ /V {rlineto} bind def\n\ /N {newpath moveto} bind def\n\ /Z {closepath} bind def\n\ /C {setrgbcolor} bind def\n\ BLACK {/C {pop pop pop 0 setgray} bind def } if\n\ WHITE {/C {pop pop pop 1 setgray} bind def } if\n\ /D {def} def\n\ /G {setgray} bind def\n\ /W {setlinewidth} bind def\n\ /S {stroke} bind def\n\ /T {translate} bind def\n\ /F {fill} bind def\n\ /A {gsave} bind def\n\ /B {grestore} bind def\n\ /rf {rlineto fill} bind def\n\ /f {lineto fill} bind def\n\ /s1 {moveto (Helvetica) findfont} def\n\ /s2 {FONT_SCALE mul scalefont setfont gsave 1 -1 scale} def\n\ /s3 {show grestore} def\n\ end\n\ %%EndProlog\n\ %%Page: 1 1\n\ gds2svg2ps_dict begin\n\ gsave\n\ 0 setlinejoin 2 setlinecap\n\ WHITE {A /x1{50}D /y1{50}D /x2{554}D /y2{770}D\n\ 0 G x1 y1 N x1 y2 L x2 y2 L x2 y1 L F S B} if\n\ 2.83464566929134 -2.83464566929134 scale % units are mm\n\ 93 -117 translate % middle of A4\n\ POSITION translate\n\ SCALE scale\n\ " MAX_SUBCELL_SIZE=128000 # gs cannot deal with larger chunk of elements (in bytes) } ### NEW CELL ### $1 == "" { # don't use == because it fails if CRLF instead of LF gsub(" 0[.]", " .", cell) # save bytes: remove leading 0, e.g. 0.124 gsub(" -0[.]", " -.", cell) # save bytes: remove leading 0, e.g. -0.124 gsub("\n0[.]", "\n.", cell) # save bytes: remove leading 0, e.g. 0.124 gsub("\n-0[.]", "\n-.", cell) # save bytes: remove leading 0, e.g. -0.124 if (length(cell) < MAX_SUBCELL_SIZE) { print "/" id " {" print cell "}D" next } npart=0 small="" while (1) { i=index(cell, "\n") if (i==0 || length(small)+i >= MAX_SUBCELL_SIZE) { npart++ print "/" id "$$PART$$" npart " {\n" small "}D" small="" if (i==0) break; } small=small substr(cell,1,i); cell=substr(cell,i+1); } printf "/" id " {\n " for (i=1; i<=npart; i++) printf " " id "$$PART$$" i print "\n}D" next } ### CELL ELEMENTS ### $1 == "") text=substr($0, i+1) i=index(text, "<") text=substr(text, 1, i-1) color=parse_value("fill") r_g_b=hexcolor2r_g_b(color) this_cell=new_this_cell(r_g_b) this_cell=this_cell x " " y " s1 " 1 " s2 (" text ") s3\n" cell=cell this_cell next } ### DRAW CELL(S) ### $1 == "/ { next } # Switch on writing of unknown lines: $0 ~ /title/ { print_ignoring = 1 next } print_ignoring { print NR ": ignoring " $0 >"/dev/stderr" } END { print "grestore\n\ end\n\ showpage\n\ %%Trailer" } function parse_value ( key ) { key = " " key "=\"" i = index($0, key) if (i <= 0) return "" value = substr($0, i+length(key)) i = index(value, "\"") if (i <= 0) return value value = substr(value, 1, i-1) return value } # "#FF000A" => "1 0 0.123" function hexcolor2r_g_b ( color ) { if (substr(color,1,1)=="#") { color="0x" substr(color,2) } color=strtonum(color) b=int(color % 256)/255 color=color / 256 g=int(color % 256)/255 r=int(color / 256)/255 # round them and save bytes (3 decimal places, no leading 0) r=0.001*int(r*1000); g=0.001*int(g*1000); b=0.001*int(b*1000) r_g_b=sprintf("%g %g %g", r, g, b) gsub("0[.]", ".", r_g_b) return r_g_b } function new_this_cell ( r_g_b ) { if (r_g_b == r_g_b_last) return "" r_g_b_last=r_g_b return r_g_b " C " } # eof