Adjust Xfig figure depths with figdepth

John Peck
Published

Xfig's depth settings can create some headaches when you use figure libraries. Library figures can use depths that conflict with your current drawing. Say I have this drawing of the Teensy Audio Board and a red circle,

Teensy audio board and a red circle

...and then I move the red circle over the board:

Overlapping objects without depth correction

This is clearly not what I want. The circle has a depth of 50, and the board has depths between 10 and 60. The circle ends up on top of some objects and not others. If you were using PowerPoint, you would just select Bring to Front or Send to Back to arrange the objects. But Xfig requires setting the depth of each member object individually, which you should really do with a script like figdepth.

Using figdepth

Figdepth has some options, the most important of which is the minimum depth argument

Figdepth command options

...which sets the depth of the topmost object in a fig file. The script simply increments all depths by some number to make this minimum depth to be your setting. You will, of course, need to have everything you want to modify in its own fig file. You can then run figdepth like

Figdepth use

...to write your new depth-adjusted figure. Use Xfig's merge command to bring the new figure into your old drawing. My new drawing looks like this:

Fixed overlap

...with all objects in the Teensy Audio Board at a deeper depth than the red circle.

How does it work?

The Fig file format is really simple, which is one reason why I like Xfig so much. You can figure out what kind of object each line describes by looking at the first character. You then figure out which number in the line is the object's depth and increment it. The switch statement below shows how one line is processed.

proc increase_object_depth { xfig_line depth_increase} {
    # Return a new xfig line with the depth increased
    #
    # Arguments:
    #   xfig_line -- Single line from an xfig file
    #   depth_increase -- Amount to increase the depth
    set entry_list [split $xfig_line]
    set first_character [lindex $entry_list 0]
    switch $first_character {
    "0" {
        # Color object -- nothing to do
        return $xfig_line
    }
    "1" {
        # Ellipse
        set depth_index 6
        set old_depth [get_object_depth $xfig_line]
        set new_depth [expr $old_depth + $depth_increase]
        set new_entry_list [lset entry_list $depth_index $new_depth]
        set new_line [join $new_entry_list]
        return $new_line
    }
    "2" {
        # Polyline (also imported picture bounding boxes)
        set depth_index 6
        set old_depth [get_object_depth $xfig_line]
        set new_depth [expr $old_depth + $depth_increase]
        set new_entry_list [lset entry_list $depth_index $new_depth]
        set new_line [join $new_entry_list]
        return $new_line
    }
    "3" {
        # Spline
        set depth_index 6
        set old_depth [get_object_depth $xfig_line]
        set new_depth [expr $old_depth + $depth_increase]
        set new_entry_list [lset entry_list $depth_index $new_depth]
        set new_line [join $new_entry_list]
        return $new_line
    }
    "4" {
        # Text
        set depth_index 3
        set old_depth [get_object_depth $xfig_line]
        set new_depth [expr $old_depth + $depth_increase]
        set new_entry_list [lset entry_list $depth_index $new_depth]
        set new_line [join $new_entry_list]
        return $new_line
    }
    "5" {
        # Arc
        set depth_index 6
        set old_depth [get_object_depth $xfig_line]
        set new_depth [expr $old_depth + $depth_increase]
        set new_entry_list [lset entry_list $depth_index $new_depth]
        set new_line [join $new_entry_list]
        return $new_line
    }
    "6" {
        # Compound -- nothing to do
        return $xfig_line
    }
    default {
        # Some non-object -- nothing to do
        return $xfig_line
    }
  }
}

Having trouble with cmdline?

Figdepth uses the cmdline package from tcllib to handle command line arguments. I usually run scripts out of Eshell in Emacs, so I have this in my .emacs:

eshell setup

...to set the TCLLIBPATH environment variable. This tells Tcl where to find Tcllib's packages.

Where is the figdepth script?

Figdepth is part of my xfigart repository.