123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638 |
- # --------------------------------------------------------------------
- #
- # gpge.itcl
- #
- # The classes in this file can generate a GPGE graphic file
- # from the CSDL description, which can in turn be used
- # in MMTL simulators.
- #
- # Bob Techentin
- # February 2, 2001
- #
- # Copyright 2001-2004 Mayo Foundation. All Rights Reserved.
- # $Id: bem_gpge.itcl,v 1.4 2004/02/12 22:28:27 techenti Exp $
- #
- # --------------------------------------------------------------------
- # --------------------------------------------------------------------
- #
- # Rules for making a GPGE graphic cross section
- #
- # 0. Object section starts with $OBJECT, $PAGE, $PAGESIZE, $DESIGN
- # $ORIGIN, and $PINGRID records, followed by ICON section attributes
- # "COUPLING_LENGTH", "RISETIME", "FREQUENCY" (if != 0),
- # "CONDUCTIVITY" (if != 0), "CONTOUR_SEGMENTS" and "PLANE_SEGMENTS".
- #
- # 1. Pins and pin attributes for polygon shapes.
- # Attributes are "POLYGON_VERTEX".
- # Record looks like:
- # \t(6.58333,1.14685)2;
- # \t\t$ATT;
- # \t\t"POLYGON_VERTEX" (0,0) "( 24 mils, 18 mils )" 2,0.06,1,2,1,1,0,0;
- # \t\t$END;
- #
- # 2. Bottom ground plane is INSTANCE (I record) at (0,0).
- # Attribute is "COMP" for instance component number.
- # Record looks like:
- # \tI ground_plane (0,0)(0,0)0,0,0;
- # \t\t$ATT;
- # \t\t"COMP" (0,0) "10001" 2,0.06,1,2,1,1,0,0;
- # \t\t$END;
- #
- # 3. Top ground plane, if it exists, is the second instance,
- # located at (0,$top_of_last_dielectric_layer).
- # Record looks like:
- # \tI ground_plane (0,3.29667)(0,3.29667)0,0,0;
- # \t\t$ATT;
- # \t\t"COMP" (0,0) "10002" 2,0.06,1,2,1,1,0,0;
- # \t\t$END;
- #
- # 4. Dielectric layers are drawn as RECTANGLE primitives.
- # First dielectric layer starts at y=0.32. Dielectric
- # layers are drawn as rectangles from x=1.25 to x=9.25.
- # Attributes are "LOWER_LEFT", "UPPER_RIGHT",
- # "RELATIVE_PERMITTIVITY", and "LOSS_TANGENT" (if != 0).
- # Record looks like:
- # \tR(1.25,0.32)(9.25,3.29667)2,0,0;
- # \t\t$ATT;
- # \t\t"LOWER_LEFT" (0,0) "( 0 mils , 0 mils )" 2,0.06,1,2,1,1,0,0;
- # \t\t"UPPER_RIGHT" (0,0) "( 156 mils , 52 mils )" 2,0.06,1,2,1,1,0,0;
- # \t\t"RELATIVE_PERMITTIVITY" (0,0) "4.2" 2,0.06,1,2,1,1,0,0;
- # \t\t$END;
- #
- # 5. Rectangle conductors are drawn as RECTANGLE primitives.
- # Attributes are "LOWER_LEFT", "UPPER_RIGHT", and
- # "SIGNAL_NAME".
- # Record looks like:
- # \tR(4.01923,0.548974)(4.17308,0.589045)3,47,1;
- # \t\t$ATT;
- # \t\t"SIGNAL_NAME" (0,0) "signal1" 2,0.06,1,2,1,1,0,0;
- # \t\t"LOWER_LEFT" (0,0) "( 54 mils , 4 mils )" 2,0.06,1,2,1,1,0,0;
- # \t\t"UPPER_RIGHT" (0,0) "( 57 mils , 4.7 mils )" 2,0.06,1,2,1,1,0,0;
- # \t\t$END;
- #
- # 6. Circle conductors are drawn as circles, with the "A" primitive.
- # (for ARC, I think). Circles are defined by their center and
- # radius, instead of bounding box.
- # Atttibutes are "CIRCLE_CENTER", "CIRCLE_RADIUS" and "SIGNAL_NAME"
- # \tA(4.07353,1.37059)(4.23039,1.37059)3,47,1;
- # \t\t$ATT;
- # \t\t"SIGNAL_NAME" (0,0) "signal1" 2,0.06,1,2,1,1,0,0;
- # \t\t"CIRCLE_CENTER" (0,0) "( 180 mils , 60 mils )" 2,0.06,1,2,1,1,0,0;
- # \t\t"CIRCLE_RADIUS" (0,0) "10 mils" 2,0.06,1,2,1,1,0,0;
- # \t\t$END;
- #
- # 7. Trapezoid conductors are drawn as polygons, with the "G" primitive.
- # Attribute is "SIGNAL_NAME". (Coordinates are all in the PINs.
- # Lord only knows how much work MMTL has to do to figure out the
- # connection between the PIN and the POLYGON coordinates. :-)
- # The polygon record looks like:
- # \tG 4 (6.138,1.146)(6.175,1.312)(6.54,1.312)(6.583,1.146)3,47,1;
- # \t\t$ATT;
- # \t\t"SIGNAL_NAME" (0,0) "signal4" 2,0.06,1,2,1,1,0,0;
- # \t\t$END;
- #
- # --------------------------------------------------------------------
- package provide bem 1.0
- package require Itcl
- # --------------------------------------------------------------------
- #
- # itcl::class gpge
- #
- # This class is a visitor to the CSDL structures. It can generate
- # a GPGE cross section from a Stackup or from a list of inidividual
- # CSDL structures.
- #
- # --------------------------------------------------------------------
- itcl::class gpge {
- #inherit CSDLvisitor
- variable xOffset 0.0
- variable yOffset 0.0
- variable totalWidth 0.0
- variable scaleFactor 0.0
- # Parts of the graphic file
- public variable polygonPins ""
- public variable iconAttributes ""
- # Unlike pins and attributes, we build up a list of
- # primitives, then sort them according to location.
- # Then objects appear in the graphic file in an order
- # that compares with the appearance of the cross section.
- public variable primList {}
- # State, which is set in higher level structures,
- # and used in lower level structures
- variable otherAttributes ""
- variable primProps "3,47,1"
- variable attrProps "2,0.06,1,2,1,1,0,0"
- variable structName
- # helper functions for translating coordinates
- method prim_coord { x y }
- method attr_coord { x y }
- method attr_length { x }
- # Produce and return a graphic file
- # (as a string)
- method graphic { stackup }
- # HLCSDL - Stackup Structures
- method visitStackup { stackup x y }
- method visitGroundPlane { groundPlane x y }
- method visitDielectricLayer { dielectricLayer x y }
- method visitRectangleDielectric { rectangleDielectric x y }
- method visitRectangleConductors { rectangleConductors x y }
- method visitTrapezoidConductors { trapezoidConductors x y }
- method visitCircleConductors { circleConductors x y }
- # LLCSDO - low level structures
- method visitDielectric { dielectric x y }
- method visitConductor { conductor x y }
- method visitGround { ground x y }
- method visitRectangle { rectangle x y }
- method visitTrapezoid { trapezoid x y }
- method visitCircle { circle x y }
- method visitLayer { layer x y }
- }
- # --------------------------------------------------------------------
- # helper functions for translating coordinates
- # --------------------------------------------------------------------
- # --------------------------------------------------------------------
- #
- # gpge::prim_coord
- #
- # Creates coordinate string for GPGE primitives.
- # The x and y dimensions are scaled to fit
- # on the 11x8.5 inch page.
- #
- # Note that we use the scale factor (computed in the
- # stackup visitor or the constructor), and add in a
- # hardcoded offset of (1.25,0.32) so that all coordinates
- # are "above" the first ground plane instance. This
- # first ground plane instance is required, and is hard
- # coded at (0,0).
- #
- # --------------------------------------------------------------------
- itcl::body gpge::prim_coord { x y } {
- format "(%g,%g)" \
- [expr {([length $x]+$xOffset)*$scaleFactor}] \
- [expr {([length $y]+$yOffset)*$scaleFactor + 0.32}]
- }
- # --------------------------------------------------------------------
- #
- # gpge::attr_coord
- #
- # Creates coordinate string for GPGE attributes.
- # The x and y dimensions are converted into
- # default units and have the units string appended.
- # For example: "( 80 mils , 12.5 mils )"
- #
- # --------------------------------------------------------------------
- itcl::body gpge::attr_coord { x y } {
- format "( %g %s , %g %s )" \
- [length $x] $units::default(Length) \
- [length $y] $units::default(Length)
- }
- # --------------------------------------------------------------------
- #
- # gpge::prim_coord
- #
- # Creates a length string for GPGE primitives.
- # The value is converted into default units, then
- # the units string is appended, so the value becomes
- # something like "20 mils"
- #
- # --------------------------------------------------------------------
- itcl::body gpge::attr_length { x } {
- format "%g %s" \
- [length $x] $units::default(Length)
- }
- # --------------------------------------------------------------------
- #
- # graphic
- #
- # Generate a graphic file and return it as a string.
- #
- # --------------------------------------------------------------------
- itcl::body gpge::graphic { stackup } {
- set primList {}
- set polygonPins ""
- # Process the layer stackup to get the major parts
- # of the graphic file description
- ::Stackup::accept $this 0 0
- # Initialize the graphic file string with information
- # from the layer stackup.
- set structureList $Stackup::structureList
- set stackup_design [info script]
- set coupling_length "[length $::Stackup::couplingLength] $units::default(Length)"
- set rise_time "[time $::Stackup::riseTime] $units::default(Time)"
- set graphic "\$ICON;\n"
- append graphic "\$DESIGN \"${stackup_design}\";\n"
- append graphic "\$ORIGIN (4.16,0);\n"
- append graphic "\$PINGRID (0,0);\n"
- append graphic "\t\t\$IATT;\n"
- append graphic "\t\t\"EM_TYPE\" (0,0) \"tran_line\" 2,0.06,1,2,1,1,0,0;\n"
- append graphic "\t\t\"PAGE1\" (0,0) \"10001\" 2,0.06,1,2,1,1,0,0;\n"
- append graphic "\t\t\$END;\n"
- append graphic "\$PINS;\n"
- append graphic "\$END;\n"
- append graphic "\$PRIMITIVES;\n"
- append graphic "\$END;\n"
- append graphic "\$CONNECTS;\n"
- append graphic "\$END;\n"
- append graphic "\$TEXT;\n"
- append graphic "\$END;\n"
- append graphic "\$OBJECT;\n"
- append graphic "\$PAGE 1;\n"
- append graphic "\$PAGESIZE (11,8.5);\n"
- append graphic "\$DESIGN \"${stackup_design}_1\";\n"
- append graphic "\$ORIGIN (0,0);\n"
- append graphic "\$PINGRID (0,0);\n"
- append graphic "\t\t\$IATT;\n"
- append graphic "\t\t\"COUPLING_LENGTH\" (0,0) \"${coupling_length}\" 2,0.06,1,2,1,1,0,0;\n"
- append graphic "\t\t\"RISETIME\" (0,0) \"${rise_time}\" 2,0.06,1,2,1,1,0,0;\n"
- # append graphic "\t\t\"FREQUENCY\" (0,0) \"${frequency}\" 2,0.06,1,2,1,1,0,0;\n"
- # append graphic "\t\t\"CONDUCTIVITY\" (0,0) \"${conductivity}\" 2,0.06,1,2,1,1,0,0;\n"
- append graphic "\t\t\"CONTOUR_SEGMENTS\" (0,0) \"10\" 2,0.06,1,2,1,1,0,0;\n"
- append graphic "\t\t\"PLANE_SEGMENTS\" (0,0) \"10\" 2,0.06,1,2,1,1,0,0;\n"
- append graphic "\t\t\$END;\n"
- append graphic "\$PINS;\n"
- # put trapezoid/polygon pins here
- append graphic $polygonPins
- append graphic "\$END;\n"
- append graphic "\$PRIMITIVES;\n"
- # Add bottom ground plane instance
- set struct [lindex $structureList 0]
- if {[$struct isa GroundPlane]} {
- append graphic "\tI ground_plane (0,0)(0,0)0,0,0;\n"
- append graphic "\t\t\$ATT;\n"
- append graphic "\t\t\"COMP\" (0,0) \"10001\" 2,0.06,1,2,1,1,0,0;\n"
- append graphic "\t\t\$END;\n"
- } else {
- error "Stackup must begin with a bottom GroundPlane"
- }
- # Calculate the thickness of the stackup, and add a
- # top ground plane if necessary.
- set y0 0
- foreach struct [lrange $structureList 1 end-1] {
- if {[$struct isa GroundPlane]} {
- error "Top GroundPlane must be last in the stackup"
- } else {
- if {[$struct isa DielectricLayer]} {
- set y0 [expr {$y0 + [$struct height]}]
- }
- }
- }
- set struct [lindex $structureList end]
- if {[$struct isa GroundPlane]} {
- scan [prim_coord 0 $y0] "(%f,%f)" xval yval
- append graphic "\tI ground_plane (0,$yval)(0,$yval)0,0,0;\n"
- append graphic "\t\t\$ATT;\n"
- append graphic "\t\t\"COMP\" (0,0) \"10002\" 2,0.06,1,2,1,1,0,0;\n"
- append graphic "\t\t\$END;\n"
- }
- # Sort primitives, bottom to top, left to right.
- # (increasing X and Y coordinates)
- set primList [lsort -command comparePrimXY $primList]
- # Add primitives to the graphics file string
- foreach prim $primList {
- append graphic $prim
- }
- append graphic "\$END;\n"
- append graphic "\$CONNECTS;\n"
- append graphic "\$END;\n"
- append graphic "\$TEXT;\n"
- append graphic "\$END;\n"
- # return the string value
- return $graphic
- }
- # --------------------------------------------------------------------
- #
- # comparePrimXY
- #
- # This procedure compares two primitive strings for sorting.
- # Each primitive is examined for its first (X,Y) coordinate
- # and the Y values, then the X values are compared. The
- # net effect is to sort the primitives from bottom to top, and
- # (at the same Y offset) from left to right.
- #
- # --------------------------------------------------------------------
- proc comparePrimXY { prim1 prim2 } {
- # Scan the primitive strings for their X and Y coords
- # (skip over non-open-parens, then scan for two floats)
- scan $prim1 {%[^(](%f,%f)} junk x1 y1
- scan $prim2 {%[^(](%f,%f)} junk x2 y2
- # If Y coordinates are equal, then compare X coordinates
- if { $y1 == $y2 } {
- set compare [expr {$x1 - $x2}]
- } else {
- set compare [expr {$y1 - $y2}]
- }
- # must return negative, zero, or positive integer,
- # so we have to translate the compare value
- if { $compare < 0 } {return -1}
- if { $compare > 0 } {return 1}
- return 0
- }
- # --------------------------------------------------------------------
- # HLCSDL - Stackup Structures
- # --------------------------------------------------------------------
- #
- # gpge::visitStackup
- #
- # Compute scale factors for GPGE drawing based on
- # total cross section height and width.
- #
- # --------------------------------------------------------------------
- itcl::body gpge::visitStackup { stackup x y } {
- set structureList $Stackup::structureList
- # Drawn cross section must be 3 times the maximum
- # conductor widths and/or dielectric thicknesses.
- # (For MMTL to work properly.)
- if { [::Stackup::height] > [::Stackup::width] } {
- set xOffset [::Stackup::height]
- } else {
- set xOffset [::Stackup::width]
- }
- set totalWidth [expr {3.0*$xOffset}]
- set condWidth 0.0
- set totalWidth 0.0
- set y0 0.0
- foreach struct $structureList {
- if {[$struct isa GroundPlane] || [$struct isa DielectricLayer]} {
- if { [$struct height] > 0.0 } {
- set y0 [expr {$y0 + [$struct height]}]
- }
- }
- if { [$struct width] > $totalWidth } {
- set totalWidth [$struct width]
- }
- if {! [$struct isa GroundPlane] && ! [$struct isa DielectricLayer]} {
- if { [$struct width] > $condWidth } {
- set condWidth [$struct width]
- }
- }
- }
- # Scale factor is based on total width
- set totalWidth [expr { $totalWidth * 2 }]
- set scaleFactor [expr {11.0/$totalWidth}]
- set xOffset [expr { ($totalWidth - $condWidth) * 0.5}]
- set y0 0
- foreach struct $structureList {
- if {[$struct isa GroundPlane] || [$struct isa DielectricLayer]} {
- set y0 [expr {$y0 + [$struct height]}]
- }
- $struct accept $this 0 $y0
- }
- }
- itcl::body gpge::visitGroundPlane { groundPlane x y } {}
- itcl::body gpge::visitDielectricLayer { dielectricLayer x y } {}
- itcl::body gpge::visitRectangleDielectric { rectangleDielectric x y } {}
- itcl::body gpge::visitRectangleConductors { rectangleConductors x y } {}
- itcl::body gpge::visitTrapezoidConductors { trapezoidConductors x y } {}
- itcl::body gpge::visitCircleConductors { circleConductors x y } {}
- # LLCSDO - low level structures
- itcl::body gpge::visitDielectric { dielectric x y } {
- set primProps "2,0,0"
- set attrProps "2,0.06,1,2,1,1,0,0"
- set structName $dielectric
- set permittivity [$dielectric cget -permittivity]
- set lossTangent [$dielectric cget -lossTangent]
- set otherAttributes ""
- append otherAttributes $otherAttributes
- append otherAttributes "\t\t\"RELATIVE_PERMITTIVITY\" (0,0)\
- \"${permittivity}\" $attrProps;\n"
- if { $lossTangent != 0.0 } {
- append otherAttributes "\t\t\"LOSS_TANGENT\" (0,0)\
- \"${lossTangent}\" $attrProps;\n"
- }
- }
- itcl::body gpge::visitConductor { conductor x y } {
- set attrProps "2,0.06,1,2,1,1,0,0"
- set name "$conductor"
- #---------------------------------------------------------------
- # If the conductor name starts with GR
- #---------------------------------------------------------------
- set typ [string range $name 2 3]
- set typ [string tolower $typ]
- if { [string compare $typ "gr"] == 0 } {
- set primProps "4,47,1"
- } else {
- set primProps "3,47,1"
- }
- set conductivity [$conductor cget -conductivity]
- set otherAttributes ""
- append otherAttributes $otherAttributes
- append otherAttributes "\t\t\"SIGNAL_NAME\" (0,0) \"${name}\" $attrProps;\n"
- append otherAttributes "\t\t\"CONDUCTIVITY\" (0,0) \"${conductivity}\" 2,0.06,1,2,1,1,0,0;\n"
- }
- itcl::body gpge::visitGround { ground x y} {
- set primProps "3,47,1"
- set attrProps "2,0.06,1,2,1,1,0,0"
- set otherAttributes ""
- }
- # --------------------------------------------------------------------
- #
- # gpge::visitRectangle
- #
- # --------------------------------------------------------------------
- itcl::body gpge::visitRectangle { rectangle xp yp } {
- # (x0,y1) + ----------- + (x1,y1)
- # | |
- # (x0,y0) + ----------- + (x1,y0)
-
- set x0 [length $xp]
- set y0 [length $yp]
- set x1 [expr {$x0 + [$rectangle width]}]
- set y1 [expr {$y0 + [$rectangle height]}]
-
- # Creates the GPGE primitive line and attributes for
- # LOWER_LEFT and UPPER_RIGHT coordinates.
- set primstring ""
- append primstring "\tR[prim_coord $x0 $y0][prim_coord $x1 $y1]$primProps;\n"
- append primstring "\t\t\$ATT;\n"
- append primstring "\t\t\"LOWER_LEFT\" (0,0) \"[attr_coord $x0 $y0]\" $attrProps;\n"
- append primstring "\t\t\"UPPER_RIGHT\" (0,0) \"[attr_coord $x1 $y1]\" $attrProps;\n"
- append primstring $otherAttributes
- append primstring "\t\t\$END;\n"
- lappend primList $primstring
- }
- # --------------------------------------------------------------------
- #
- # gpge::visitTrapezoid
- #
- # --------------------------------------------------------------------
- itcl::body gpge::visitTrapezoid { trapezoid xp yp } {
- # (x1,y1) + ----------- + (x2,y1)
- # / \
- # (x0,y0) + --------------- + (x3,y0)
- set xp [length $xp]
- set yp [length $yp]
- set topWidth [length [$trapezoid cget -topWidth]]
- set bottomWidth [length [$trapezoid cget -bottomWidth]]
- set width [$trapezoid width]
- set height [$trapezoid height]
- set x0 [expr {$xp + ($width - $bottomWidth)/2}]
- set x1 [expr {$xp + ($width - $topWidth)/2}]
- set x2 [expr {$xp + ($width + $topWidth)/2}]
- set x3 [expr {$xp + ($width + $bottomWidth)/2}]
- set y0 $yp
- set y1 [expr {$yp + $height}]
- set xcenter [expr {($x0 + $x3)/2}]
- set ycenter [expr {($y0 + $y1)/2}]
- # Create the GPGE primitive line and attributes for
- # LOWER_LEFT and UPPER_RIGHT coordinates.
- set primstring ""
- append primstring "\tG 4[prim_coord $x0 $y0][prim_coord $x1 $y1][prim_coord $x2 $y1][prim_coord $x3 $y0]$primProps;\n"
- append primstring "\t\t\$ATT;\n"
- append primstring $otherAttributes
- append primstring "\t\t\$END;\n"
- lappend primList $primstring
- # Create the GPGE pin definitions for this Trapezoid.
- append polygonPins "\t[prim_coord $x0 $y0]2;\n"
- append polygonPins "\t\t\$ATT;\n"
- append polygonPins "\t\t\"POLYGON_VERTEX\" (0,0) \"[attr_coord $x0 $y0]\" $attrProps;\n"
- append polygonPins "\t\t\$END;\n"
- append polygonPins "\t[prim_coord $x1 $y1]2;\n"
- append polygonPins "\t\t\$ATT;\n"
- append polygonPins "\t\t\"POLYGON_VERTEX\" (0,0) \"[attr_coord $x1 $y1]\" $attrProps;\n"
- append polygonPins "\t\t\$END;\n"
- append polygonPins "\t[prim_coord $x2 $y1]2;\n"
- append polygonPins "\t\t\$ATT;\n"
- append polygonPins "\t\t\"POLYGON_VERTEX\" (0,0) \"[attr_coord $x2 $y1]\" $attrProps;\n"
- append polygonPins "\t\t\$END;\n"
- append polygonPins "\t[prim_coord $x3 $y0]2;\n"
- append polygonPins "\t\t\$ATT;\n"
- append polygonPins "\t\t\"POLYGON_VERTEX\" (0,0) \"[attr_coord $x3 $y0]\" $attrProps;\n"
- append polygonPins "\t\t\$END;\n"
- }
- # --------------------------------------------------------------------
- #
- # gpge::visitCircle
- #
- # --------------------------------------------------------------------
- itcl::body gpge::visitCircle { circle xp yp } {
- # (x0,y1) + --- + (x1,y1)
- # | | (just imagine a circle in the box)
- # (x0,y0) + --- + (x1,y0)
- set diameter [length [$circle cget -diameter]]
- set x0 [length $xp]
- set y0 [length $yp]
- set x1 [expr {$x0 + $diameter}]
- set y1 [expr {$y0 + $diameter}]
- set xcenter [expr {($x0 + $x1)/2}]
- set ycenter [expr {($y0 + $y1)/2}]
- set radius [expr {$diameter/2}]
- # Creates the GPGE primitive line and attributes for
- # CIRCLE_CENTER and CIRCLE_RADIUS and $otherAttributes
- set primstring ""
- append primstring "\tA[prim_coord $xcenter $ycenter][prim_coord $x1 $ycenter]$primProps;\n"
- append primstring "\t\t\$ATT;\n"
- append primstring "\t\t\"CIRCLE_CENTER\" (0,0) \"[attr_coord $xcenter $ycenter]\" $attrProps;\n"
- append primstring "\t\t\"CIRCLE_RADIUS\" (0,0) \"[attr_length $radius]\" $attrProps;\n"
- append primstring $otherAttributes
- append primstring "\t\t\$END;\n"
- lappend primList $primstring
- }
- # --------------------------------------------------------------------
- #
- # gpge::visitLayer
- #
- # --------------------------------------------------------------------
- itcl::body gpge::visitLayer { layer x y } {
- # The layer width is really $totalWidth. Subtract
- # the X offset from X0. (prim_coord will add it back in
- # to get us back to zero)
- set x0 [expr {[length $x]-$xOffset}]
- set x1 [expr {$x0 + $totalWidth}]
- set y1 [length $y]
- set y0 [expr {$y1 - [length [$layer cget -thickness]]}]
- if { [$layer cget -thickness] == 0 } {
- return
- }
- # Creates the GPGE primitive line and attributes for
- # LOWER_LEFT and UPPER_RIGHT coordinates.
- set primstring ""
- append primstring "\tR[prim_coord $x0 $y0][prim_coord $x1 $y1]$primProps;\n"
- append primstring "\t\t\$ATT;\n"
- append primstring "\t\t\"LOWER_LEFT\" (0,0) \"[attr_coord $x0 $y0]\" $attrProps;\n"
- append primstring "\t\t\"UPPER_RIGHT\" (0,0) \"[attr_coord $x1 $y1]\" $attrProps;\n"
- append primstring $otherAttributes
- append primstring "\t\t\$END;\n"
- lappend primList $primstring
- }
|