bem_gpge.itcl 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. # --------------------------------------------------------------------
  2. #
  3. # gpge.itcl
  4. #
  5. # The classes in this file can generate a GPGE graphic file
  6. # from the CSDL description, which can in turn be used
  7. # in MMTL simulators.
  8. #
  9. # Bob Techentin
  10. # February 2, 2001
  11. #
  12. # Copyright 2001-2004 Mayo Foundation. All Rights Reserved.
  13. # $Id: bem_gpge.itcl,v 1.4 2004/02/12 22:28:27 techenti Exp $
  14. #
  15. # --------------------------------------------------------------------
  16. # --------------------------------------------------------------------
  17. #
  18. # Rules for making a GPGE graphic cross section
  19. #
  20. # 0. Object section starts with $OBJECT, $PAGE, $PAGESIZE, $DESIGN
  21. # $ORIGIN, and $PINGRID records, followed by ICON section attributes
  22. # "COUPLING_LENGTH", "RISETIME", "FREQUENCY" (if != 0),
  23. # "CONDUCTIVITY" (if != 0), "CONTOUR_SEGMENTS" and "PLANE_SEGMENTS".
  24. #
  25. # 1. Pins and pin attributes for polygon shapes.
  26. # Attributes are "POLYGON_VERTEX".
  27. # Record looks like:
  28. # \t(6.58333,1.14685)2;
  29. # \t\t$ATT;
  30. # \t\t"POLYGON_VERTEX" (0,0) "( 24 mils, 18 mils )" 2,0.06,1,2,1,1,0,0;
  31. # \t\t$END;
  32. #
  33. # 2. Bottom ground plane is INSTANCE (I record) at (0,0).
  34. # Attribute is "COMP" for instance component number.
  35. # Record looks like:
  36. # \tI ground_plane (0,0)(0,0)0,0,0;
  37. # \t\t$ATT;
  38. # \t\t"COMP" (0,0) "10001" 2,0.06,1,2,1,1,0,0;
  39. # \t\t$END;
  40. #
  41. # 3. Top ground plane, if it exists, is the second instance,
  42. # located at (0,$top_of_last_dielectric_layer).
  43. # Record looks like:
  44. # \tI ground_plane (0,3.29667)(0,3.29667)0,0,0;
  45. # \t\t$ATT;
  46. # \t\t"COMP" (0,0) "10002" 2,0.06,1,2,1,1,0,0;
  47. # \t\t$END;
  48. #
  49. # 4. Dielectric layers are drawn as RECTANGLE primitives.
  50. # First dielectric layer starts at y=0.32. Dielectric
  51. # layers are drawn as rectangles from x=1.25 to x=9.25.
  52. # Attributes are "LOWER_LEFT", "UPPER_RIGHT",
  53. # "RELATIVE_PERMITTIVITY", and "LOSS_TANGENT" (if != 0).
  54. # Record looks like:
  55. # \tR(1.25,0.32)(9.25,3.29667)2,0,0;
  56. # \t\t$ATT;
  57. # \t\t"LOWER_LEFT" (0,0) "( 0 mils , 0 mils )" 2,0.06,1,2,1,1,0,0;
  58. # \t\t"UPPER_RIGHT" (0,0) "( 156 mils , 52 mils )" 2,0.06,1,2,1,1,0,0;
  59. # \t\t"RELATIVE_PERMITTIVITY" (0,0) "4.2" 2,0.06,1,2,1,1,0,0;
  60. # \t\t$END;
  61. #
  62. # 5. Rectangle conductors are drawn as RECTANGLE primitives.
  63. # Attributes are "LOWER_LEFT", "UPPER_RIGHT", and
  64. # "SIGNAL_NAME".
  65. # Record looks like:
  66. # \tR(4.01923,0.548974)(4.17308,0.589045)3,47,1;
  67. # \t\t$ATT;
  68. # \t\t"SIGNAL_NAME" (0,0) "signal1" 2,0.06,1,2,1,1,0,0;
  69. # \t\t"LOWER_LEFT" (0,0) "( 54 mils , 4 mils )" 2,0.06,1,2,1,1,0,0;
  70. # \t\t"UPPER_RIGHT" (0,0) "( 57 mils , 4.7 mils )" 2,0.06,1,2,1,1,0,0;
  71. # \t\t$END;
  72. #
  73. # 6. Circle conductors are drawn as circles, with the "A" primitive.
  74. # (for ARC, I think). Circles are defined by their center and
  75. # radius, instead of bounding box.
  76. # Atttibutes are "CIRCLE_CENTER", "CIRCLE_RADIUS" and "SIGNAL_NAME"
  77. # \tA(4.07353,1.37059)(4.23039,1.37059)3,47,1;
  78. # \t\t$ATT;
  79. # \t\t"SIGNAL_NAME" (0,0) "signal1" 2,0.06,1,2,1,1,0,0;
  80. # \t\t"CIRCLE_CENTER" (0,0) "( 180 mils , 60 mils )" 2,0.06,1,2,1,1,0,0;
  81. # \t\t"CIRCLE_RADIUS" (0,0) "10 mils" 2,0.06,1,2,1,1,0,0;
  82. # \t\t$END;
  83. #
  84. # 7. Trapezoid conductors are drawn as polygons, with the "G" primitive.
  85. # Attribute is "SIGNAL_NAME". (Coordinates are all in the PINs.
  86. # Lord only knows how much work MMTL has to do to figure out the
  87. # connection between the PIN and the POLYGON coordinates. :-)
  88. # The polygon record looks like:
  89. # \tG 4 (6.138,1.146)(6.175,1.312)(6.54,1.312)(6.583,1.146)3,47,1;
  90. # \t\t$ATT;
  91. # \t\t"SIGNAL_NAME" (0,0) "signal4" 2,0.06,1,2,1,1,0,0;
  92. # \t\t$END;
  93. #
  94. # --------------------------------------------------------------------
  95. package provide bem 1.0
  96. package require Itcl
  97. # --------------------------------------------------------------------
  98. #
  99. # itcl::class gpge
  100. #
  101. # This class is a visitor to the CSDL structures. It can generate
  102. # a GPGE cross section from a Stackup or from a list of inidividual
  103. # CSDL structures.
  104. #
  105. # --------------------------------------------------------------------
  106. itcl::class gpge {
  107. #inherit CSDLvisitor
  108. variable xOffset 0.0
  109. variable yOffset 0.0
  110. variable totalWidth 0.0
  111. variable scaleFactor 0.0
  112. # Parts of the graphic file
  113. public variable polygonPins ""
  114. public variable iconAttributes ""
  115. # Unlike pins and attributes, we build up a list of
  116. # primitives, then sort them according to location.
  117. # Then objects appear in the graphic file in an order
  118. # that compares with the appearance of the cross section.
  119. public variable primList {}
  120. # State, which is set in higher level structures,
  121. # and used in lower level structures
  122. variable otherAttributes ""
  123. variable primProps "3,47,1"
  124. variable attrProps "2,0.06,1,2,1,1,0,0"
  125. variable structName
  126. # helper functions for translating coordinates
  127. method prim_coord { x y }
  128. method attr_coord { x y }
  129. method attr_length { x }
  130. # Produce and return a graphic file
  131. # (as a string)
  132. method graphic { stackup }
  133. # HLCSDL - Stackup Structures
  134. method visitStackup { stackup x y }
  135. method visitGroundPlane { groundPlane x y }
  136. method visitDielectricLayer { dielectricLayer x y }
  137. method visitRectangleDielectric { rectangleDielectric x y }
  138. method visitRectangleConductors { rectangleConductors x y }
  139. method visitTrapezoidConductors { trapezoidConductors x y }
  140. method visitCircleConductors { circleConductors x y }
  141. # LLCSDO - low level structures
  142. method visitDielectric { dielectric x y }
  143. method visitConductor { conductor x y }
  144. method visitGround { ground x y }
  145. method visitRectangle { rectangle x y }
  146. method visitTrapezoid { trapezoid x y }
  147. method visitCircle { circle x y }
  148. method visitLayer { layer x y }
  149. }
  150. # --------------------------------------------------------------------
  151. # helper functions for translating coordinates
  152. # --------------------------------------------------------------------
  153. # --------------------------------------------------------------------
  154. #
  155. # gpge::prim_coord
  156. #
  157. # Creates coordinate string for GPGE primitives.
  158. # The x and y dimensions are scaled to fit
  159. # on the 11x8.5 inch page.
  160. #
  161. # Note that we use the scale factor (computed in the
  162. # stackup visitor or the constructor), and add in a
  163. # hardcoded offset of (1.25,0.32) so that all coordinates
  164. # are "above" the first ground plane instance. This
  165. # first ground plane instance is required, and is hard
  166. # coded at (0,0).
  167. #
  168. # --------------------------------------------------------------------
  169. itcl::body gpge::prim_coord { x y } {
  170. format "(%g,%g)" \
  171. [expr {([length $x]+$xOffset)*$scaleFactor}] \
  172. [expr {([length $y]+$yOffset)*$scaleFactor + 0.32}]
  173. }
  174. # --------------------------------------------------------------------
  175. #
  176. # gpge::attr_coord
  177. #
  178. # Creates coordinate string for GPGE attributes.
  179. # The x and y dimensions are converted into
  180. # default units and have the units string appended.
  181. # For example: "( 80 mils , 12.5 mils )"
  182. #
  183. # --------------------------------------------------------------------
  184. itcl::body gpge::attr_coord { x y } {
  185. format "( %g %s , %g %s )" \
  186. [length $x] $units::default(Length) \
  187. [length $y] $units::default(Length)
  188. }
  189. # --------------------------------------------------------------------
  190. #
  191. # gpge::prim_coord
  192. #
  193. # Creates a length string for GPGE primitives.
  194. # The value is converted into default units, then
  195. # the units string is appended, so the value becomes
  196. # something like "20 mils"
  197. #
  198. # --------------------------------------------------------------------
  199. itcl::body gpge::attr_length { x } {
  200. format "%g %s" \
  201. [length $x] $units::default(Length)
  202. }
  203. # --------------------------------------------------------------------
  204. #
  205. # graphic
  206. #
  207. # Generate a graphic file and return it as a string.
  208. #
  209. # --------------------------------------------------------------------
  210. itcl::body gpge::graphic { stackup } {
  211. set primList {}
  212. set polygonPins ""
  213. # Process the layer stackup to get the major parts
  214. # of the graphic file description
  215. ::Stackup::accept $this 0 0
  216. # Initialize the graphic file string with information
  217. # from the layer stackup.
  218. set structureList $Stackup::structureList
  219. set stackup_design [info script]
  220. set coupling_length "[length $::Stackup::couplingLength] $units::default(Length)"
  221. set rise_time "[time $::Stackup::riseTime] $units::default(Time)"
  222. set graphic "\$ICON;\n"
  223. append graphic "\$DESIGN \"${stackup_design}\";\n"
  224. append graphic "\$ORIGIN (4.16,0);\n"
  225. append graphic "\$PINGRID (0,0);\n"
  226. append graphic "\t\t\$IATT;\n"
  227. append graphic "\t\t\"EM_TYPE\" (0,0) \"tran_line\" 2,0.06,1,2,1,1,0,0;\n"
  228. append graphic "\t\t\"PAGE1\" (0,0) \"10001\" 2,0.06,1,2,1,1,0,0;\n"
  229. append graphic "\t\t\$END;\n"
  230. append graphic "\$PINS;\n"
  231. append graphic "\$END;\n"
  232. append graphic "\$PRIMITIVES;\n"
  233. append graphic "\$END;\n"
  234. append graphic "\$CONNECTS;\n"
  235. append graphic "\$END;\n"
  236. append graphic "\$TEXT;\n"
  237. append graphic "\$END;\n"
  238. append graphic "\$OBJECT;\n"
  239. append graphic "\$PAGE 1;\n"
  240. append graphic "\$PAGESIZE (11,8.5);\n"
  241. append graphic "\$DESIGN \"${stackup_design}_1\";\n"
  242. append graphic "\$ORIGIN (0,0);\n"
  243. append graphic "\$PINGRID (0,0);\n"
  244. append graphic "\t\t\$IATT;\n"
  245. append graphic "\t\t\"COUPLING_LENGTH\" (0,0) \"${coupling_length}\" 2,0.06,1,2,1,1,0,0;\n"
  246. append graphic "\t\t\"RISETIME\" (0,0) \"${rise_time}\" 2,0.06,1,2,1,1,0,0;\n"
  247. # append graphic "\t\t\"FREQUENCY\" (0,0) \"${frequency}\" 2,0.06,1,2,1,1,0,0;\n"
  248. # append graphic "\t\t\"CONDUCTIVITY\" (0,0) \"${conductivity}\" 2,0.06,1,2,1,1,0,0;\n"
  249. append graphic "\t\t\"CONTOUR_SEGMENTS\" (0,0) \"10\" 2,0.06,1,2,1,1,0,0;\n"
  250. append graphic "\t\t\"PLANE_SEGMENTS\" (0,0) \"10\" 2,0.06,1,2,1,1,0,0;\n"
  251. append graphic "\t\t\$END;\n"
  252. append graphic "\$PINS;\n"
  253. # put trapezoid/polygon pins here
  254. append graphic $polygonPins
  255. append graphic "\$END;\n"
  256. append graphic "\$PRIMITIVES;\n"
  257. # Add bottom ground plane instance
  258. set struct [lindex $structureList 0]
  259. if {[$struct isa GroundPlane]} {
  260. append graphic "\tI ground_plane (0,0)(0,0)0,0,0;\n"
  261. append graphic "\t\t\$ATT;\n"
  262. append graphic "\t\t\"COMP\" (0,0) \"10001\" 2,0.06,1,2,1,1,0,0;\n"
  263. append graphic "\t\t\$END;\n"
  264. } else {
  265. error "Stackup must begin with a bottom GroundPlane"
  266. }
  267. # Calculate the thickness of the stackup, and add a
  268. # top ground plane if necessary.
  269. set y0 0
  270. foreach struct [lrange $structureList 1 end-1] {
  271. if {[$struct isa GroundPlane]} {
  272. error "Top GroundPlane must be last in the stackup"
  273. } else {
  274. if {[$struct isa DielectricLayer]} {
  275. set y0 [expr {$y0 + [$struct height]}]
  276. }
  277. }
  278. }
  279. set struct [lindex $structureList end]
  280. if {[$struct isa GroundPlane]} {
  281. scan [prim_coord 0 $y0] "(%f,%f)" xval yval
  282. append graphic "\tI ground_plane (0,$yval)(0,$yval)0,0,0;\n"
  283. append graphic "\t\t\$ATT;\n"
  284. append graphic "\t\t\"COMP\" (0,0) \"10002\" 2,0.06,1,2,1,1,0,0;\n"
  285. append graphic "\t\t\$END;\n"
  286. }
  287. # Sort primitives, bottom to top, left to right.
  288. # (increasing X and Y coordinates)
  289. set primList [lsort -command comparePrimXY $primList]
  290. # Add primitives to the graphics file string
  291. foreach prim $primList {
  292. append graphic $prim
  293. }
  294. append graphic "\$END;\n"
  295. append graphic "\$CONNECTS;\n"
  296. append graphic "\$END;\n"
  297. append graphic "\$TEXT;\n"
  298. append graphic "\$END;\n"
  299. # return the string value
  300. return $graphic
  301. }
  302. # --------------------------------------------------------------------
  303. #
  304. # comparePrimXY
  305. #
  306. # This procedure compares two primitive strings for sorting.
  307. # Each primitive is examined for its first (X,Y) coordinate
  308. # and the Y values, then the X values are compared. The
  309. # net effect is to sort the primitives from bottom to top, and
  310. # (at the same Y offset) from left to right.
  311. #
  312. # --------------------------------------------------------------------
  313. proc comparePrimXY { prim1 prim2 } {
  314. # Scan the primitive strings for their X and Y coords
  315. # (skip over non-open-parens, then scan for two floats)
  316. scan $prim1 {%[^(](%f,%f)} junk x1 y1
  317. scan $prim2 {%[^(](%f,%f)} junk x2 y2
  318. # If Y coordinates are equal, then compare X coordinates
  319. if { $y1 == $y2 } {
  320. set compare [expr {$x1 - $x2}]
  321. } else {
  322. set compare [expr {$y1 - $y2}]
  323. }
  324. # must return negative, zero, or positive integer,
  325. # so we have to translate the compare value
  326. if { $compare < 0 } {return -1}
  327. if { $compare > 0 } {return 1}
  328. return 0
  329. }
  330. # --------------------------------------------------------------------
  331. # HLCSDL - Stackup Structures
  332. # --------------------------------------------------------------------
  333. #
  334. # gpge::visitStackup
  335. #
  336. # Compute scale factors for GPGE drawing based on
  337. # total cross section height and width.
  338. #
  339. # --------------------------------------------------------------------
  340. itcl::body gpge::visitStackup { stackup x y } {
  341. set structureList $Stackup::structureList
  342. # Drawn cross section must be 3 times the maximum
  343. # conductor widths and/or dielectric thicknesses.
  344. # (For MMTL to work properly.)
  345. if { [::Stackup::height] > [::Stackup::width] } {
  346. set xOffset [::Stackup::height]
  347. } else {
  348. set xOffset [::Stackup::width]
  349. }
  350. set totalWidth [expr {3.0*$xOffset}]
  351. set condWidth 0.0
  352. set totalWidth 0.0
  353. set y0 0.0
  354. foreach struct $structureList {
  355. if {[$struct isa GroundPlane] || [$struct isa DielectricLayer]} {
  356. if { [$struct height] > 0.0 } {
  357. set y0 [expr {$y0 + [$struct height]}]
  358. }
  359. }
  360. if { [$struct width] > $totalWidth } {
  361. set totalWidth [$struct width]
  362. }
  363. if {! [$struct isa GroundPlane] && ! [$struct isa DielectricLayer]} {
  364. if { [$struct width] > $condWidth } {
  365. set condWidth [$struct width]
  366. }
  367. }
  368. }
  369. # Scale factor is based on total width
  370. set totalWidth [expr { $totalWidth * 2 }]
  371. set scaleFactor [expr {11.0/$totalWidth}]
  372. set xOffset [expr { ($totalWidth - $condWidth) * 0.5}]
  373. set y0 0
  374. foreach struct $structureList {
  375. if {[$struct isa GroundPlane] || [$struct isa DielectricLayer]} {
  376. set y0 [expr {$y0 + [$struct height]}]
  377. }
  378. $struct accept $this 0 $y0
  379. }
  380. }
  381. itcl::body gpge::visitGroundPlane { groundPlane x y } {}
  382. itcl::body gpge::visitDielectricLayer { dielectricLayer x y } {}
  383. itcl::body gpge::visitRectangleDielectric { rectangleDielectric x y } {}
  384. itcl::body gpge::visitRectangleConductors { rectangleConductors x y } {}
  385. itcl::body gpge::visitTrapezoidConductors { trapezoidConductors x y } {}
  386. itcl::body gpge::visitCircleConductors { circleConductors x y } {}
  387. # LLCSDO - low level structures
  388. itcl::body gpge::visitDielectric { dielectric x y } {
  389. set primProps "2,0,0"
  390. set attrProps "2,0.06,1,2,1,1,0,0"
  391. set structName $dielectric
  392. set permittivity [$dielectric cget -permittivity]
  393. set lossTangent [$dielectric cget -lossTangent]
  394. set otherAttributes ""
  395. append otherAttributes $otherAttributes
  396. append otherAttributes "\t\t\"RELATIVE_PERMITTIVITY\" (0,0)\
  397. \"${permittivity}\" $attrProps;\n"
  398. if { $lossTangent != 0.0 } {
  399. append otherAttributes "\t\t\"LOSS_TANGENT\" (0,0)\
  400. \"${lossTangent}\" $attrProps;\n"
  401. }
  402. }
  403. itcl::body gpge::visitConductor { conductor x y } {
  404. set attrProps "2,0.06,1,2,1,1,0,0"
  405. set name "$conductor"
  406. #---------------------------------------------------------------
  407. # If the conductor name starts with GR
  408. #---------------------------------------------------------------
  409. set typ [string range $name 2 3]
  410. set typ [string tolower $typ]
  411. if { [string compare $typ "gr"] == 0 } {
  412. set primProps "4,47,1"
  413. } else {
  414. set primProps "3,47,1"
  415. }
  416. set conductivity [$conductor cget -conductivity]
  417. set otherAttributes ""
  418. append otherAttributes $otherAttributes
  419. append otherAttributes "\t\t\"SIGNAL_NAME\" (0,0) \"${name}\" $attrProps;\n"
  420. append otherAttributes "\t\t\"CONDUCTIVITY\" (0,0) \"${conductivity}\" 2,0.06,1,2,1,1,0,0;\n"
  421. }
  422. itcl::body gpge::visitGround { ground x y} {
  423. set primProps "3,47,1"
  424. set attrProps "2,0.06,1,2,1,1,0,0"
  425. set otherAttributes ""
  426. }
  427. # --------------------------------------------------------------------
  428. #
  429. # gpge::visitRectangle
  430. #
  431. # --------------------------------------------------------------------
  432. itcl::body gpge::visitRectangle { rectangle xp yp } {
  433. # (x0,y1) + ----------- + (x1,y1)
  434. # | |
  435. # (x0,y0) + ----------- + (x1,y0)
  436. set x0 [length $xp]
  437. set y0 [length $yp]
  438. set x1 [expr {$x0 + [$rectangle width]}]
  439. set y1 [expr {$y0 + [$rectangle height]}]
  440. # Creates the GPGE primitive line and attributes for
  441. # LOWER_LEFT and UPPER_RIGHT coordinates.
  442. set primstring ""
  443. append primstring "\tR[prim_coord $x0 $y0][prim_coord $x1 $y1]$primProps;\n"
  444. append primstring "\t\t\$ATT;\n"
  445. append primstring "\t\t\"LOWER_LEFT\" (0,0) \"[attr_coord $x0 $y0]\" $attrProps;\n"
  446. append primstring "\t\t\"UPPER_RIGHT\" (0,0) \"[attr_coord $x1 $y1]\" $attrProps;\n"
  447. append primstring $otherAttributes
  448. append primstring "\t\t\$END;\n"
  449. lappend primList $primstring
  450. }
  451. # --------------------------------------------------------------------
  452. #
  453. # gpge::visitTrapezoid
  454. #
  455. # --------------------------------------------------------------------
  456. itcl::body gpge::visitTrapezoid { trapezoid xp yp } {
  457. # (x1,y1) + ----------- + (x2,y1)
  458. # / \
  459. # (x0,y0) + --------------- + (x3,y0)
  460. set xp [length $xp]
  461. set yp [length $yp]
  462. set topWidth [length [$trapezoid cget -topWidth]]
  463. set bottomWidth [length [$trapezoid cget -bottomWidth]]
  464. set width [$trapezoid width]
  465. set height [$trapezoid height]
  466. set x0 [expr {$xp + ($width - $bottomWidth)/2}]
  467. set x1 [expr {$xp + ($width - $topWidth)/2}]
  468. set x2 [expr {$xp + ($width + $topWidth)/2}]
  469. set x3 [expr {$xp + ($width + $bottomWidth)/2}]
  470. set y0 $yp
  471. set y1 [expr {$yp + $height}]
  472. set xcenter [expr {($x0 + $x3)/2}]
  473. set ycenter [expr {($y0 + $y1)/2}]
  474. # Create the GPGE primitive line and attributes for
  475. # LOWER_LEFT and UPPER_RIGHT coordinates.
  476. set primstring ""
  477. append primstring "\tG 4[prim_coord $x0 $y0][prim_coord $x1 $y1][prim_coord $x2 $y1][prim_coord $x3 $y0]$primProps;\n"
  478. append primstring "\t\t\$ATT;\n"
  479. append primstring $otherAttributes
  480. append primstring "\t\t\$END;\n"
  481. lappend primList $primstring
  482. # Create the GPGE pin definitions for this Trapezoid.
  483. append polygonPins "\t[prim_coord $x0 $y0]2;\n"
  484. append polygonPins "\t\t\$ATT;\n"
  485. append polygonPins "\t\t\"POLYGON_VERTEX\" (0,0) \"[attr_coord $x0 $y0]\" $attrProps;\n"
  486. append polygonPins "\t\t\$END;\n"
  487. append polygonPins "\t[prim_coord $x1 $y1]2;\n"
  488. append polygonPins "\t\t\$ATT;\n"
  489. append polygonPins "\t\t\"POLYGON_VERTEX\" (0,0) \"[attr_coord $x1 $y1]\" $attrProps;\n"
  490. append polygonPins "\t\t\$END;\n"
  491. append polygonPins "\t[prim_coord $x2 $y1]2;\n"
  492. append polygonPins "\t\t\$ATT;\n"
  493. append polygonPins "\t\t\"POLYGON_VERTEX\" (0,0) \"[attr_coord $x2 $y1]\" $attrProps;\n"
  494. append polygonPins "\t\t\$END;\n"
  495. append polygonPins "\t[prim_coord $x3 $y0]2;\n"
  496. append polygonPins "\t\t\$ATT;\n"
  497. append polygonPins "\t\t\"POLYGON_VERTEX\" (0,0) \"[attr_coord $x3 $y0]\" $attrProps;\n"
  498. append polygonPins "\t\t\$END;\n"
  499. }
  500. # --------------------------------------------------------------------
  501. #
  502. # gpge::visitCircle
  503. #
  504. # --------------------------------------------------------------------
  505. itcl::body gpge::visitCircle { circle xp yp } {
  506. # (x0,y1) + --- + (x1,y1)
  507. # | | (just imagine a circle in the box)
  508. # (x0,y0) + --- + (x1,y0)
  509. set diameter [length [$circle cget -diameter]]
  510. set x0 [length $xp]
  511. set y0 [length $yp]
  512. set x1 [expr {$x0 + $diameter}]
  513. set y1 [expr {$y0 + $diameter}]
  514. set xcenter [expr {($x0 + $x1)/2}]
  515. set ycenter [expr {($y0 + $y1)/2}]
  516. set radius [expr {$diameter/2}]
  517. # Creates the GPGE primitive line and attributes for
  518. # CIRCLE_CENTER and CIRCLE_RADIUS and $otherAttributes
  519. set primstring ""
  520. append primstring "\tA[prim_coord $xcenter $ycenter][prim_coord $x1 $ycenter]$primProps;\n"
  521. append primstring "\t\t\$ATT;\n"
  522. append primstring "\t\t\"CIRCLE_CENTER\" (0,0) \"[attr_coord $xcenter $ycenter]\" $attrProps;\n"
  523. append primstring "\t\t\"CIRCLE_RADIUS\" (0,0) \"[attr_length $radius]\" $attrProps;\n"
  524. append primstring $otherAttributes
  525. append primstring "\t\t\$END;\n"
  526. lappend primList $primstring
  527. }
  528. # --------------------------------------------------------------------
  529. #
  530. # gpge::visitLayer
  531. #
  532. # --------------------------------------------------------------------
  533. itcl::body gpge::visitLayer { layer x y } {
  534. # The layer width is really $totalWidth. Subtract
  535. # the X offset from X0. (prim_coord will add it back in
  536. # to get us back to zero)
  537. set x0 [expr {[length $x]-$xOffset}]
  538. set x1 [expr {$x0 + $totalWidth}]
  539. set y1 [length $y]
  540. set y0 [expr {$y1 - [length [$layer cget -thickness]]}]
  541. if { [$layer cget -thickness] == 0 } {
  542. return
  543. }
  544. # Creates the GPGE primitive line and attributes for
  545. # LOWER_LEFT and UPPER_RIGHT coordinates.
  546. set primstring ""
  547. append primstring "\tR[prim_coord $x0 $y0][prim_coord $x1 $y1]$primProps;\n"
  548. append primstring "\t\t\$ATT;\n"
  549. append primstring "\t\t\"LOWER_LEFT\" (0,0) \"[attr_coord $x0 $y0]\" $attrProps;\n"
  550. append primstring "\t\t\"UPPER_RIGHT\" (0,0) \"[attr_coord $x1 $y1]\" $attrProps;\n"
  551. append primstring $otherAttributes
  552. append primstring "\t\t\$END;\n"
  553. lappend primList $primstring
  554. }