tgif(1)

๐ŸŒธ tgif(1) โ€” General Commands Manual ๐ŸŒธ

okay bestie, sit down, hydrate, because we are about to talk about tgif โ€” an Xlib based interactive 2-D drawing facility under X11, and no, it is not just a cute little doodle app, it is so much more. it supports hierarchical construction of drawings AND easy navigation between sets of drawings (the way it just organizes for you?? obsessed). and plot twist: it's also a hyper-graphics (or hyper-structured-graphics) browser on the World-Wide-Web. main character energy fr fr ๐Ÿ’…


โœจ NAME โœจ

tgif โ€” Xlib based interactive 2-D drawing facility under X11. Supports hierarchical construction of drawings and easy navigation between sets of drawings. It's also a hyper-graphics (or hyper-structured-graphics) browser on the World-Wide-Web. ๐Ÿฆ‹


๐ŸŽ€ SYNOPSIS ๐ŸŽ€

so there are literally two whole modes and you gotta pick your fighter. first form:

tgif [-display displayname] [-fg <color>] [-bg <color>] [-bd <color>]
[-rv] [-nv] [-bw] [-reqcolor] [-cwo[+sbwarp]] [-hyper] [-exec <file>]
[-dbim {xcin|chinput|xim|kinput2|tgtwb5[,font]}] [-sbim xim] [-usexlib]
[{-a4|-letter}] [-listdontreencode] [-version] [-pdfspd | -pdfspd=true |
-pdfspd=false ] [-pssetup "<string>" ] [-tgwb2 [-rmcastlibdir
<directory> | -rmcastlibpath <path>]] [-nomode] [-geometry <geom>]
[=<geom>] [{file[.obj]|-merge file1[.obj] file2[.obj] ...}]

or, and hear me out, the printing era:

tgif -print [-eps] [-p] [-ps] [-f] [-text] [-epsi] [-tiffepsi] [-gif]
[-png] [-jpeg] [-ppm] [-pbm] [-xpm] [-xbm] [-html] [-pdf] [-netlist]
[-svg] [-display displayname] [-stdout] [-raw[+h[eaderonly]]]
[-dosepsfilter [-previewonly]] [-status] [-gray] [-color | -reqcolor]
[-adobe | -adobe=<number>/<number> | -adobe=false ]
[-dontreencode=<string> | -listdontreencode] [-version | -justversion]
[-producedby=<string>] [-page <number>] [-print_cmd "<command>"]
[-one_file_per_page] [-pepsc] [-pdfspd | -pdfspd=true | -pdfspd=false ]
[-pssetup "<string>" ] [-j2p6_cmd "<command>" ] [-dontcondense |
-condensed] [{-a4|-letter}] [-noshowpageineps] [-quiet] [-bop_hook
"<string>"] [-eop_hook "<string>"] [-tmp_file_mode "<octal number>"]
[-patterndir "<xbm directory>"] [-o<dir>] [-exec <file>] [file1[.obj]
file2[.obj] ...]

๐Ÿ’– DESCRIPTION ๐Ÿ’–

Tgif is an interactive drawing tool that lets you draw and manipulate objects in the X Window System. iconic behavior honestly. ๐ŸŒˆ

Tgif runs interactively in the first form. But in that second form up there in the SYNOPSIS section? it just prints file1.obj, file2.obj, etc. (generated by tgif) into PostScript(TM) page description files โ€” and bestie, note this โ€” without opening windows or fonts โ€” and pipes them to lpr(1) if none of the -eps, -p, -epsi, -tiffepsi, -gif, -png, -jpeg, -ppm, -pbm, -xpm, -xbm, -html, -pdf, -ps, -f, -text, -netlist, or -svg options are specified. yes that's a whole list, count them if you want, they're all there. ๐Ÿ’€

This form of printing is tgif's way of exporting a tgif file to another format. and in this case, any other unrecognized command line options are sent straight to lpr(1). in this mode, tgif is compatible with the obsoleted prtgif. and a symbol file (see descriptions below ๐Ÿ‘€) can also be printed by specifying the .sym extension explicitly.

The command line argument file specifies a file or an Uniform Resource Locator (URL) of objects to be initially edited by tgif. Only HTTP or FTP URL's are supported. (For a more detailed description of URL and the World-Wide-Web, the reader is referred to [1].) ๐Ÿงš

Tgif is purely based on Xlib. It is tested under X11R6, and it requires a 3 button mouse. like, actually requires it, no cap, do not come to this party with a trackpad and expect everything to slay. ๐Ÿ™ˆ


okay that's the setup, the lore, the vibe check โœ… โ€” and bestie, the OPTIONS section is coming up next and it is long, so stay with me, we're not even close to done ๐Ÿ’…

โœจ OPTIONS โœจ

okay bestie, so here's the tea on all the command line options. there are literally two forms depending on how you're calling tgif, and we're gonna go through every single one. no skips, no cap. ๐Ÿ’…

First form (from the SYNOPSIS)

the command line args can be:

  • -fg โ€” sets the foreground color to whatever <color> you pass in. ๐ŸŽจ
  • -bg โ€” sets the background color to whatever <color> you pass in. ๐ŸŒˆ
  • -bd โ€” sets the border color to whatever <color> you pass in. โœจ
  • -rv โ€” starts tgif in reversed-video mode. ๐Ÿ‘€
  • -nv โ€” starts tgif in normal-video mode. ๐Ÿ˜Œ
  • -bw โ€” starts tgif in black and white mode. ๐Ÿ–ค๐Ÿค
  • -reqcolor โ€” same effect as setting the Tgif.PrintUsingRequestedColor X default to true (see the X DEFAULTS section below). ๐Ÿ’–
  • -cwo โ€” Canvas Window Only. only the canvas window (see TGIF SUBWINDOWS section below) will be displayed. this has the same effect as setting the Tgif.CanvasWindowOnly X default to true. ๐ŸชŸ
  • -cwo+sbwarp โ€” if -cwo+sbwarp is used, single-button-warp (clicking the left mouse button to warp) is used to activate teleporting (see TELEPORT/HYPERJUMP section below). ๐ŸŒ€
  • -hyper โ€” starts tgif in the hyperspace mode (see HYPERSPACE section below). ๐Ÿš€
  • -exec <file> โ€” after tgif starts, execute the internal command in <file> (see INTERNAL COMMANDS section below). if <file> is the string "-", tgif executes internal commands from the standard input. ๐Ÿ“œ
  • -dbim method โ€” use method as the input method for double-byte fonts (see SQUARE DOUBLE BYTE FONTS section below). this cannot be used in conjunction with -sbim. ๐Ÿˆฏ
  • -sbim method โ€” use method as the input method for single-byte fonts. this is useful if the X Keyboard Extension is used in inputing international characters (with dead keys). this cannot be used in conjunction with -dbim. ๐Ÿ”ค
  • -usexlib โ€” if tgif is compiled with -DUSE_XT_INITIALIZE, X Toolkit initialization routines will be used to setup tgif. using this command line option will force tgif to ignore the -DUSE_XT_INITIALIZE compiler option and use Xlib only. this is useful when the system resource file for tgif is not installed properly or messed up and needs to be bypassed. ๐Ÿ› ๏ธ
  • -a4 โ€” using this option has the same effect as setting the Tgif.PSA4PaperSize X default to true. ๐Ÿ“„
  • -letter โ€” using this option has the same effect as setting the Tgif.InitialPaperSize X default to "letter" ๐Ÿ“
  • -noshowpageineps โ€” using this option has the same effect as setting the Tgif.ShowPageInEPS X default to false. ๐Ÿ™ˆ
  • -quiet โ€” if this option is used, tgif will suppress standard messages. ๐Ÿคซ
  • -listdontreencode=<string> โ€” if this option is used, tgif will print out the list of PostScript font names specified in the -D_DONT_REENCODE compiler option used in compiling tgif. ๐Ÿ”

Second form (from the SYNOPSIS)

the command line args can be:

  • -version โ€” if this option is used, tgif will print out its version number and copyright on the command line. ๐Ÿ“ฆ
  • -justversion โ€” if this option is used, tgif will print out its version number and copyright on the command line and exits immediately. ๐Ÿƒโ€โ™€๏ธ
  • -nomode โ€” using this option has the same effect as setting the Tgif.NoModeWindow X default to true. ๐Ÿšซ
  • -eps (or -p) โ€” generates an Encapsulated PostScript(TM) file in file.eps; this file can be included in a LaTeX file through the \psfig, \epsf, or \psfile construct (see the LATEX FIGURE FORMATS section below). ๐Ÿ“„
  • -ps (or -f) โ€” generates a PostScript file in file.ps; this file can be printed to a PostScript printer with lpr(1). ๐Ÿ–จ๏ธ
  • -text โ€” generates a text file in file.txt; the text file contains all visible text and can be fed to a spell checker. ๐Ÿ“
  • -epsi โ€” generates an Encapsulated PostScript (EPS) file with a preview bitmap in file.eps. tgif aborts if a valid display is not accessible. ๐Ÿ˜ญ
  • -tiffepsi โ€” generates an EPS file with a DOS EPS Binary File Header and a trailing TIFF image in file.eps. see the GENERATING MICROSOFT WINDOWS EPSI FILES section for more details. tgif aborts if a valid display is not accessible. ๐Ÿ–ผ๏ธ
  • -gif โ€” generates a GIF file in file.gif. please see the notes for Tgif.GifToXpm in the X DEFAULTS section below. tgif aborts if a valid display is not accessible. ๐ŸŽž๏ธ
  • -png โ€” generates a PNG file in file.png. tgif aborts if a valid display is not accessible. ๐Ÿ–ผ๏ธ
  • -jpeg โ€” generates a JPEG file in file.jpg. tgif aborts if a valid display is not accessible. ๐Ÿ“ธ
  • -ppm โ€” generates a PPM file in file.ppm. tgif aborts if a valid display is not accessible. ๐ŸŽจ
  • -pbm โ€” generates a PBM file in file.pbm. tgif aborts if a valid display is not accessible. ๐Ÿ–ค
  • -xpm โ€” generates an X11 pixmap (XPM) file in file.xpm. tgif aborts if a valid display is not accessible. ๐Ÿ–Œ๏ธ
  • -xbm โ€” generates an X11 bitmap (XBM) file in file.xbm. tgif aborts if a valid display is not accessible. ๐Ÿ–๏ธ
  • -html โ€” generates a GIF file in file.gif and an HTML file in file.html. tgif aborts if a valid display is not accessible. ๐ŸŒ
  • -pdf โ€” generates a PDF file in file.pdf. please see the notes for Tgif.PsToPdf in the X DEFAULTS section below. ๐Ÿ“„
  • -netlist โ€” generates a text file in file.net and a text file in file.cmp. file.net contains netlist information stored in a table. the first line in it contains column names and each line in it is a port name (surrounded by double-quotes), followed by a comma and a <TAB> character, followed by a signal name (also surrounded by double-quotes). file.cmp contains information about components in the file. each component begins with its name followed by its type. the attributes of a component are printed afterwards (indented by <TAB> characters). ๐Ÿ”Œ
  • -svg โ€” generates an SVG file in file.svg. please see the notes for Tgif.EpsToTmpSvg and Tgif.TmpSvgToSvg in the X DEFAULTS section below. ๐ŸŽจ
  • -stdout โ€” sends the output to the standard output instead of generating the output in a file. ๐Ÿ–ฅ๏ธ
  • -raw โ€” causes the content of the files to be dumped to stdout. ๐Ÿ—‘๏ธ
  • -raw+h โ€” if -raw+h is used and if the file is an HTTP URL, the HTTP header is also dumped to stdout. ๐ŸŒ
  • -raw+headeronly โ€” if -raw+headeronly is used and if the file is an HTTP URL, the HTTP header is dumped to stdout. ๐Ÿ“‹
  • -dosepsfilter โ€” makes tgif act as a filter for getting rid of the DOS EPS Binary File Header and the trailing TIFF image in a DOS/Windows EPS file. ๐Ÿงน
  • -previewonly โ€” if -dosepsfilter is specified, -previewonly makes tgif act as a filter for extracting the preview bitmap from the trailing TIFF image in a DOS/Windows EPS file. ๐Ÿ‘€
  • -status โ€” if this option is used in conjunction with either -raw, -raw+h, or -raw+headeronly causes a status line to be displayed in stderr. ๐Ÿ“Š
  • -gray โ€” using this option has the same effect as setting the Tgif.UseGrayScale X default to true (see the X DEFAULTS section below). ๐ŸŒซ๏ธ
  • -color (or -reqcolor) โ€” to print in color, one can use either the -color or the -reqcolor option. the only difference between the two is that using -reqcolor has the same effect as setting the Tgif.PrintUsingRequestedColor X default to true (see the X DEFAULTS section below). ๐ŸŒˆ
  • -adobe (or -adobe=<number>/<number> -adobe=false) โ€” using this option has the same effect as specifying the Tgif.UsePsAdobeString X default. ๐Ÿ…ฐ๏ธ
  • -dontreencode=<string> โ€” using this option has the same effect as specifying the Tgif.DontReencode X default. ๐Ÿšซ
  • -producedby=<string> โ€” using this option has the same effect as specifying the Tgif.ProducedBy X default. ๐Ÿท๏ธ
  • -page โ€” causes a specified page (specified by <number>) to be printed. ๐Ÿ“„
  • -print_cmd โ€” using this option has the same effect as specifying the Tgif.PrintCommand X default. ๐Ÿ–จ๏ธ
  • -one_file_per_page โ€” causes each page to be printed into a separate file. ๐Ÿ“‘
  • -pepsc โ€” Preserve EPS Comment. this command line option became obsolete since EPS comments are always preserved starting from tgif-4.0.11. ๐Ÿ’€
  • -nolandpdfspd โ€” this commandline option became obsolete in tgif-4.1.42. it is interpreted as -nopdfspd. ๐Ÿ’€
  • -pdfspd (or -pdfspd=true -pdfspd=false) โ€” if -pdfspd or -pdfspd=true is specified, "setpagedevice" is generated in the interim PostScript file when exporting PDF files or in the final PostScript file when exporting PS files. if -pdfspd=false is specified, no "setpagedevice" will be generated in the interim PostScript file when exporting PDF files or in the final PostScript file when exporting PS files. this option overrides the Tgif.PdfSetPageDevice X default. ๐Ÿ“„
  • -pssetup โ€” using these options have the same effect as specifying the Tgif.AdditionalPSSetup X default. โš™๏ธ
  • -tgwb2 โ€” this commandline option enables the Tangram Whiteboard feature in tgif. it requires librmcast.so (Reliable IP-multicast library). the location of the rmcast library can be specified by the optional commandline argument -rmcastlibdir. alternatively, the full path to the rmcast library can be specified by using the optional commandline argument -rmcastlibpath. please note that the rmcast library has only been extensively tested on Linux machines. ๐Ÿง
  • -j2p6_cmd โ€” using this option has the same effect as specifying the Tgif.JpegToPpm6 X default. ๐Ÿ–ผ๏ธ
  • -dontcondense โ€” using this option has the same effect as setting the Tgif.DontCondensePSFile X default to true. ๐Ÿšซ
  • -condensed โ€” using this option has the same effect as setting the Tgif.DontCondensePSFile X default to false. โœ…
  • -bop_hook and -eop_hook โ€” using these options have the same effect as specifying the Tgif.PSBopHook and Tgif.PSEpsHook X defaults. ๐Ÿช
  • -tmp_file_mode โ€” using this option have the same effect as specifying the Tgif.TmpFileMode X defaults. ๐Ÿ—‚๏ธ
  • -patterndir โ€” using this option have the same effect as specifying the Tgif.CustomPatternDir X defaults. ๐ŸŽจ
  • -o โ€” if this option is not specified, the output file (eps, ps, etc.) goes into the same directory as the input file. if -o<dir> is specified, the output file goes into the directory specified by <dir>. ๐Ÿ“
  • -merge file1 file2 ... โ€” using this option merges file1.obj, file2.obj, etc. into a multipage file. ๐Ÿ“š

๐ŸŒˆ BASIC FUNCTIONALITIES ๐ŸŒˆ

okay bestie, deep breath, this is the part where we find out what tgif can actually draw ๐Ÿ’–

The primitive objects tgif supports are: rectangles, ovals, rounded-corner rectangles, arcs, polylines, polygons, open-splines, closed-splines, text, X11 bitmaps, some specific forms of X11 pixmaps, and Encapsulated PostScript. quick side note though: the splines tgif draws are not Bezier curves, just so you're not out here assuming. ๐Ÿ™ˆ

Objects can be grouped together to form a grouped object. And a primitive or a grouped object can be turned into an icon object or a symbol object through user commands. slay.

Tgif objects live in two types of files:

  • a file with a .obj extension โ€” aka an object file โ€” is a file of objects
  • a file with a .sym extension โ€” aka a symbol file โ€” specifies a "building-block" object

There's a whole teleport mechanism so you can travel (or hyperjump โœจ) among the .obj files. And a building-block object is made of two parts: the representation part and the definition part (which can totally be empty).

Tgif does the bottom-up construction of hierarchical drawings thing by letting you "instantiate" a building-block object inside a drawing. It also does the top-down thing by letting you make any object into the representation of an un-specified subsystem. Both types of files get stored as Prolog facts. And yes โ€” you can literally write Prolog code to interpret the drawings! ๐ŸŽ€ (but producing that code is on you, bestie. see the PROLOG/C TESTDRIVE section for the deets.) Prolog engines are called drivers in the sections that follow. (other kinds of drivers are allowed too, like ones written in C ๐Ÿ’…)

Text based attributes can be attached to any non-text object. Attributes specified in the representation part of a building-block object are non-detachable once that object gets instantiated. See the ATTRIBUTES section for the full tea.


๐Ÿ–จ๏ธ output formats, the whole menu ๐Ÿ–จ๏ธ

Tgif can generate output in a few different formats. By default it's PostScript (and yes, color PostScript is supported), generated into a file named /tmp/Tgifa* (produced by mktemp() calls) where * is a number. That file gets piped to lpr(1). This happens when the laser-printer icon is showing in the Choice Window (peep the TGIF SUBWINDOWS section for how tgif windows are named).

  • That output can be redirected to a file with a .ps extension โ€” this happens when the PS icon is displayed in the Choice Window.
  • When the PDF icon is displayed in the Choice Window, the output goes into a file with a .pdf extension. By default, tgif calls ps2pdf(1) from the ghostscript(1) package to convert a PS file to a PDF file.
  • When the LaTeX (or EPSI) icon is displayed in the Choice Window, the output goes into a file with a .eps extension. That file is in the Encapsulated PostScript (or Encapsulated PostScript Interchange) format, and it can be included in a LaTeX document with the \psfig or the \epsf construct โ€” more on that later. The only difference between the EPS and EPSI formats is that an EPSI file contains a preview bitmap. but heads up: generating that preview bitmap takes time. So if the EPS/EPSI file is going into some tool that doesn't know how to use a preview bitmap, you can save time by just not using the EPSI format. ๐Ÿ’…
  • When the T icon is displayed in the Choice Window, the output goes into a file with a .txt extension. It's a text file containing all visible text, and you can feed it to a spell checker. iconic.
  • When the x11bm (X11 bitmap) icon is displayed in the Choice Window and color output is not selected, tgif generates output with the .xbm extension, in the X11 bitmap format. BUT if the x11bm icon is displayed and color output is selected (through the ^#k keyboard command โ€” ^ means the <Control> key and # means the <Meta> or <Alt> key), then tgif generates output with the .xpm extension, in the X11 pixmap format (the version of this XPM format depends on the settings of the Tgif.XPmOutputVersion X default).
  • When the GIF icon is displayed in the Choice Window, the output goes into a file with a .gif extension. By default, tgif calls xpmtoppm and ppmtogif from the netpbm(1) package to convert an XPM file to a GIF file.

๐Ÿ“ฅ what you can import ๐Ÿ“ฅ

X11 bitmap files, certain forms of X11 pixmap files (like the one tgif itself generates โ€” see the section on X11 PIXMAP for the details), GIF files, and Encapsulated PostScript (EPS) files can all be imported into tgif and represented as tgif primitive objects. ๐Ÿฆ‹

Files in other raster formats (e.g, JPEG, TIFF, etc.) can also be imported into tgif if external tools can be used to convert them into X11 pixmap files. See the IMPORT RASTER GRAPHICS section for the how-to.


๐Ÿ“„ paper, because yes it matters ๐Ÿ“„

Tgif drawings are supposed to be printed on letter size paper (8.5in by 11in). Both landscape and portrait page styles are supported. Reduction (or magnification) can be controlled by the #% keyboard command to set the reduction/magnification.

if the compiler flag -DA4PAPER is defined (in Imakefile or Makefile.noimake), then the output is supposed to be printed on A4 papers (which have approximate dimensions of 8.25in by 11.7in). ๐Ÿ“

๐ŸŽจ GRAPHICAL OBJECTS ๐ŸŽจ

An object in an object (.obj) file can be a primitive object, a grouped object, or an icon object.

A symbol (.sym) file can have any number of objects that are allowed in an object file, plus exactly one symbol object. (remember, a symbol file specifies a building-block object ๐Ÿ’–) The symbol object in a symbol file is the representation part of the building-block object, and the rest of the symbol file is the definition part of the building-block object. The symbol object gets highlighted with a dashed outline so you can tell it apart from the rest of the objects. And when a building-block object is instantiated, the symbol part of the file gets copied into the graphics editor and becomes the icon for that building-block object. โœจ

All objects in tgif can be moved, duplicated, deleted, rotated, flipped, and sheared. However โ€” in the non-stretchable text mode, text objects can not be stretched. And for a text object, if it has not been stretched, rotated, or sheared, flipping it horizontally will cause the text justification to change, and flipping it vertically has no effect. ๐Ÿซ 


๐Ÿ”ข the numbers, because we love specifics ๐Ÿ”ข

Tgif supports:

  • 32 fill patterns
  • 32 pen patterns
  • 7 default line widths
  • 4 line styles (plain, head arrow, tail arrow, double arrows) for polylines and open-splines
  • 9 dash patterns
  • 3 types of text justifications
  • 4 text styles (roman, italic, bold, bold-italic)
  • 11 default text sizes (8, 10, 12, 14, 18, and 24 for the 75dpi fonts and 11, 14, 17, 20, 25, and 34 for the 100dpi fonts)
  • 5 default fonts (Times, Courier, Helvetica, New-Century-Schoolbook, Symbol)
  • 11 default colors (magenta, red, green, blue, yellow, pink, cyan, cadet-blue, white, black, dark-slate-gray)

โž• adding more of everything โž•

  • Additional line widths can be added through the use of Tgif.MaxLineWidths, Tgif.LineWidth#, Tgif.ArrowWidth#, and Tgif.ArrowHeight# X defaults.
  • Additional text sizes can be added through the use of the Tgif.FontSizes X default.
  • Additional fonts can be added through the use of the Tgif.AdditionalFonts X default. And if the default fonts aren't available, their replacement fonts can be specified by Tgif.HasAlternateDefaultFonts and related X defaults.
  • Additional colors can be added through the use of Tgif.MaxColors and Tgif.Color# X defaults. You can also pick AddColor() or ChooseColor() from the Properties Menu to add a color. ๐Ÿ’…
  • Alternate startup colors can be selected through the use of the Tgif.ColorFromXPixmap, Tgif.UseStdPalette8, Tgif.UseStdPalette27, Tgif.UseStdPalette64, Tgif.UseStdPalette216, Tgif.UseMobileWebSafePalette, Tgif.UseOpenOfficeGalaxyPalette, Tgif.UseOpenOfficeGooglePalette, and Tgif.AdditionalColors X defaults.

โ†ฉ๏ธ undo, redo, the whole saga โ†ฉ๏ธ

Most commands in tgif can either be activated by a popup menu or by typing an appropriate non-alphanumeric key. All operations that change any object can be undone and then redone. Commands such as zoom, scroll, change fonts while no text objects are selected, etc. are not undoable. ๐Ÿ˜ญ

The undo/redo history buffer size can be set using the Tgif.HistoryDepth X default.


๐ŸชŸ TGIF SUBWINDOWS ๐ŸชŸ

okay bestie, this is the window tour. let's go window by window ๐Ÿ’–

Top Window

Displays the current domain and the name of the file tgif is looking at. Mouse clicks and key presses have no effect here. it's just vibes ๐Ÿ‘‘

This window sits right under the Top Window. Pull-down menus can be activated from it with any mouse buttons. Key presses have no effect.

  • If HideMenubar() is selected from the Layout Menu, this window becomes invisible.
  • If ShowMenubar() is selected from the Layout Menu (which can be activated from the Canvas Window below), this window becomes visible.

The View, Text, and Graphics pull-down menus are cascading menus and can not be pinned (see the Popup Menus subsection below for the description).

Message Window

This one is right under the Menubar Window and to the right. It displays tgif messages.

  • Clicking the left mouse button in this window scrolls the messages towards the bottom.
  • Clicking the right mouse button scrolls towards the top.
  • Clicking or dragging the middle mouse button scrolls to the location in the message history depending on where the mouse is clicked.
  • If the <Shift> (or <Control>) key is held down when clicking the left/right mouse button, it scrolls right/left. ๐ŸŒ€

Panel (Choice) Window

This is the window to the left of the Message Window, and it contains a whole collection of icons (not to be confused with the tgif icon objects, bestie, different thing) reflecting the current state of tgif.

In top/bottom, left/right order, it displays:

  • the current drawing mode
  • the page style (portrait or landscape)
  • edit (see below)
  • print/export mode
  • zoom factor
  • move and stretch mode (constrained or unconstrained)
  • radius for rounded-corner rectangles
  • text rotation
  • page number or row/column
  • page layout mode (stacked or tiled)
  • horizontal alignment (L C R S -)
  • vertical alignment (T M B S -)
  • font
  • text size
  • vertical spacing between lines of text within the same text object
  • text justification
  • shape (see below)
  • stretchable or non-stretchable text mode
  • dash pattern
  • line style
  • polyline, spline, or interpolated spline
  • line width
  • fill pattern
  • pen pattern
  • color
  • and special (see below)

Key presses have no effect in this window. ๐ŸŒธ

ok so the icons in the Choice Window aren't just there to look cute โ€” they show you the current state of tgif and they let you change it. Every icon is wired up to a particular state variable of tgif, bestie. Here's the whole vibe:

  • left click on an icon โ†’ cycles that state variable forward โœจ
  • right click on an icon โ†’ cycles it backwards ๐Ÿ™ˆ
  • drag the middle mouse button on an icon โ†’ usually pops up a menu that matches an entry in the Main Menu for the Canvas Window down below ๐Ÿซถ

And real quick, iykyk: the edit, shape, and special icons up there are dummy icons โ€” they literally just exist so you can reach the edit, shape, and special menus from the Choice Window. They do not respond to left and right mouse clicks, periodt. ๐Ÿ’…

The middle-mouse drag hits different for the zoom, radius, and vertical spacing icons though:

  • drag the mouse left or up โ†’ increases zoom, or decreases the radius or vertical spacing โฌ†๏ธ
  • drag the mouse right or down โ†’ the opposite effect โฌ‡๏ธ

Also, if there are objects selected in the canvas window, then whatever you do with the mouse makes those selected objects flip to the newly selected mode. but heads up โ€” in that case the current choice won't change if the middle mouse button is used (unless the Tgif.StickyMenuSelection X default is set to true). noted. ๐ŸŽ€


The settings of the horizontal and vertical alignments are the main character of a whole lot of behavior. They determine:

  • how objects (or vertices) align with each other when the ^l keyboard command is issued
  • how each individual object (or vertex) aligns with the grids when the ^t keyboard command is issued
  • how objects or vertices distribute spatially with respect to each other when the #l keyboard command is issued
  • how each icon replaces the old icon when the ^#u keyboard command is issued

The horizontal alignments are left (L), center (C), right (R), space (S), and ignore (-). The vertical alignments are top (T), middle (M), bottom (B), space (S), and ignore (-).

In aligning operations, the space (S) and the ignore (-) settings have the same effect. The space settings are the ones you use to distribute objects so that the gaps between any two neighboring objects are equal ๐Ÿซถ. In vertex mode, any non-ignore setting will cause the selected vertices to be spaced out evenly. And ngl the best way to actually understand them is to just try them out. fr fr.

The text vertical spacing determines the vertical distance to advance when a carriage return is pressed during text editing. And okay watch out: if the user tries to set the value too negative, such that the next line lands exactly at the same position as the current line, that setting will not be allowed ๐Ÿ˜ญ (this distance depends on the current font and font size, so it's not a fixed thing).


๐ŸŽจ Canvas Window ๐ŸŽจ

This is the drawing area, the whole stage. โœจ The effects of your mouse actions are determined by the current drawing mode. And a lil lore drop: before tgif-4.x, dragging the right mouse button would generate the Mode Menu. That's disabled by default in tgif-4.x, but you can turn it back on with the Tgif.Btn3PopupModeMenu X default. ๐Ÿฆ‹

The drawing modes are (in order, exactly as they appear in the Mode Menu):

  1. select
  2. text
  3. rectangle
  4. corner oval
  5. center oval
  6. edge circle
  7. polyline (open-spline)
  8. polygon (closed-spline)
  9. arc (center first)
  10. arc (endpoints first)
  11. rounded-corner rectangle
  12. freehand polyline (open-spline)
  13. select vertices
  14. rotate/shear

When you're drawing a rectangle, an oval, or a rounded-corner rectangle, if the <Shift> key is held down, you get a square, a circle, or a rounded-corner square instead ๐Ÿ‘‘. Dragging the middle mouse button generates the Main Menu.


In select mode, the left mouse button selects, moves, stretches, and reshapes objects (and a double-click will de-select all selected objects in vertex mode). When an object is selected, it gets highlighted by little squares (we call them handles here) at the corners/vertices โ€” and you can customize the sizes of the handles using the Tgif.HandleSize X default ๐ŸŽ€. Dragging one of the handles stretches/reshapes the selected object.

But listen โ€” if you want to move a selected object, do not drag the handles. Drag other parts of the object instead. For example:

  • if the object is a hollow rectangle (the fill is NONE and the pen is not NONE), then to select the rectangle you click on the outline of the rectangle with the left mouse button, and to move it you drag the outline of the rectangle with the left mouse button
  • if the object is a filled rectangle (fill is not NONE), you can click inside the rectangle to select it, and drag anywhere inside the rectangle to move it ๐Ÿซถ

Holding down the <Shift> key and clicking the left mouse on an object that is not currently selected will add that object to the list of already selected objects. The same action on an object that's already selected will de-select it. When stretching objects (not reshaping poly-type objects), holding down the <Shift> key after stretching is initiated activates proportional stretching (basically, a scale operation is being performed). And in non-stretchable text mode, text objects can not be stretched or scaled. ๐Ÿ’…

Double-clicking, or clicking the middle mouse button while the <Shift> key is held down, activates the teleport (or travel), the launch, or the execute internal command mechanism. See the sections on TELEPORT/HYPERJUMP, LAUNCH APPLICATIONS, and INTERNAL COMMANDS for the details โœจ. Precedence goes: teleporting > launching > executing an internal command. In the text drawing mode, dragging the middle mouse button while the <Cntrl> key is held down inside the edit text area will move the edit text area.

The arrow keys can also be used to move selected objects. but if no objects are selected, using the arrow keys will scroll the drawing area by a small amount โ€” and using the arrow keys while the <Control> key is held down will scroll a screen full. ๐Ÿ‘‘


In select vertices mode, the left mouse button selects and moves vertices. Only the top-level polyline/open-spline and polygon/closed-spline objects which are selected when the vertex mode is activated are eligible for vertex operations. In this mode, all eligible objects have their vertices highlighted with squares. When a vertex is selected (using a similar mechanism as selecting objects described above), it's doubly highlighted with a + sign โœจ.

The operations available to these doubly highlighted vertices are:

  • move
  • delete
  • align (with each other)
  • distribute (space them equally)
  • align to grid

The arrow keys can also be used to move selected vertices. ๐Ÿฆ‹


Objects can be locked (through the #< keyboard command). Locked objects are shown with gray handles, and they can not be moved, stretched, flipped, rotated, or sheared. When objects are grouped, the resulting grouped object will also be locked if any one of its constituents is locked. Locked objects can still have their properties, such as color, font, pen, etc., changed โ€” and they can also be deleted. ๐Ÿ’œ


Now, if the current move/stretch mode is of the constrained type (activated and deactivated by the #@ keyboard command), top-level polylines get this whole special behavior:

  • In a move operation, if both endpoints of a polyline lie inside the objects being moved, then the whole polyline is moved. Otherwise, if only one endpoint falls inside the objects being moved, then that endpoint is moved. The vertex that is the neighbor of the moved endpoint may also be moved either horizontally or vertically. If the last line segment is horizontal or vertical, then the neighbor vertex may be moved so that the direction of the last line segment is maintained.
  • In a stretch (not reshape) operation, if an endpoint of a polyline lies inside the objects being moved, that endpoint will be moved. The vertex that is the neighbor of the moved endpoint will also be moved in the same manner as described above.

When the drawing mode is set to text (a vertical-bar cursor is shown), clicking the left mouse button causes selected text to go into edit mode. Dragging the left mouse button, or clicking the left mouse button while the <Shift> key is held down, highlights substrings of the text. Double-clicking causes a word to be selected. In edit mode, key presses are treated as text strings being inputed, and arrow keys are used to move the current input position. ๐ŸŽ€

If a key press is preceded by an <ESC> key, then the character's bit 7 is turned on. This allows non-ASCII (international) characters to be entered โœจ. One can use xfd(1) to see what the corresponding international character is for an ASCII character. For the Symbol font, symbols such as the integral, partial derivative, and copyright symbols can all be found in this range. There are some characters that are supported by X11 but not by PostScript โ€” and those characters are not accepted by tgif.

If the text being edited is an attribute of an object, <Meta><Tab> will move the cursor to the next visible attribute and <Shift><Tab> will move the cursor to the previous visible attribute. ๐Ÿซถ


If the drawing mode is set to draw polygons (not closed-splines) and if the <Shift> key is held down, the rubber-banded polygon will be self-closing. ๐ŸŒธ

The freehand drawing mode can be used to draw polylines and open splines. All intermediate points are specified by moving the mouse (as opposed to clicking the mouse buttons as in the polyline mode). The second endpoint is specified by releasing the mouse button. ๐Ÿ’…

And in all drawing modes (other than the text mode), pressing the <ESC> key cancels the drawing (creation) of the current object. ๐Ÿ˜ญ

okay bestie, we're still deep in the subwindow tour and it just keeps going ๐Ÿ’… first up, the mouse-button tea:

  • The middle mouse button? Always pops the main tgif popup menu. No cap, every time.
  • Hold down <Shift> and click the right mouse button and boom, the drawing mode flips to select.
  • Key presses with <Control> or <Meta> held down (we call these non-alphanumeric key presses, since they can also generate control characters) get treated as commands, and all their bindings are summarised in the next section.
  • You can also define your own single key commands to emulate the functions of those non-alphanumeric key commands. The SHORTCUTS section spills all the details.

๐ŸŒธ Scrollbars ๐ŸŒธ

Click the left mouse button in the vertical or horizontal scrollbar and the canvas window scrolls down/right by a small distance. Click the right mouse button and it does the reverse. (The scrollbars in the popup windows for selecting file names and domain names behave similarly, iykyk.) Hold down <Shift> while clicking and it scrolls a window full. Click or drag the middle button and the page scrolls to the location that corresponds to the gray area in the scrollbars. ๐Ÿฆ‹

Fr fr, tgif insists that the left-top corner of the Canvas Window sits at a distance that is a nonnegative multiple of some internal units from the left-top corner of the actual page. It's giving โœจparticularโœจ.

๐Ÿ“ Rulers ๐Ÿ“

They track the mouse location, periodt. Mouse clicks and key presses have no effect on them.

  • When the page reduction/magnification is set at 100%, the markings in the rulers correspond to centimeters when the metric grid system is used, and they correspond to inches when the English grid system is used. ๐Ÿ’–
  • When the page reduction/magnification is not set at 100%, the markings do not correspond to the above mentioned units any more. This is considered as a known bug, so don't come for the rulers, they're just out here doing their best. ๐Ÿ˜ญ

๐Ÿš€ Interrupt/Hyperspace Window ๐Ÿš€

This window is right below the Message Window and to the left of the horizontal ruler. Two icons live here and honestly they have main character energy:

  • When the Tgif.IntrCheckInterval X default has a positive value, an interrupt icon is visible when the Canvas Window is being redrawn. Click on this window while the interrupt icon is showing and tgif aborts the repainting of the objects. ๐Ÿ‘‘
    • If you do this while a file is being opened (either through Open() or Push()), the drawing of objects is stopped, but the reading of the file continues โ€” reading of the file is not aborted. Not me hitting the brakes on the drawing while the reading just keeps going ๐Ÿ’€
  • If tgif is currently in the hyperspace mode (peep the HYPERSPACE section below for the deets), a space ship icon ๐Ÿš€ is displayed when the interrupt icon is not being displayed. Clicking any button in this window switches tgif in and out of the hyperspace mode. Iconic.

๐ŸŽ€ Page Control Window ๐ŸŽ€

The Page Control Window sits to the left of the horizontal scrollbar. Its whole vibe depends on the page mode:

  • If the current page mode is set to the tiled page mode, this window is empty. Nothing to see here bestie, it's giving minimalist.
  • If the current page mode is set to the stacked page mode, each page gets a tab in the tabs subwindow of this window.
    • Clicking the left mouse button on a tab goes to the corresponding page.
    • Clicking the middle mouse button brings up the Page Menu.

When there are too many pages in a drawing and you can't see all the tabs, use the icons to the left side of the Page Control Window to scroll the tabs subwindow:

  • Clicking the first icon scrolls the tabs subwindow such that the first tab is visible.
  • Clicking the 4th icon scrolls the tabs subwindow such that the last tab is visible.
  • Clicking the 2nd icon scrolls the tabs subwindow towards the first tab by one tab.
  • Clicking the 3rd icon scrolls the tabs subwindow towards the last tab by one tab.

four little icons, so much scrolling power, we love to see it โญ


๐Ÿ’œ Status Window ๐Ÿ’œ

This window is below the horizontal scrollbar, and it's the little narrator of the operation:

  • It shows what action will be taken if a mouse button is depressed.
  • When a menu is pulled down or popped up, this window shows what action will be taken if a menu item is selected.
  • It also displays miscellaneous status information. ๐ŸŒˆ
  • Mouse clicks and key presses have no effect on it.
  • Select HideStatus() from the Layout Menu and this window becomes invisible. Select ShowStatus() from the Layout Menu and it becomes visible. ๐Ÿซถ

By default, when this window is displaying mouse button status, a right-handed mouse is assumed. Setting the Tgif.ReverseMouseStatusButtons X default to true will reverse the status (as if a left-handed mouse is used). Inclusive king behavior ngl ๐Ÿ‘‘


When a menu is popped up by a mouse drag, the menu can be pinned if it is dragged far enough horizontally. How far is far enough? Determined by the setting of the Tgif.MainMenuPinDistance X default. ๐Ÿ’ซ

  • Clicking the right mouse button in a pinned menu will cause it to disappear. bye bestie ๐Ÿ‘‹
  • Dragging the left mouse button in a pinned menu will reposition the menu โ€” except when the Tgif.TitledPinnedMenu X default is set to true, in which case the left mouse button performs the same function as the middle mouse button. Sneaky switch-up, iykyk.
  • Clicking the middle mouse button in it will activate the item right below the mouse. So precise, so demure. ๐Ÿ’…

๐Ÿ”‘ NON-ALPHANUMERIC KEY BINDINGS ๐Ÿ’…

Okay bestie, so most of the stuff you can do in tgif has a key combo. Some operations are only reachable through popup menus or shortcut keys, but the ones below? All yours via a keystroke with <Control> and/or <Meta> held down. In this whole description, ^ means the <Control> key and # means the <Meta> key. Periodt. ๐ŸŽ€

The keys.obj file, distributed with tgif, also summarizes the same info โ€” but it's organized differently. You can view it with tgif, and if it's installed properly, it lives in the same directory as the tgificon.obj file mentioned in the FILES section of this doc. ๐Ÿฆ‹

โœจ Just <Control> things โœจ

  • ^a โ€” select all ๐ŸŒˆ
  • ^b โ€” send selected objects to the back
  • ^c โ€” copy selected objects into the cut buffer
  • ^d โ€” duplicate selected objects
  • ^e โ€” save/restore drawing mode
  • ^f โ€” send selected objects to the front
  • ^g โ€” group selected objects (heads up: the grouped object gets brought to the front) ๐Ÿ‘‘
  • ^i โ€” instantiate a building-block object
  • ^k โ€” pop back to (or return to) a higher level and close the symbol file (it's the reverse of ^v)
  • ^l โ€” align selected objects according to the current alignment settings
  • ^n โ€” open a new un-named object file
  • ^o โ€” open an object file to edit
  • ^p โ€” print the current page (or export in XBM, XPM, GIF, HTML, PDF, EPS, or PS formats)
  • ^q โ€” quit tgif
  • ^r โ€” redraw the page
  • ^s โ€” save the current object/symbol file
  • ^t โ€” align selected objects to the grid according to the current alignment
  • ^u โ€” ungroup selected objects
  • ^v โ€” paste from the cut buffer
  • ^w โ€” change the drawing mode to text
  • ^x โ€” delete all selected objects
  • ^y โ€” change domain
  • ^z โ€” escape to driver
  • ^, โ€” scroll left
  • ^. โ€” scroll right
  • ^- โ€” print the current page with a specified command

๐ŸŒธ The <Meta> key era ๐ŸŒธ

  • #a โ€” attach selected text objects to a selected non-text object as attributes
  • #b โ€” escape to driver
  • #c โ€” rotate selected objects counter-clockwise
  • #d โ€” decrement the grid size
  • #e โ€” send a token on a selected polyline
  • #f โ€” flash a selected polyline
  • #g โ€” show/un-show grid points
  • #h โ€” flip the selected objects horizontally
  • #i โ€” increment the grid size
  • #j โ€” hide the attribute names of the selected objects
  • #k โ€” change the drawing mode to select
  • #l โ€” distribute selected objects according to the current alignment
  • #m โ€” move/justify an attribute of a selected object
  • #n โ€” show all the attribute names of the selected objects
  • #o โ€” zoom out
  • #p โ€” import a .obj or a .sym file into the current file
  • #q โ€” change the drawing mode to polyline/open-spline
  • #r โ€” change the drawing mode to rectangle
  • #s โ€” escape to driver
  • #t โ€” detach all the attributes of the selected objects
  • #u โ€” undo
  • #v โ€” flip the selected objects vertically
  • #w โ€” rotate the selected objects clockwise
  • #x โ€” escape to driver
  • #y โ€” escape to driver
  • #z โ€” zoom in
  • #9 โ€” create a user-specified arc (12 o'clock position is 0 degree)
  • #0 โ€” update the selected objects according to current settings
  • #, โ€” scroll up
  • #. โ€” scroll down
  • #- โ€” show all the attributes of the selected objects
  • #[ โ€” align the left sides of objects
  • #= โ€” align the horizontal centers of objects
  • #] โ€” align the right sides of objects
  • #{ โ€” align the top sides of objects
  • #+ โ€” align the vertical centers of objects
  • #} โ€” align the bottom sides of objects
  • #" โ€” make the selected polygon regular (fit the original bounding box)
  • #% โ€” set the percent print reduction (if < 100%) or magnification (if > 100%)
  • #: โ€” go to default zoom
  • `#`` โ€” zoom out all the way so that the whole page is visible
  • #~ โ€” save selected objects in a new file
  • #; โ€” cut and/or magnify a selected bitmap/pixmap object
  • #_ โ€” abut selected objects horizontally
  • #| โ€” abut selected objects vertically
  • ## โ€” break up text objects into single character text objects
  • #^ โ€” scroll to the origin set by SaveOrigin()
  • #@ โ€” toggle between constrained and unconstrained move (stretch) modes
  • #$ โ€” change the drawing mode to select vertices
  • #& โ€” align selected objects to the paper according to the current alignment
  • #* โ€” redo
  • #( โ€” import an Encapsulated PostScript file
  • #) โ€” scale selected objects by specifying X and Y scaling factors
  • #< โ€” lock the selected objects (can't be moved, stretched, flipped, or rotated) ๐Ÿ”’
  • #> โ€” unlock the selected objects ๐Ÿ”“

๐Ÿ’œ <Control> + <Meta> combo meal ๐Ÿ’œ

  • ^#a โ€” add points to the selected poly or spline
  • ^#b โ€” change the text style to bold
  • ^#c โ€” change to center justified text
  • ^#d โ€” delete points from the selected poly or spline
  • ^#e โ€” change the drawing mode to rounded-corner rectangles
  • ^#f โ€” reverse-video the selected bitmap objects
  • ^#g โ€” toggle snapping to the grid points
  • ^#h โ€” hide all attributes of the selected objects
  • ^#i โ€” make the selected object iconic
  • ^#j โ€” make the selected icon object a grouped object
  • ^#k โ€” select color or black-and-white output
  • ^#l โ€” change to left justified text
  • ^#m โ€” make the selected object symbolic
  • ^#n โ€” make the selected symbol object a grouped object
  • ^#o โ€” change the text style to roman
  • ^#p โ€” change the text style to bold-italic
  • ^#q โ€” change the drawing mode to polygon/closed-spline
  • ^#r โ€” change to right justified text
  • ^#s โ€” save the file under a new name
  • ^#t โ€” change the text style to italic
  • ^#u โ€” update iconic representations of selected objects
  • ^#v โ€” change the drawing mode to oval
  • ^#w โ€” toggle between poly and spline
  • ^#x โ€” cycle among the various output file formats
  • ^#y โ€” push into (or edit) the definition part of a building-block (icon) object
  • ^#z โ€” change the drawing mode to arcs
  • ^#. โ€” import an X11 bitmap file
  • ^#, โ€” import an X11 pixmap file
  • ^#- โ€” toggle between English and Metric grid systems
  • ^#= โ€” repeat the last Find command

โšก SHORTCUTS โšก

So you can make your own single character shortcut keys that emulate the whole non-alphanumeric key press situation and activate commands. It's all done through the Tgif.ShortCuts X default. ๐Ÿซถ

Careful bestie: these shortcut keys are only active when the drawing mode is not set to the text mode. No cap.

Tgif.ShortCuts is a list of items, each one specifying the bindings between a key (and yes, it may be case sensitive) and a command. Items get separated by blanks, and every item is interpreted like this: it has two parts, KEY and COMMAND, glued together with a ':' character.

The format of the KEY part is one of :<Key>x, !<Key>x, or <Key>x โ€” and yes, the character x there is just an example; also, the substring <Key> has to be spelled exactly the way it appears right there. The first 2 formats are equivalent and they specify the lower case x; the 3rd format specifies both the characters x and X.

The COMMAND part is a string that matches strings in tgif's popup menus with space characters removed (exceptions noted below, don't worry ๐ŸŒธ).

Example time, because this is giving "explain it to me like I'm five" energy and honestly, valid. In the Edit menu, two of the entries are:

"Delete   ^x"
"SelectAll     ^a"

which means <Control>x activates the Delete() command, and <Control>a activates the SelectAll() command. So both Delete() and SelectAll() are valid names for the COMMAND part of a shortcut specification. ๐ŸŽ€

To complete the example, this line binds the lower case x to Delete() and a or A to SelectAll():

Tgif.ShortCuts:     !<Key>x:Delete() \n\
               <Key>a:SelectAll()

Want more examples? Go peek at the sample X defaults file, tgif.Xdefaults, included in the tgif distribution. ๐Ÿ’–


๐ŸŒˆ The exception list (iykyk) ๐ŸŒˆ

Here's the list of exceptions where the COMMAND does not match a command name in a menu entry. Left entry is a proper COMMAND name, and the right side is a list of strings shown in popup menus that the COMMAND would correspond to:

  • CyclePrintFormat() โ€” Printer, LaTeXFig, RawPSFile, XBitmap, TextFile, EPSI, GIF/ISMAP, TiffEPSI, NetList
  • ToggleBW/ColorPS() โ€” BlkWhtPS, ColorPS
  • ToggleGridSystem() โ€” EnglishGrid, MetricGrid
  • ToggleMapShown() โ€” ShowBit/Pixmap, HideBit/Pixmap
  • ToggleUseGrayScale() โ€” UseGrayScale, NoGrayScale
  • ToggleMoveMode() โ€” ConstMove, UnConstMove
  • ToggleShowMeasurement() โ€” ShowMeasurement, HideMeasurement
  • ToggleLineType() โ€” (advances between different curved shapes)
  • ScrollPageUp() โ€” (scroll up a window full)
  • ScrollPageDown() โ€” (scroll down a window full)
  • ScrollPageLeft() โ€” (scroll left a window full)
  • ScrollPageRight() โ€” (scroll right a window full)
  • FreeHandMode() โ€” (change the drawing mode to freehand poly/open-spline)
  • CenterAnEndPoint() โ€” (move an endpoint of a polyline object to the center of another object)
  • ToggleNamedAttrShown(<x>=) โ€” (toggle name shown for the attribute <x>)
  • ToggleSmoothHinge() โ€” (convert smooth to hinge and hinge to smooth points)
  • ToggleShowMenubar() โ€” ShowMenubar, HideMenubar
  • ToggleShowStatus() โ€” ShowStatus, HideStatus
  • ToggleShowMode() โ€” ShowMode, HideMode
  • ToggleOneMotionSelMove() โ€” OneMotionSelMove, ClickSelClickMove
  • ToggleHyperSpace() โ€” GoHyperSpace, LeaveHyperSpace
  • ImportOtherFileType(<x>) โ€” (import using a filter named <x>)
  • BrowseOtherType(<x>) โ€” (browse using a filter named <x>)
  • PrintSelectedObjs() โ€” (print selected objects)

And on top of that whole list, these are also valid COMMAND names (they have the obvious meaning, bestie): ScrollLeft(), ScrollRight(), ScrollUp(), ScrollDown(), SelectMode(), DrawText(), DrawBox(), DrawOval(), DrawPoly(), DrawPolygon(), DrawRCBox(), DrawArc(), and SelectVertexMode(). โœจ

okay bestie, buckle up, this is the part where we talk about how tgif deals with the fact that your screen is, like, tragically limited ๐Ÿ’…


๐ŸŒˆ COLORS AND COLORMAPS ๐ŸŒˆ

So in most X environments, only 256 colors can be displayed at once. Only. 256. In these environments, if one app needs 128 colors and another app needs a totally different 129 colors, bestie, they literally cannot both be displayed at once with all the colors they want. It's giving cramped. ๐Ÿ˜ญ

X solves this by letting applications use their own colormaps (known as private colormaps). Each private colormap can have at most 256 colors. There's also a shared colormap available for applications that don't wanna go private. The main problem with private colormaps? You get the the well-known colormap flashing phenomenon when you switch in and out of apps that use private colormaps. Iconic behavior, honestly, but not in a good way. ๐Ÿ’€

Tgif uses the shared colormap initially. When it needs more color than what's available in the shared colormap, it will use a private colormap automatically. And here's the tea โ€” when tgif no longer needs the extra colors, it does not automatically revert to using the shared colormap, because it needs to be able to undo operations that use the extra colors. Undo history is sacred, periodt.

If one does no longer need the objects in the undo buffer, one can select FlushUndoBuffer() from the Edit Menu to flush the undo buffer. At this point, tgif will attempt to use the shared colormap to avoid the colormap flashing problem. ๐ŸŽ€

If one often uses XPM and GIF objects, one can bind the <Shift>f key to the FlushUndoBuffer() operation by setting the following X default, and uses the <Shift>f key to regain entries in the colormap when an XPM/GIF object is deleted:

Tgif.ShortCuts: !<Key>F:FlushUndoBuffer()

Even when a private colormap is used, only 256 colors can be used at once. So it is literally not possible to import two 256-colors GIF files into the same drawing unless the colors are somehow reduced to fit in the 256-colors colormap. This can be done through dithering, which is described in the IMPORT RASTER GRAPHICS section below. iykyk ๐Ÿฆ‹


๐Ÿ–ผ๏ธ IMPORT RASTER GRAPHICS ๐Ÿ–ผ๏ธ

The native raster graphics formats that tgif supports are XBM and XPM. That's it, that's the native list, no cap.

In order to import a color raster graphics file of another format, tgif can work with external tools that can convert non-XPM format files to XPM files. A popular raster format conversion toolkit is the pbmplus(1) (also known as the netpbm(1)) toolkit. It can convert a GIF file (e.g., "foo.gif") to an XPM file (e.g., "foo.xpm") with the following command (giftopnm is in netpbm; an earlier version of it called giftoppm exists in pbmplus):

giftopnm foo.gif | ppmtoxpm > foo.xpm

When working with tgif, a GIF file name will be supplied by tgif and the output of ppmtoxpm will be directly read by tgif through a pipe; therefore, the previous sequence is replaced by an X default containing the following form (which happens to be the default setting for the Tgif.GifToXpm X default):

giftopnm %s | ppmtoxpm

The "%s" is to be replaced by a GIF file name. The above is referred to as a filter. ๐Ÿงš

To be able to import other types of raster graphics files, one can use Tgif.MaxImportFilters and Tgif.ImportFilter# X defaults to specify additional filters. The following example adds a JPEG filter:

Tgif.MaxImportFilters: 1
Tgif.ImportFilter0: \n\
        JPEG-222 jpg;jpeg \n\
        djpeg -gif -colors 222 %s | \n\
        giftopnm | ppmtoxpm

The "JPEG-222" above is the name given to the filter (must not contain any space character). The "jpg;jpeg" are possible file extensions separated by semicolons. The rest is the filter specification.

The djpeg(1) program is part of the libjpeg distribution. It can convert a JPEG file to a GIF file. The above filter also restricts the output to have a maximum of 222 colors. (The 222 is chosen arbitrarily. Many XPM files use some ``standard'' 32 colors, so one may want to leave room form them.) โœจ

To invoke a filter, one can select ImportOtherFile() or BrowseOther() commands from the File Menu. This will bring up a dialogbox listing the available filters by their names (e.g., "JPEG-222"). After selecting a filter, tgif continues in a similar manner as with invoking ImportXPixmap() or BrowseXPixmap() commands from the File Menu.

heads up bestie: the above example is not suitable for the BrowseOther() command, because only 256 colors can be used in a drawing (as explained in the COLORS AND COLORMAPS section above). ๐Ÿ™ˆ

In order for BrowseOther() to work well, one can use dithering to represent an image with a dithered image that only uses a set of standard colors. The example below uses ppmdither from the pbmplus/netpbm toolkit:

Tgif.MaxImportFilters: 2
Tgif.ImportFilter0: \n\
        JPEG-222 jpg;jpeg \n\
        djpeg -gif -colors 222 %s | \n\
        giftopnm | ppmtoxpm
Tgif.ImportFilter1: \n\
        JPEG-dithered jpg;jpeg \n\
        djpeg -gif %s | \n\
        giftopnm | ppmdither | ppmtoxpm

If one is working with one JPEG image, one can select ImportOtherFile() then select "JPEG-222" to get as many as 222 colors. If one is browsing for JPEG images, one can select BrowseOther() then select "JPEG-dithered". Choose your fighter. ๐Ÿ’…


๐Ÿท๏ธ OBJECT NAMES ๐Ÿท๏ธ

If an object contains an attribute (please see the ATTRIBUTES sections below for details) whose name is the string "name" (case-sensitive), the value part of the attribute is the name of the object. ๐ŸŽ€

Subobject of a composite object can be named using a path, e.g., <t>!<s1>!<s2>!..., where <t> is the name of a top-level object which directly contains <s1> which directly contains <s2>, etc.

!* refers to the currently selected object (if more than one object is selected, the top-most object in the stacking order is used). !*<s1>!<s2> names the <s2> subobject of the <s1> subobject of the currently selected object. Nested like a little matryoshka, obsessed. ๐Ÿฆ‹

The following is not fully supported, yet (only the #<page> form is supported at this time). ๐Ÿ‘‘

Every object in a tgif file can be uniquely named using the notation #<page>!<path>, where <page> can be a string that specifies the name of a page or #<number> which specifies a page number. The <path> is described in the previous paragraph.

If an object o1 is referenced by another object o2 within the same file (no file name or URL is specified before #) and <page> is omitted, then o1 must be on the same page as o2. If a file name or URL is specified before # and <page> is omitted, then o1 must be on the first page.


๐ŸŽ€ ATTRIBUTES ๐ŸŽ€

Attributes are text strings of the form name=value or value which are attached to either the current drawing or any non-text objects.

An attribute attached to the current drawing is called a file attribute; otherwise, it is a regular attribute.

Attributes can be attached and detached from these objects except in the following case:

  • Attributes appearing in the symbol object in a building-block object file can not be detached when the building-block object is instantiated. These attributes are considered to be the <purple>inherited</purple>'' attributes of the icon object. (If it is really necessary to detach inherited attributes of an icon object, the icon object can be de-iconified'' by using UnMakeIconic() in the Special Menu to make it a grouped object; then the attributes can be detached.) ๐Ÿ˜ค

A file attribute is always invisible. For a regular attribute, the user has control over which part of the attribute is displayed. An entire attribute can be made invisible, or only its name can be made invisible (accomplished through the commands under the special menu, such as #m, #n, #j, #-, and ^#h). โœจ


๐Ÿš€ TELEPORT/HYPERJUMP ๐Ÿš€

Tgif provides the mechanism to travel between .obj and .sym files. Portal vibes, honestly.

If the middle mouse button is clicked on an object with the <Shift> key held down (or double-clicking such an object), tgif looks for an attribute named warp_to (by default) or href of that object.

The only difference between warp_to and href is that ".obj" is automatically appended to the value of a warp_to attribute while the value of a href attribute is taken as is. (Please note that warp_to is obsolete now. It is still supported for the sake of compatibility.) ๐Ÿซถ

If such an attribute is found, the value part of the attribute is interpreted as the name of a .obj file to travel to. (If tgif is in the hyperspace mode, then clicking the left mouse button has the same effect.)

If there are multiple href attributes on the object, but are in different colors, tgif will use the one that has the same color as the current color appearing in the Choice Window.

If the current file is modified, the user is prompted to save the file before traveling to the next file. ๐Ÿ™ˆ

If the value part of the href attribute starts with the '/' character, the value is treated as an absolute file name; otherwise, it is treated as a relative file name. ๐Ÿ’…


๐Ÿ›ธ HYPERSPACE ๐Ÿ›ธ

Tgif provides a hyperspace mode to facilitate traveling between .obj files. The hyperspace mode is entered when GoHyperSpace() is selected from the Navigate Menu.

In hyperspace mode, the little window below the Message Window will show a little space ship. ๐Ÿš€โœจ The hyperspace mode is also automatically entered when a remote URL is opened (unless the Tgif.AutoHyperSpaceOnRemote X default is set to false).

In the hyperspace mode, certain objects are considered hot-links. When the cursor is placed on top of these objects, it will change from a pointer to a hand to indicate that clicking on the left mouse button will invoke some actions. ๐Ÿ‘‘

An object is a hot-link if it contains an attribute described in either the TELEPORT/HYPERJUMP, LAUNCH APPLICATIONS, or INTERNAL COMMANDS section.

The hyperspace mode is exited when the drawing mode is changed or the LeaveHyperSpace() is selected from the Navigate Menu. Safe travels bestie ๐Ÿฆ‹

๐Ÿ’ซ LAUNCH APPLICATIONS ๐Ÿ’ซ

Okay bestie, this is where tgif becomes a โœจlittle launcherโœจ and honestly? iconic. Here's the tea:

tgif can literally launch applications for you. If you click the middle mouse button on an object while holding down the <Shift> key (or if you just double-click that object, same energy), tgif goes looking for an attribute named launch (that's the default name, iykyk) on that object.

Found it? Then the value part of that attribute gets interpreted as a sh(1) command to execute. Slay.

Same color rule applies as described in the TELEPORT/HYPERJUMP section above, so don't @ me about it.

Now here's the fork-in-the-road moment ๐Ÿ”€:

  • If the command ends with the '&' character, tgif forks itself โ€” and what actually happens depends on whether the _BACKGROUND_DONT_FORK compiler flag was defined or not at compile time โ€” and the command gets executed by the child process.
  • Otherwise, popen() is used to execute the command.
๐Ÿšจ Real talk: in that popen() case, if the command hangs, there is no way provided to terminate the command, and tgif will not be able to recover from it. Not a vibe. Be careful.

Within the command, values of other attributes of the same object can be used. The syntax is:

$(attr)

where attr is the name of another attribute. Cute, right? ๐ŸŽ€


๐ŸŒธ Example time ๐ŸŒธ

Say you want to do a man(1) function. Here's the whole recipe:

  1. Draw a box.
  2. Enter a line of text "title=tgif".
  3. Enter another line of text "launch=xterm -rw -e man $(title)".
  4. Select all three objects using the ^a keyboard command.
  5. Attach the text strings to the box using the #a keyboard command.
  6. Launch the man(1) command by clicking the middle mouse button on the box (or on the text strings) with the <Shift> key held down.

And if you want to be more fancy ๐Ÿ’…: the box can be replaced by an X11 pixmap object; the 'launch' attribute can be made invisible; and the 'title' attribute can be center justified and have its name hidden using the #m keyboard command. Main character behavior, honestly.


๐Ÿ”’ Security corner ๐Ÿ”’

By default, launching of an application is disabled in the hyperspace mode, for security considerations. (This can be overridden by the Tgif.AllowLaunchInHyperSpace X default setting.)

If a launch command is encountered in the hyperspace mode, the command is displayed and the user is prompted to see if he/she wants to execute the command. Consent first, always ๐Ÿซถ


๐Ÿง  INTERNAL COMMANDS ๐Ÿง 

tgif also has a whole mechanism for executing internal commands. Same trigger, different flavor: click the middle mouse button on an object with the <Shift> key held down (or double-click such an object), and tgif looks for an attribute named exec (that's the default name) on that object.

Found it? Then the value part of that attribute is interpreted as a list of internal commands (separated by semicolons) to execute. Same color rule applies as described in the TELEPORT/HYPERJUMP section above. Periodt.

A command usually takes the form:

<cmd_name> ( <arg1>, <arg2>, ..., <argN> )

An argument of a command can be a string argument or a numeric argument:

  • A string argument must be enclosed in double-quotes.
  • A numeric argument can be a numerical value, or a string of the form "$(x)", where x is the name of another attribute โ€” this form is referred as the substitution form.

A string argument can also contain substitution form. โœจ

โš ๏ธ Please note that only one-level substitution is performed. The collection of internal commands should be viewed as a simple scripting language and not a declaration language. Don't get it twisted.

๐Ÿ“› Attribute name rules ๐Ÿ“›

When an attribute is referenced in an internal command, the attribute name can be in the form:

<obj_name>.<string>

where <obj_name> must be in the form specified in the OBJECT NAMES section above, and <string> contains only alphanumeric characters and the underscore ('_') character.

Special prefixes, bestie, memorize these:

  • If the first 2 characters of an attribute name are "!.", the rest of the attribute name names a file attribute.
  • If the first 2 characters of an attribute name are "!*", the rest of the attribute name names an attribute of the currently selected object. (And if more than one object is selected, the top-most object in the stacking order is used. ๐Ÿ‘‘)
๐Ÿ’ฌ Please note that lines that begin with "//" are treated as comments.

The following internal commands are supported:


launch(<attr_name>)

The value of the attribute specified by <attr_name> is interpreted as a sh(1) command to execute. Please see the LAUNCH APPLICATIONS section above for more details. ๐Ÿš€

exec(<attr_name>)

The value of the attribute specified by <attr_name> is interpreted as an internal command to execute. This is similar to a subroutine call. Please note that the internal command is executed in the context of the top-level which contain the attribute. ๐Ÿ”

mktemp(<str>,<attr_name>)

This command makes a unique file name. The <str> argument is a template string, e.g., "/tmp/TgifXXXXXX", and it requires at least two "/" in it. The result of mktemp() is stored as the value of the attribute specified by <attr_name>. Please see the man pages of the C library function on mktemp(3C) for more details.

๐Ÿ’ก (If tgif is compiled with the -D_USE_TMPFILE compiler option, then tempnam(3S) is used instead.)

create_file_using_simple_template(<template>,<output>,<str>,<attr_name>)

The file specified by <template> is scanned for a line that matches <str>. When such a line is found, that line is replaced by the value of the attribute specified by <attr_name>. The result is put into the file specified as <output>. ๐Ÿ“

update_eps_child(<eps_file_name>)

This only works if the object being executed is a composite object. If the object has a component which is an imported EPS (Encapsulated PostScript) object, it is replaced by the EPS file specified by <eps_file_name>. If the object does not contain an EPS subobject, an EPS subobject is created. โœจ

update_xbm_child(<xbm_file_name>)

This only works if the object being executed is a composite object. If the object has a component which is an imported XBM (X11 bitmap) object, it is replaced by the XBM file specified by <xbm_file_name>. If the object does not contain an XBM subobject, an XBM subobject is created. ๐Ÿ–ผ๏ธ

update_xpm_child(<xpm_file_name>)

This only works if the object being executed is a composite object. If the object has a component which is an imported XPM (X11 pixmap) object, it is replaced by the XPM file specified by <xpm_file_name>. If the object does not contain an XPM subobject, an XPM subobject is created. ๐ŸŽจ

delete_eps_child(<obj_name>)

This only works if the object named <obj_name> is a composite object. If the object has a component which is an EPS (Encapsulated PostScript) object, it is deleted. If the object does not contain an EPS subobject, no operation is performed. ๐Ÿ’€

delete_xpm_child(<obj_name>)

This only works if the object named <obj_name> is a composite object. If the object has a component which is an XPM (X11 pixmap) object, it is deleted. If the object does not contain an XPM subobject, no operation is performed. ๐Ÿ’€

delete_xbm_child(<obj_name>)

This only works if the object named <obj_name> is a composite object. If the object has a component which is an XBM (X11 bitmap) object, it is deleted. If the object does not contain an XBM subobject, no operation is performed. ๐Ÿ’€

flip_deck(<times>,<frames_per_second>,<style>)

This only works if the object being executed is a composite object and all subobjects of the composite object are X11 bitmap or X11 pixmap objects and have identical positions and sizes.

  • The <times> argument specifies the number of times the deck is flipped. It can be a number or the string "infinite". โ™พ๏ธ
  • The <frames_per_second> argument must be a number between 1 and 60.
  • The <style> argument can be either "linear" or "ping_pong".
๐Ÿ›‘ When this command is being executed, any mouse button click or key click aborts command execution.

read_file_into_attr(<file_name>,<attr_name>)

This command reads a file into an attribute. The <file_name> argument names a file, e.g., "/tmp/foo". The content of the file is read as the value of the attribute specified by <attr_name>. If the file can not be opened for read, the attribute's value is set to an empty string. ๐Ÿ“–

write_attr_into_file(<attr_name>,<file_name>)

This command writes the value of an attribute into a file. The <file_name> argument names a file, e.g., "/tmp/foo". The value of the attribute specified by <attr_name> is written into <file_name>. โœ๏ธ

append_attr_into_file(<attr_name>,<file_name>)

This command appends the value of an attribute into a file. The <file_name> argument names a file, e.g., "/tmp/foo". The value of the attribute specified by <attr_name> is appended into <file_name>. โž•

select_obj_by_name(<obj_name>)

This command silently (no highlighting handles) selects an object named <obj_name>. Please see the OBJECT NAMES section above for the specification of object names. ๐Ÿคซ

select_top_obj()

This command silently (no highlighting handles) selects the top object. This command fails if there is no object in the current page. ๐Ÿ‘‘

delete_selected_obj()

This command deletes all selected objects. This command fails if no object is selected. ๐Ÿ—‘๏ธ

unselect_all_obj()

This command de-selects all selected objects. If the select_obj_by_name() command is used, this command must be used eventually. ๐Ÿงน

move_selected_obj_relative(<dx>,<dy>)

This command moves the selected object by <dx> absolute units in the x direction and <dy> absolute units in the y direction. โ†”๏ธ

repeat(<cmd_attr_name>,<times>)

This command executes the internal command in the <cmd_attr_name> attribute <times> times. ๐Ÿ”‚

hyperjump(<attr_name>)

This command teleports to the file name or URL name found in the <attr_name> attribute. ๐ŸŒ€

make_cgi_query(<dest_attr_name>,<url_name>,<list_attr_name>)

This command constructs an URL in the Common Gateway Interface (CGI) format in the <dest_attr_name> attribute. <url_name> names the CGI server script and <list_attr_name> names an attribute whose value are comma-separated attribute names.

For example, if an object has the following attributes:

attr_list=last_name,first_name
last_name=Cheng
first_name=Bill
final_url=
exec=make_cgi_query(final_url,
    http://bourbon.usc.edu:8001/cgi-bin/test-cgi,
    attr_list)

Executing this object will construct the following string in final_url:

http://bourbon.usc.edu:8001/cgi-bin/test-
cgi?last_name=Cheng&first_name=Bill

A subsequent hyperjump(final_url) command can be fired off to run the matching "test-cgi" CGI server script, handing it the last_name and first_name arguments. ๐ŸŽ€

And if you actually want the full lore on CGI scripts, the reader is pointed at reference [2]. ๐Ÿ’…


wait_click(<cursor_name>,<grab>,<attr_name>)

This one shows the <cursor_name> cursor and then just... sits there waiting for someone to click a mouse button. ๐Ÿ–ฑ๏ธ If <cursor_name> is the string NULL (case-sensitive, bestie, don't test me), the cursor does not change at all. Click <Btn1> and the command ends with 1 dropped into <attr_name>. Click <Btn2> and it's 2 in <attr_name>, etc. โ€” you get the pattern. If <grab> is set to TRUE (case-sensitive again ๐Ÿ’€), then tgif grabs the mouse. Valid <cursor_name> names live in <X11/cursorfont.h>, and you use them without the XC_ prefix.

sleep(<cursor_name>,<ms_interval>)

Displays the <cursor_name> cursor and then waits for <ms_interval> milliseconds to tick by. โณ If <cursor_name> is the string NULL (case-sensitive), the cursor won't change. This command can be interrupted โ€” and aborted โ€” by any mouse clicks or key strokes, so it's very "you can leave whenever, no hard feelings". Valid <cursor_name> names are in <X11/cursorfont.h> (again, no XC_ prefix).

begin_animate()

Kicks off an animation sequence using double-buffering. ๐Ÿฆ‹ Heads up though: by default tgif gets ready for undo/redo, and for a long animation sequence those undo/redo records can eat up a lot of memory. So in that case, call disable_undo() (it's described down below) before this command.

end_animate()

Ends an animation sequence. That's it, that's the whole vibe. ๐Ÿซถ

set_redraw(<true_or_false>)

Temporarily disables redraw when <true_or_false> is FALSE (case-sensitive) and tgif is in animation mode (the mode turned on by begin_animate()). Here's the move: if you're using a shuffle_obj_to_top() or a shuffle_obj_to_bottom() command before a move command, then set_redraw(FALSE) should go immediately before it and set_redraw(TRUE) should go immediately after it. Timing is everything, periodt. โœจ

set_selected_obj_color(<color_str>)

Changes the color of the selected object to <color_str>. If nothing is selected, the current color gets changed to <color_str> instead. ๐ŸŽจ

set_selected_obj_fill(<fill_index>)

Changes the fill pattern of the selected object to <fill_index>, which has to be between 0 (that's no fill) and 31. If nothing is selected, the current fill pattern becomes <fill_index>. ๐ŸŒˆ

set_selected_obj_pen(<pen_index>)

Changes the pen of the selected object to <pen_index>, which must be between 0 (no pen) and 31. If no object is selected, the current pen gets changed to <pen_index>. ๐Ÿ–Š๏ธ

set_selected_obj_line_width(<width>,<arrow_w>,<arrow_h>)

Changes the line width, arrow width, and arrow height of the selected object to <width>, <arrow_w>, and <arrow_h> respectively. If <arrow_w> or <arrow_h> is -1, then the arrow width or arrow height (respectively) is left alone, no touchy. ๐Ÿ™ˆ If no object is selected, the current line width changes to whichever one matches <width>, <arrow_w>, and <arrow_h> most closely. And how is closeness measured, you ask? The difference in width counts as 10 times the difference in arrow width and arrow height. Math girlies stay winning. ๐Ÿ‘‘

set_selected_obj_spline(<spline_type>)

Changes the spline type of the selected object to <spline_type>, which can be straight, spline, interpolated, or structured. If no object is selected, the current spline type changes to <spline_type>. ๐ŸŒ€

set_selected_obj_arrow(<arrow_type>)

Changes the arrow type of the selected object to <arrow_type>, which can be none, right, left, or double. If no object is selected, the current arrow type changes to <arrow_type>. โžก๏ธ

set_selected_obj_dash(<dash_index>)

Changes the dash type of the selected object to <dash_index>, which must be between 0 (solid) and 8. If no object is selected, the current dash type changes to <dash_index>. โœ‚๏ธ

set_selected_obj_trans_pat(<trans_pat>)

Gives the selected object an opaque pattern if <trans_pat> is 0; gives it a transparent pattern if <trans_pat> is any other numeric value. If no object is selected, the current fill and pen pattern will be opaque when <trans_pat> is 0, and transparent when <trans_pat> is any other numeric value. ๐Ÿ‘ป

set_selected_obj_rcb_radius(<rcb_radius>)

Changes the rcbox radius of the selected object to <rcb_radius>, which must be greater than or equal to 4. If no object is selected, the current rcbox radius changes to <rcb_radius>. ๐ŸŽ€

set_selected_text_vspace(<vspace>)

Changes the text vspace of the selected object to <vspace>. If no object is selected, the current text vspace changes to <vspace>. ๐Ÿ“

set_selected_text_just(<justification>)

Changes the text justification of the selected object to <justification>, which can be left, center, or right. If no object is selected, the current text justification changes to <justification>. ๐Ÿซถ

set_selected_text_font(<ps_font_name>)

Changes the font and text style of the selected object to match <ps_font_name>. Wanna see examples of valid <ps_font_name> values? Select CopyProperties() from the Properties Menu โ€” the item listed under text font is a valid <ps_font_name>. If no object is selected, the current font and text style change to match <ps_font_name>. Warning bestie: this command fails if no match can be found. ๐Ÿ˜ญ

set_selected_text_style(<textstyle>)

Changes the text style of the selected object to <textstyle>, which can be r (for roman), b (for bold), i (for italic), or bi (for bold-italic). If no object is selected, the current text style changes to <textstyle>. โœ๏ธ

set_selected_text_size(<size>)

Changes the text size of the selected object to <size>. Sneaky detail: if <size> ends with the substring "pt", then point size is used instead of text size. ๐Ÿ‘€ And if that size can't be found in the Size Menu, the closest size in the Size Menu gets used instead. If no object is selected, the current text size changes to <size> โ€” or the closest size. โญ

set_selected_text_underline(<underline>)

Removes text underline from the selected object if <underline> is 0; underlines the text in the selected object if <underline> is any other numeric value. If no object is selected, the current text underline changes accordingly. ๐Ÿ”ก

set_selected_text_overline(<overline>)

Removes text overline from the selected object if <overline> is 0; overlines the text in the selected object if <overline> is any other numeric value. If no object is selected, the current text overline changes accordingly. ๐ŸŽฏ

inc(<attr_name>,<expr>)

Increments <attr_name> by the expression <expr>. Both the value of <attr_name> and <expr> must be integers. For the deets on expressions, go read the ARITHMETIC EXPRESSIONS section below. โž•

dec(<attr_name>,<expr>)

Decrements <attr_name> by <expr>. Both the value of <attr_name> and <expr> must be integers. โž–

shuffle_obj_to_top(<obj_name>)

Moves <obj_name> to the top. If <obj_name> is a subobject, it gets raised to the top relative to its siblings. This one is genuinely so useful in animation, where a selected frame (subobject) can be raised to the top. ๐Ÿ”

shuffle_obj_to_bottom(<obj_name>)

Moves <obj_name> to the bottom. If <obj_name> is a subobject, it gets dropped to the bottom relative to its siblings. Also super useful in animation, where a selected frame (subobject) can be dropped to the bottom. ๐Ÿ”ป

disable_undo()

Cleans up the undo/redo records and disables undo โ€” and it also stops recording undo/redo information. The original history depth is saved away for later. Use this before a long animation sequence so your memory doesn't just evaporate. ๐Ÿ’€

enable_undo()

Restores the history depth that was saved away by the disable_undo() command, and re-enables undo/redo. This one should eventually be used after disable_undo() is called โ€” don't leave your girl hanging. ๐Ÿซถ

get_drawing_area(<ltx_attr>,<lty_attr>,<rbx_attr>,<rby_attr>)

Stores the absolute coordinate of the current drawing area into the attributes you name. <ltx_attr> gets the left-top X coordinate, <lty_attr> gets the left-top Y coordinate, <rbx_attr> gets the right-bottom X coordinate, and <rby_attr> gets the right-bottom Y coordinate. ๐Ÿ“

get_selected_obj_bbox(<ltx_attr>,<lty_attr>,<rbx_attr>,<rby_attr>)

Stores the absolute coordinate of the bounding box of the selected object into the given attributes. <ltx_attr> = left-top X coordinate, <lty_attr> = left-top Y coordinate, <rbx_attr> = right-bottom X coordinate, <rby_attr> = right-bottom Y coordinate. Important caveat: the bounding box is computed assuming that all lines are of width 0. ๐Ÿ“ฆ

get_named_obj_bbox(<obj_name>,<ltx_attr>,<lty_attr>,<rbx_attr>,<rby_attr>)

Stores the absolute coordinate of the bounding box of the object named <obj_name> into the given attributes. <ltx_attr> = left-top X coordinate, <lty_attr> = left-top Y coordinate, <rbx_attr> = right-bottom X coordinate, <rby_attr> = right-bottom Y coordinate. Same caveat as above: the bounding box assumes all lines are of width 0. ๐Ÿงš

move_selected_obj_absolute(<ltx>,<lty>)

Moves the left-top corner of the selected object to (<ltx>,<lty>). ๐Ÿšš

assign(<attr_name>,<expr>)

Assigns <expr> to the attribute specified by <attr_name>. And <expr> must evaluate to a numeric value, no exceptions. ๐Ÿ’–

strcpy(<attr_name>,<string>)

Copies <string> into the attribute specified by <attr_name>. ๐Ÿ“

  • copy_string_to_cut_buffer(<string>) โ€” bestie, this one yeets <string> straight into the cut buffer. That's it. That's the whole job. ๐Ÿ’–
  • strcat(<attr_name>,<string>) โ€” glues <string> onto the end of whatever's already in the attribute called <attr_name>. Append-core fr.
  • while(<expr>,<cmd_attr_name>) โ€” the iconic loop ๐Ÿ’… it keeps running the internal command sitting in <cmd_attr_name> over and over until <expr> evaluates to 0.
  • if(<expr>,<then_cmd_attr_name>,<else_cmd_attr_name>) โ€” the classic pick-a-path. If <expr> evaluates to 0, the internal command in <else_cmd_attr_name> runs; otherwise the internal command in <then_cmd_attr_name> runs. Now listen โ€” <then_cmd_attr_name> or <else_cmd_attr_name> can be the string NULL (case-sensitive), and in that case, no corresponding action is taken at all. Nothing. Silencio. ๐Ÿคซ
  • get_current_file(<attr_name>) โ€” drops the full path name of the current file into <attr_name>.
  • get_current_export_file(<attr_name>) โ€” same energy but for the output (print/export) file โ€” full path name goes into <attr_name>. โœจ
  • get_current_dir(<attr_name>) โ€” stores the current directory in <attr_name>. Where you at? Now your attribute knows.
  • getenv(<attr_name>,<env_var_name>) โ€” snags the environment variable named <env_var_name> and stashes it in <attr_name>.
  • strlen(<attr_name>,<string>) โ€” counts the characters in <string> and assigns that number to <attr_name>. Math but make it stringy.
  • substr(<attr_name>,<string>,<start_index>,<length>) โ€” copies <length> characters of <string>, starting from character index <start_index>, into <attr_name>. Heads up: <start_index> is zero-based, so the first character is index 0, no cap. ๐Ÿ“
  • strstr(<attr_name>,<string>,<sub_string>) โ€” finds the first occurrence of <sub_string> inside <string>, then copies <sub_string> and the rest of the string into <attr_name>.
  • strrstr(<attr_name>,<string>,<sub_string>) โ€” literally the same but for the last occurrence of <sub_string> in <string>, and again it copies <sub_string> plus the rest of the string into <attr_name>. ๐Ÿ”ฅ
  • unmake_selected_obj_iconic() โ€” does the exact same thing as picking UnMakeIconic() from the Special Menu, with one lil condition: at least one object has to already be selected. ๐Ÿ‘‘
  • hyperjump_then_exec(<attr_name>,<attr_name_to_exec>) โ€” teleports to the file name or URL name found in the <attr_name> attribute, then executes the internal command specified by the <attr_name_to_exec> attribute in the new file. Teleport + do-a-thing, the crossover episode. ๐Ÿฆ‹
  • show_attr(<attr_name>) โ€” makes the <attr_name> attribute visible.
  • hide_attr(<attr_name>) โ€” makes the <attr_name> attribute invisible. Poof. ๐Ÿ™ˆ
  • show_attr_name(<attr_name>) โ€” makes the name part of the <attr_name> attribute visible.
  • hide_attr_name(<attr_name>) โ€” makes the name part of the <attr_name> attribute invisible.
  • show_value(<attr_value>) โ€” makes the attribute whose name is empty and whose value is <attr_value> visible.
  • hide_value(<attr_value>) โ€” makes the attribute whose name is empty and whose value is <attr_value> invisible.
  • get_attr_bbox(<ltx_attr>,<lty_attr>,<rbx_attr>,<rby_attr>,<attr_name>) โ€” stores the absolute coordinate of the bounding box of the <attr_name> attribute into the attributes you named. So: <ltx_attr> gets the left-top X coordinate, <lty_attr> gets the left-top Y coordinate, <rbx_attr> gets the right-bottom X coordinate, and <rby_attr> gets the right-bottom Y coordinate. ๐Ÿ“ And lowkey important: the bounding box is computed assuming that all lines are of width 0.
  • size_selected_obj_absolute(<abs_w>,<abs_h>) โ€” stretches the right-bottom corner of the selected object so its width becomes <abs_w> and its height becomes <abs_h>.
  • size_named_obj_absolute(<obj_name>,<abs_w>,<abs_h>) โ€” same stretchy situation but for the object named <obj_name>: right-bottom corner gets pulled so the width is <abs_w> and the height is <abs_h>.
  • message_box(<attr_name>,<msg>,<title>,<style>) โ€” pops up a messagebox with <title> as the title and <msg> as the message. ๐Ÿ’ฌ <style> can be the string "info", "ync", "yn", or "stop". The messagebox shows an OK button for the "info" or "stop" styles, YES/NO/CANCEL buttons for the "ync" style, and YES/NO buttons for the "yn" style. When the user clicks a button, the name of that button gets placed in <attr_name>. If the user cancels the messagebox by typing the <ESC> key, <attr_name> gets set to the string "CANCEL". If <attr_name> is the string NULL (case-sensitive), then the info about which button was clicked isn't written anywhere at all. And if <title> is the string NULL, then Tgif will be the title for the messagebox. ๐Ÿ˜Œ
  • get_user_input(<attr_name>,<msg1>,<msg2>) โ€” shows a dialogbox with <msg1> on the first line and <msg2> on the second line. If <msg2> is the string "USE_CURRENT_DIR", then that second line displays the current directory instead. The user can type a line into the dialogbox, and whatever they type gets placed in <attr_name>. If they cancel by typing the <ESC> key, <attr_name> gets set to the empty string. ๐Ÿซถ
  • add_attr_to_selected_obj(<attr_name>,<attr_value>,<abs_x>,<abs_y>) โ€” adds <attr_name>=<attr_value> to a selected object and places the attribute at (<abs_x>,<abs_y>). If <attr_name> is the string NULL (case-sensitive), the attribute's name will be the empty string. If <abs_x> and <abs_y> are both NULL (case-sensitive), the attribute gets placed below the lower left corner of the object. And plot twist โ€” if <attr_name> starts with "!.", a file attribute will be added. ๐Ÿ‘€
  • delete_attr_from_selected_obj(<attr_name>) โ€” deletes an attribute named <attr_name> from a selected object. Same deal as above: if <attr_name> starts with "!.", a file attribute will be deleted.
  • user_end_an_edge(<attr_name>,<abs_x>,<abs_y>) โ€” starts a polyline/open-spline at (<abs_x>,<abs_y>), flips the drawing mode to the draw polyline/open-spline, and lets the user finish the polyline/open-spline themselves. If the endpoint falls in an object having an attribute type=port, that object's name gets placed in <attr_name> โ€” but only if <attr_name> is not the string NULL (case-sensitive).
  • user_draw_an_edge(<start_attr_name>,<end_attr_name>) โ€” switches the drawing mode to the draw polyline/open-spline and lets the user draw a polyline/open-spline. If the first endpoint falls in an object having an attribute type=port, that object's name gets placed in <start_attr_name> โ€” if <end_attr_name> is not the string NULL (case-sensitive). If the last endpoint falls in an object having an attribute type=port, that object's name gets placed in <end_attr_name> โ€” if <attr_name> is not the string NULL (case-sensitive). ๐Ÿงš
  • get_a_poly_vertex_absolute(<x_attr_name>,<y_attr_name>,<obj_name>,<index>) โ€” stores the absolute coordinate of the <index>th vertex of <obj_name> into the attributes specified by <x_attr_name> and <y_attr_name>. Important vibe check: the object specified by <obj_name> must be either a poly/open-spline or a polygon/closed-spline object. โญ
  • move_a_poly_vertex_absolute(<obj_name>,<index>,<abs_x>,<abs_y>) โ€” moves the <index>th vertex of <obj_name> to the absolute coordinate (<abs_x>,<abs_y>). Same rule applies: <obj_name> must be either a poly/open-spline or a polygon/closed-spline object.
  • post_attr_and_get_cgi_result(<url_attr>,<query_attr>,<result_attr>) โ€” makes an HTTP request using the POST method. ๐ŸŒˆ <url_attr> names the attribute that contains the URL (which usually names a CGI server script). <query_attr> names the attribute whose value is the data to be posted. <result_attr> names the attribute for receiving the results. For example, if an object has the following attributes:
url=http://bourbon.usc.edu:8001/cgi-bin/echo-post
query=Hello World!
result=
exec=post_attr_and_get_cgi_result(url,query,result)

executing this object will post "Hello World!" to the specified CGI script. In this case, the result of executing the script just echoes "Hello World!" back (along with some other bookkeeping information). ๐Ÿ’–

  • navigate_back() โ€” performs the same operation as if NavigateBack() is selected from the Navigate Menu.
  • stop() โ€” this command stops the execution of all internal commands. ๐Ÿ’€ The ultimate "we're done here."
  • sqrt(<attr_name>,<expr>) โ€” assigns the square-root of <expr> to <attr_name>. Heads up bestie: <expr> must be evaluated to a non-negative numeric value. No imaginary numbers on my watch. ๐Ÿ“
  • random(<attr_name>) โ€” assigns a random integer to <attr_name> using the C library function rand(). And note: 0 is used as a seed for the random number generator. (So like, not that random the first time, iykyk.)
  • srand48(<use_cur_time_as_seed>) โ€” seeds the random generator used by the C library function drand48(). If <use_cur_time_as_seed> is 0, then 0 will be used as a seed. Otherwise, the current time will be used as a seed. โฐ
  • drand48(<attr_name>) โ€” assigns a floating pointer number between 0.0 and 1.0 to <attr_name> using the C library function drand48().
  • round(<attr_name>,<expr>) โ€” assigns the round of <expr> to <attr_name>.
  • redraw_obj(<obj_name>) โ€” redraws the area occupied by <obj_name>.
  • redraw_drawing_area() โ€” redraws the whole drawing area (the part visible through the Canvas Window). Refresh slay. โœจ
  • itox(<attr_name>,<digits>,<expr>) โ€” assigns <attr_name> to be the hex value of <expr>. And <digits> (which must be between 1 and 8, inclusive) is the final width of the hex value โ€” zeroes get added on the left. ๐ŸŽ€
  • for_i(<attr_name>,<min_val>,<max_val>,<increment>,<cmd_attr_name>) โ€” this command is the same as the following sequence of commands:
assign(<attr_name>,<min_val>);
while($(<attr_name>) <= <max_val>,loop)

where loop has the following value:

exec(<cmd_attr_name>);
inc(<attr_name>,<increment>)

Please note that <min_val>, <max_val>, and <increment> are only evaluated once prior to the execution of this command. One and done, no re-evaluating mid-loop. ๐Ÿ’…

  • set_file_not_modified() โ€” flips the file modified flag to false, like "okay bestie, we're saved, we're chill, no unsaved-changes drama here" ๐Ÿ’…
  • new_id(<attr_name>) โ€” cooks up an object ID that's unique in the current drawing and drops it into <attr_name>. Every ID is one of a kind, no dupes allowed ๐Ÿ‘‘
  • rotate_selected_obj(<angle>) โ€” spins the selected object by <angle> degrees. Heads up: a positive angle goes clockwise. Not counterclockwise. Clockwise. That's the vibe ๐ŸŒ€
  • call_simple_shortcut(<shortcut_name>) โ€” calls a shortcut named <shortcut_name> that takes zero arguments. Peep the SHORTCUTS section if you need the lore on what shortcuts even are โœจ
  • call_one_arg_shortcut(<shortcut_name>,<arg>) โ€” calls a shortcut named <shortcut_name> that takes exactly one argument, and hands it <arg>. Again, SHORTCUTS section has the full tea ๐Ÿซถ
  • substitute_attr(<attr_name>,<src_attr_name>,<replace_attr_name>,<pattern_str>) โ€” takes every occurrence of <pattern_str> inside the value of the attribute named by <src_attr_name>, swaps them for the value of the attribute named by <replace_attr_name>, and writes the glow-up result into the attribute named by <attr_name>. It's giving find-and-replace but for attributes ๐Ÿ’–
  • get_file_size(<attr_name>,<file_name>) โ€” plops the size of the file at <file_name> into the attribute <attr_name>. Size check, no cap ๐Ÿ“
  • is_file(<attr_name>,<file_name>) โ€” writes a "1" into <attr_name> if the file <file_name> actually exists, and a "0" if it doesn't. Simple as that, fr fr โœ…
  • index(<attr_name>,<string>,<sub_string>) โ€” finds the first occurrence of <sub_string> in <string> and copies the zero-based index into <attr_name> ๐Ÿ”
  • rindex(<attr_name>,<string>,<sub_string>) โ€” same energy as index(), except it finds the last occurrence of <sub_string> in <string> and copies that zero-based index into <attr_name> ๐Ÿ”Ž
  • get_number_of_lines_in_attr(<result_attr>,<attr_name>) โ€” counts how many lines live in the attribute <attr_name> and writes that count into <result_attr>. Line census, basically ๐Ÿงฎ
  • get_line_in_attr(<result_attr>,<attr_name>,<line_number>) โ€” copies the nth line of the attribute <attr_name> into <result_attr>, where n is a zero-based index given by <line_number>. Zero-based, bestie, so line 0 is the first line, don't @ me ๐ŸŒธ
  • trim(<attr_name>) โ€” strips the leading and trailing blank characters off the attribute <attr_name>. Snip snip โœ‚๏ธ
  • is_attr(<result_attr>,<attr_name>) โ€” writes a "1" into <result_attr> if the attribute <attr_name> exists, and a "0" into <result_attr> if it doesn't ๐Ÿ•ต๏ธ
  • find_obj_names(<result_attr>,<obj_name>,<attr_name_value>) โ€” finds every object that's a direct sub-object of the object named by <obj_name> and writes their names into <result_attr>. And if <obj_name> is an empty string? Then it scans all top-level objects. The whole squad, every time ๐ŸŒˆ

<attr_name_value> is the filter, and here's how it vibes:

  • If <attr_name_value> is the empty string, every qualifying object gets selected. No filter, no problem.
  • If <attr_name_value> looks like "<string>=*", an object gets selected if it has an attribute named <string>.
  • If <attr_name_value> looks like "<string>=<value>", an object gets selected if it has an attribute named <string> and that attribute's value is <value>.
  • If <attr_name_value> doesn't contain the '=' character at all, an object gets selected if it has an attribute whose name is empty and whose corresponding value is identical to <attr_name_value>.

Now the results part: if n objects match, the attribute <result_attr> gets updated with n+1 lines. The value of the zeroth line becomes n, and the object names become lines 1 through n of <result_attr>. To actually pull those object names back out, use the get_line_in_attr() internal command ๐ŸŽ€

  • find_obj_names_on_all_pages(<result_attr>,<attr_name_value>) โ€” basically find_obj_names() above but with a passport: it only finds top-level objects on all pages, and writes the result into <result_attr>. For a multi-page file, a top-level object name <name> gets written into <result_attr> as ##<page_num>!<name>. For a single-page file, this command behaves exactly like find_obj_names(<result_attr,"",<attr_name_value>). (Yeah, the original's missing a closing paren there โ€” iconic typo, we keep it ๐Ÿ’€)
  • tg2_find_obj_names_on_all_pages(<result_attr>,<attr_name_value>) โ€” literally identical to find_obj_names_on_all_pages() above, except that for a multi-page file, a top-level object name <name> gets written into <result_attr> as <name>_Page<page_num> instead. Different naming scheme, same mission ๐Ÿฆ‹
  • tokenize(<result_attr>,<string>,<separator>) โ€” breaks <string> into tokens separated by the <separator> character and writes those tokens into <result_attr> (in the same fashion as the find_obj_names() internal command above, so you know the drill). <separator> has to be a string of length 1, and it must not be the space character, the single-quote character, or the double-quote character. Also! If a token contains the separator character itself, you can wrap that token in a pair of single-quotes or double-quotes, and those quotes get automatically removed when this command runs. Sneaky, but it works ๐Ÿ’…

Same counting deal: if n tokens are found, <result_attr> gets updated with n+1 lines, the zeroth line holds n, and the tokens become lines 1 through n of <result_attr>. Use get_line_in_attr() to retrieve them ๐Ÿ“ฅ

  • move_attr_relative(<attr_name>,<dx>,<dy>) โ€” moves the attribute named <attr_name> by <dx> absolute units in the x direction and <dy> absolute units in the y direction. Scoot scoot ๐Ÿ›ผ
  • get_number_of_vertices(<result_attr>,<obj_name>) โ€” copies the number of vertices of the object <obj_name> into <result_attr>. Important: the object has to be a polyline (open-spline) or a polygon (closed-spline). Anything else and it's just not that girl ๐Ÿ”บ
  • is_obj_transformed(<result_attr>,<obj_name>) โ€” writes a "1" into <result_attr> if the object <obj_name> is transformed (that means rotated or sheared), and a "0" otherwise. Transformation check, done ๐Ÿ’ซ
  • make_selected_obj_iconic(<sym_path>) โ€” works just like the MakeIconic() command from the Special Menu, except the user never gets prompted for the icon's name. Instead, <sym_path> hands over the full path name of the icon directly. No pop-ups, no waiting, we love efficiency ๐Ÿ‘‘
  • get_tgif_version(<major_attr,minor_attr,patchlevel_attr,build_attr>) โ€” writes tgif's major version number, minor version number, patchlevel, and build info into <major_attr>, <minor_attr>, <patchlevel_attr>, and <build_attr>, respectively. And if any argument is the string NULL (case-sensitive!), that piece of info gets skipped. Version check, but make it fashion โญ
  • get_tgif_dir(<result_attr>) โ€” writes "$HOME/.Tgif" into <result_attr>, where $HOME is the user's home directory. Home sweet home ๐Ÿ 
  • get_profile_string(<result_attr>,<section>,<key>,<def_value>,<ini_path>) โ€” grabs the value tied to the key <key> from the section <section> in the file at the full path <ini_path>, and stashes it into the attribute <result_attr>. If there's no value associated with that key, then <def_value> gets stored into <result_attr> instead. Backup plan, always ๐Ÿซถ

Two special cases, and they're good ones:

  • If <key> is an empty string, all the key names in <section> of <ini_path> get written into <result_attr> (same fashion as the find_obj_names() internal command above, you know the format by now).
  • If <section> is an empty string, all the section names in <ini_path> get written into <result_attr> (again, same fashion as find_obj_names() above).
  • write_profile_string(<section>,<key>,<value>,<ini_path>) โ€” sets the value tied to the key <key> in the section <section> of the file at the full path <ini_path> to be <value>. And if <key> is an empty string, all key/value pairs in <section> of <ini_path> get cleared. โš ๏ธ Oh, and <section> should not be an empty string here โ€” don't do it bestie, that's not the move ๐Ÿ™ˆ
  • select_additional_obj(<obj_name>) โ€” silently selects an additional object named <obj_name> โ€” silently meaning no highlighting handles, just vibes. Check the OBJECT NAMES section above for how object names are specified ๐ŸŽฏ
  • open_file(<file_number>,<file_name>,<file_mode>) โ€” opens the file <file_name> in the mode <file_mode> and gives the opened file a file reference number of <file_number>. <file_number> must be 0 or between 3 and 15. Opening file 0 rewinds the standard input. Mode examples: "r" for reading, "w" for writing, "a" for appending. And heads up โ€” a file is always opened in text (non-binary) mode ๐Ÿ“‚
  • close_file(<file_number>) โ€” closes the file tied to file reference number <file_number>. <file_number> must be 0 or between 3 and 15 ๐Ÿ”’
  • read_file(<file_number>,<result_attr>) โ€” reads a line from the file tied to file reference number <file_number> and puts that line into the attribute <result_attr>. <file_number> must be between 0 (that's standard input) or between 3 and 15 ๐Ÿ“–
  • write_file(<file_number>,<string>) โ€” writes <string> to the file tied to file reference number <file_number>. Here <file_number> must be between 1 and 15. Numbers 1 and 2 are for standard output and standard error files, respectively โœ๏ธ
  • flush_file(<file_number>) โ€” flushes the file tied to file reference number <file_number>. <file_number> must be between 1 and 15. Numbers 1 and 2 are for standard output and standard error files ๐Ÿšฐ
  • append_file(<dest_file_name>,<src_file_name>) โ€” appends the file <src_file_name> onto the file <dest_file_name>. Gluing files together, respectfully ๐Ÿงท
  • set_output_format(<format>,<color_output>) โ€” sets the output format to <format>. If <color_output> is 0, black and white output (printing) mode gets used; otherwise, color output (printing) mode gets used. Wanna know which formats are even possible? Check the Tgif.WhereToPrint X default for the full list ๐Ÿ–จ๏ธ๐ŸŒˆ

set_export_clip_rect(<ltx>,<lty>,<rbx>,<rby>)

okay so this one sets the export clipping rectangle to be a rectangular region with its left-top corner at (<ltx>,<lty>) and its right-bottom corner at (<rbx>,<rby>). and bestie, the rules are the rules: <ltx> must be strictly less than <rbx>, and <lty> must be strictly less than <rby>. no flipsies, no degenerate rectangles, the math said what it said. ๐Ÿ’…

import_file(<file_name>,<format>,<ltx>,<lty>)

this command imports the file named by <file_name> and drops it at (<ltx>,<lty>). the file is expected to be in whatever format <format> says, and <format> can be "XBM", "XPM", "GIF", "PNG", "JPEG", "PBM", "PGM", "PPM", plus the names specified by the Tgif.ImportFilter# X defaults. if <format> is "TGIF", the file should either be a tgif file. ๐Ÿ–ผ๏ธ

set_xpm_output_version(<version_number>)

sets the XPM version number used when you're outputting in the X11 pixmap format, to <version_number>. <version_number> can take on the values 1 or 3. that's it, that's the whole vibe. โœจ

edit_ini_section(<attr_name>,<title>,<section>,<ini_path>)

this one pops up a dialogbox to edit the section specified by <section> in the file given by the full path <ini_path>. now watch this:

  • if the user hits the OK button in the dialogbox, the section is cleared, the content of the dialogbox gets written back into the file, and "OK" is placed in the attribute specified by <attr_name>.
  • if the user hits the CANCEL button, the file is unmodified, and "CANCEL" is placed in the attribute specified by <attr_name>.

select_from_ini_section(<attr_name>,<title>,<section>,<ini_path>)

brings up a list so you can select an entry from the section specified by <section> in the file at the full path <ini_path>. if nothing is selected, the attribute specified by <attr_name> gets cleared. otherwise, the selected entry is written into the attribute specified by <attr_name>. pick one or get nothing, that's the deal. ๐ŸŽ€

append_line_into_attr(<attr_name>,<string>)

appends the line specified by <string> to the attribute specified by <attr_name>. simple as. ๐Ÿ’–

insert_line_into_attr(<attr_name>,<string>,<line_number>)

inserts the line specified by <string> as the nth line of the attribute specified by <attr_name>, where n is a zero-based index specified by <line_number>. and here's the lil plot twist: n must be at least 1. if n is larger than the number of lines in the attribute, blank lines are automatically inserted to fill the gap. the page said both things, so both things are going in the notes, don't come for me. ๐Ÿ˜ญ

clear_attr(<attr_name>)

clears the attribute value of the attribute specified by <attr_name>, and deletes all other lines of the attribute if the attribute contains multiple lines. full reset energy. ๐Ÿงน

create_text_obj(<abs_x>,<abs_baseline_y>,<string>)

creates a text object at the location (<abs_x>,<abs_baseline_y>) with the text specified by <string>. ๐Ÿฆ‹

create_box_obj(<abs_ltx>,<abs_lty>,<abs_rbx>,<abs_rby>)

creates a rectangle defined by (<abs_ltx>,<abs_lty>) and (<abs_rbx>,<abs_rby>). classic. iconic. rectangular. โœจ

create_corner_oval_obj(<abs_ltx>,<abs_lty>,<abs_rbx>,<abs_rby>)

creates a corner oval defined by (<abs_ltx>,<abs_lty>) and (<abs_rbx>,<abs_rby>).

create_center_oval_obj(<abs_x>,<abs_y>,<radius>)

creates a center oval centered at (<abs_x>,<abs_y>) with the radius specified by <radius>. center girlies stay winning. ๐Ÿ’…

create_edge_oval_obj(<abs_ltx>,<abs_lty>,<abs_rbx>,<abs_rby>)

creates an edge circle defined by (<abs_ltx>,<abs_lty>) and (<abs_rbx>,<abs_rby>). yes it says edge circle even though its sibling says oval, that's just how the family is. ๐Ÿซถ

create_rcbox_obj(<abs_ltx>,<abs_lty>,<abs_rbx>,<abs_rby>)

creates a rounded-corner rectangle defined by (<abs_ltx>,<abs_lty>) and (<abs_rbx>,<abs_rby>). soft edges, hard facts. ๐ŸŽ€

create_arc_obj(<abs_x>,<abs_y>,<radius>,<dir>,<angle1>,<angle2>)

creates an arc centered at (<abs_x>,<abs_y>) with radius, direction, start angle and end angle specified by <radius>, <dir>, <angle1> and <angle2> respectively. and the way these get specified is exactly the same way they're specified in the SpecifyAnArc() command under the CreateObject submenu of the Edit Menu.

  • <dir> can be "+" or "-", where "+" is clockwise.
  • <angle1> and <angle2> are in degrees, with 0 degree at the 12 o'clock position.

create_first_vertex(<abs_x>,<abs_y>)

this one is used in conjunction with the create_next_vertex() and create_poly_obj() commands to create a polyline/open-spline object. it can also be used in conjunction with the create_next_vertex() and create_polygon_obj() commands to create a polygon/closed-spline object. what it actually does: it sets the starting point of the polyline/open-spline object or the polygon/closed-spline object to be at (<abs_x>,<abs_y>). first one on the dance floor. ๐ŸŒŸ

create_next_vertex(<abs_x>,<abs_y>)

same little squad as before: used in conjunction with the create_first_vertex() and create_poly_obj() commands to create a polyline/open-spline object, and it can also be used in conjunction with the create_first_vertex() and create_polygon_obj() commands to create a polygon/closed-spline object. it sets the next vertex of the polyline/open-spline object or the polygon/closed-spline object to be at (<abs_x>,<abs_y>). keep calling it, keep adding points. ๐Ÿ”ฅ

create_poly_obj()

used in conjunction with the create_first_vertex() and create_next_vertex() commands to create a polyline/open-spline object. that's the finisher, bestie โ€” you've been stacking vertices, now you commit. ๐Ÿ’…

create_polygon_obj()

used in conjunction with the create_first_vertex() and create_next_vertex() commands to create a polygon/closed-spline object. same energy, but closed. ๐ŸŽ€

start_create_group_obj()

used in conjunction with the create_group_obj() command to create a grouped object. this command marks the beginning of the group. plant the flag. ๐Ÿšฉ

create_group_obj()

used in conjunction with the start_create_group_obj() command to create a grouped object. this command groups all objects created since the last start_create_group_obj() call into a grouped object. everything since the flag, all together now, no cap. ๐Ÿ‘‘

set_allow_interrupt(<true_or_false>)

if <true_or_false> is FALSE (case-sensitive, so type it exactly like that), this command is used to temporarily disable a user interrupt while tgif is executing internal commands. and if a user interrupt is received while interrupts are disabled, it gets queued, and it will interrupt the execution of internal commands when set_allow_interrupt() is called again with <true_or_false> being TRUE (case-sensitive again, always always). it's giving "hold my call, i'll take it later". ๐Ÿ“ž

select_each_obj_and_exec(<attr_name_to_exec>)

first this command unselects any object that is selected. then it selects each object in the current drawing in turn and executes the internal command specified by the <attr_name_to_exec> attribute. and here's where it gets picky:

  • if this command is executed as a result of a mouse click over an object, only objects in the current page will be scanned for execution.
  • if this command is executed from a script file, objects in every page will be scanned for execution.

edit_attr_in_text_mode(<attr_name>)

when this command is executed, tgif enters the text drawing mode and edits the attribute specified by <attr_name>. glow up in progress. โœ๏ธ

set_file_unsavable()

used to make the current file unsavable. that's the whole thing. chaotic? yes. documented? also yes. ๐Ÿ’€

pstoepsi(<target_eps_path>,<src_ps_path>,<scale>)

this command generates a preview bitmap for the PostScript file in <src_ps_path>, prepends it to <src_ps_path>, and saves the output in <target_eps_path> (<src_ps_path> itself is unmodified, she stays untouched). the only accepted values of <scale> are 1 or 2.

and if the Tgif.ExternalPsToEpsi X default is set to true, this command will simply invoke this externally:

pstoepsi <src_ps_path> <target_eps_path>

when <scale> is 1, and it'll invoke this:

pstoepsi -2x <src_ps_path> <target_eps_path>

when <scale> is 2.

โš ๏ธ this command only works if tgif is running in the interactive (non-batch) mode. batch mode said not today.

objs_bbox_intersect(<obj1_name>,<obj2_name>,<result_attr>)

sets the value of the attribute specified by <result_attr> to "1" if the boundingboxes of the objects named <obj1_name> and <obj2_name> intersect. otherwise it sets that attribute to "0". binary. decisive. we love a clean answer. โœ…

delete_all_attr_from_selected_objs()

deletes all attributes from selected objects.

๐Ÿšจ and the page is literally begging you here: please only use this command when commands are taken from an external file! do not freestyle this one, bestie, i'm serious. ๐Ÿ™ˆ

random_permute_lines_in_attr(<attr_name>)

randomly permutes the lines of an attribute specified by <attr_name>. shuffle button, but for attributes. ๐Ÿ”€


๐Ÿงฎ ARITHMETIC EXPRESSIONS ๐Ÿงฎ

certain internal commands allow arithmetic expressions as arguments. infix notation is used (yes, the normal human way, not the cursed reverse polish way, we're safe ๐Ÿซถ). supported operators and their precedences are listed below:

  • ? โ€” precedence 1 โ€” if-then-else, e.g. <rel> ? <iftrue> : <else>
  • : โ€” precedence 2 โ€” if-then-else, e.g. <rel> ? <iftrue> : <else>
  • || โ€” precedence 3 โ€” logical OR
  • && โ€” precedence 4 โ€” logical AND
  • | โ€” precedence 5 โ€” bit-wise OR
  • ^ โ€” precedence 5 โ€” bit-wise XOR
  • & โ€” precedence 5 โ€” bit-wise AND
  • == โ€” precedence 6 โ€” equal
  • != โ€” precedence 6 โ€” not-equal
  • > โ€” precedence 7 โ€” greater than
  • < โ€” precedence 7 โ€” less than
  • >= โ€” precedence 7 โ€” greater than or equal to
  • <= โ€” precedence 7 โ€” less than or equal to
  • << โ€” precedence 8 โ€” shift left
  • >> โ€” precedence 8 โ€” shift right
  • + โ€” precedence 9 โ€” add
  • - โ€” precedence 9 โ€” subtract
  • * โ€” precedence 10 โ€” multiple
  • / โ€” precedence 10 โ€” divide
  • // โ€” precedence 10 โ€” integer divide
  • % โ€” precedence 10 โ€” mod
  • ! โ€” precedence 11 โ€” logical NOT
  • ~ โ€” precedence 11 โ€” bit-wise invert/NOT
  • ) โ€” precedence 12 โ€” closed parenthesis
  • ( โ€” precedence 13 โ€” open parenthesis
๐Ÿ’… and yes, the parentheses really do have the highest precedences in the list โ€” the closed one is 12, the open one is 13. that's what the page says, so that's what you get. ๐ŸŽ€

๐ŸŒˆ GENERATING IMAGEMAP FILES ๐ŸŒˆ

ok bestie so this whole section is about making NCSA imagemap files and CERN clickable image files. The Tgif.ImageMapFileFormat X default is literally the thing that decides which one you get. And because the two formats are like, cousins โ€” basically the same vibe โ€” we're only gonna talk about how to generate NCSA imagemap files here. Want the NCSA tea? See [3]. Want the CERN clickable image tea? See [4]. ๐Ÿซถ

Set the Tgif.GenerateImageMap X default to "true" to turn imagemap generation on. When you print in the GIF format (peep the BASIC FUNCTIONALITIES section about printing), an XPM file gets generated first โ€” and it gets removed at the end of this whole process, no traces left ๐Ÿ’…. (The value you set in Tgif.InitExportPixelTrim X default is what trims extra pixels. Using these values is basically an escape hatch to fix an idiosyncrasy where tgif cannot figure out exactly how big the whole image is. Not tgif's fault, she's doing her best.)

The XPM version is specified by the Tgif.XPmOutputVersion X default โ€” unless Tgif.UseXPmVersion1ForImageMap X default is set to "true", which forces the XPM1 format, periodt. Then the command specified by Tgif.XpmToGif X default gets executed to convert that XPM file into a GIF (Generic Interchange Format) file, which software like NCSA's Mosaic(1) can use. The file extension for the GIF file is specified by the Tgif.GifFileExtension X default. And together with the GIF file, an imagemap file gets generated with the file extension specified by the Tgif.ImageMapFileExtension X default. The content of the imagemap is generated like this, bestie:

Tgif first looks for a file attribute with attribute name href. The value of that attribute is written as the default URL. If such a file attribute cannot be found, imagemap generation is aborted ๐Ÿ˜ญ. If it is found, then all objects in the file get scanned. For an object that has an attribute named href, the value of the attribute is written as the URL for a method line in the imagemap. And if the object is neither a circle nor a poly/polygon, the rectangle method is used. Simple as that.

Similar mechanism is used when printing in the HTML format, except that a generic HTML file is generated with an imagemap in the Spy Glass Client-side Imagemap format. You can generate a custom HTML file if you specify an HTML export template using SetHTMLExportTemplate() from the File Menu. Details about the template file are described below. ๐Ÿ‘‡


โœจ HTML EXPORT TEMPLATE โœจ

If an HTML export template file is specified with the SetHTMLExportTemplate() from the File Menu, custom HTML files can be generated when printing in the HTML format. The customization is done through the use of variables embedded in the HTML export template file. These variables have the syntax of an HTML character entity โ€” they all start with "&tgv" and end with ";". Here they are, the whole squad:

  • &tgvfilename; โ€” gets replaced by the name of the file (without file extension).
  • &tgvcurnum; โ€” gets replaced by the current page number.
  • &tgvfirstnum; โ€” gets replaced by the first page number (usually 1).
  • &tgvlastnum; โ€” gets replaced by the last page number.
  • &tgvprevnum; โ€” gets replaced by the previous page number (with wrap around).
  • &tgvprevnumnowrap; โ€” gets replaced by the previous page number (with no wrap around).
  • &tgvnextnum; โ€” gets replaced by the next page number (with wrap around).
  • &tgvnextnumnowrap; โ€” gets replaced by the next page number (with no wrap around).
  • &tgvtitle; โ€” gets replaced by the title of the page or of the file.
  • &tgvmapobjs; โ€” gets replaced by the objects (specified as <AREA> tabs) in a client-side image map.

For example, if a template specifies:

<IMG SRC="&tgvfilename;-&tgvcurnum;.gif"
       USEMAP="#p0">
<MAP NAME="p0">
&tgvmapobjs;
<AREA SHAPE="RECT"
       COORDS="0,0,&tgvmapwidth;,&tgvmapheight;"
       HREF="&tgvfilename;-&tgvnextnum;.html">
</MAP>

Exporting using PrintOneFilePerPage() with this template may get (for page 2 of a file name "foo.obj" with 5 pages):

<IMG SRC="foo-2.gif"
       USEMAP="#p0">
<MAP NAME="p0">
<AREA SHAPE="RECT" ...>
 ...
<AREA SHAPE="RECT" ...>
<AREA SHAPE="RECT"
       COORDS="0,0,145,97"
       HREF="foo-3.html">
</MAP>

๐Ÿฆ‹ GENERATING MICROSOFT WINDOWS EPSI FILES ๐Ÿฆ‹

ngl, some Microsoft Windows (TM) applications simply do not understand standard PostScript %%BeginPreview, %%EndImage, and %%EndPreview comments. Rude, but okay. This section describes how to generate an EPSI file that they do understand. ๐Ÿ’–

This feature is invoked when the current print format is TiffEPSI. In this case, the generated EPSI file will contain 30 bytes of binary information at the beginning of the file, plus a TIFF image (also binary) at the end of the file. This file also will not contain the %%BeginPreview, %%EndImage, and %%EndPreview comments. A file in this format is normally not considered to be a PostScript file except under Windows. ๐Ÿ‘‘

When this feature is enabled, tgif generates a normal EPSI file first, then dumps the current content of the file into an X11 bitmap file. The command specified in Tgif.XbmToTiff is executed to generate a TIFF image, which is then appended at the end of the EPSI file.


๐Ÿ”’ LOCKING OBJECTS ๐Ÿ”’

Objects can be locked and unlocked using #< and #> keyboard commands. When a selected object is locked, it's shown with gray handles (mysterious, iconic). A locked object cannot be moved, stretched, flipped, or rotated โ€” however, its properties like fill pattern, width, etc., can still be changed. Locked objects can also be deleted. When a locked object is grouped with other objects, the resulting grouped object is also locked. A locked object can be used as an anchor to align other objects โ€” however, DistributeObjs() command will fail if any objects are locked. And locked objects do not participate in any operations in the select vertex mode. no cap.


โ†ฉ๏ธ UNDO/REDO โ†ช๏ธ

Most operations can be undone and redone, thank god ๐Ÿ™. The Tgif.HistoryDepth X default controls the size of the undo buffer. If it's set to -1, then the undo buffer's size is infinite โ€” main character energy fr.

The undo buffer is flushed when:

  • the New() or Open() commands are executed (from the File Menu),
  • the FlushUndoBuffer() command is executed from the Edit Menu, or
  • Pop() is executed from a .sym file.

If a private colormap is used (which happens automatically when new colors can not be allocated from the default colormap), executing FlushUndoBuffer() will attempt to reset the colormap (if the -DDONT_FREE_COLORMAP compile option is not used).


๐ŸŒธ DOMAINS ๐ŸŒธ

A domain is a collection of library symbols suitable for instantiations. A library is implemented as a directory of .sym files, and therefore, a domain is implemented as a search path. If there are symbols with the same file name that live in different directories specified in the search path, then the one closer to the front of the search path will be made available for the user to instantiate. First come, first served bestie.

The number of domains is specified by the MaxDomains X default, and the names of the domains are specified by the DomainPath# X default. The library search paths are specified by csh environment variables. See the section on X DEFAULTS for more details. ๐Ÿ‘€

Domain information can also be loaded into the ~/.Tgif/domain.ini file by setting Tgif.DomainInIni to true and selecting Reload Domain Info From X from the Domain submenu of the File Menu.


๐ŸŽ€ SELECTING A NAME FROM A POPUP WINDOW ๐ŸŽ€

When you're selecting a file name, a symbol name, or a domain name, tgif pops up a window with appropriate names for you to choose from. You can use mouse clicks to select an entry, obviously. Key strokes can also be used to specify the desired name โ€” however, tgif attempts to match the key strokes with names in the selection on the fly, so if a match can not be found, the key strokes are just ignored. ๐Ÿ’…

Here's the key bindings, memorize them:

  • ^n, ^j, or the DownArrow key advances the selection down by 1 entry.
  • ^p, ^k, or the UpArrow key advances the selection up by 1 entry.
  • ^f, ^d, or the DownArrow key with <Control> key held down advances the selection down by 10 entries.
  • ^b, ^u, or the UpArrow key with <Control> key held down advances the selection up by 10 entries.
  • '$' will select the last entry.
  • '^' will select the first entry.
  • ^w or ^y un-select the selected entry.

If the selected entry is a directory, hitting <CR> will change directory; if it's not, hitting <CR> finishes the selection process and the selected entry is returned. โœจ

In selecting file names to open or import, typing '/' is interpreted as going to the root directory or specifying an URL. At this point, the automatic matching of key strokes is temporarily disabled until either a <TAB> or a <CR> is pressed. Also, clicking the middle mouse button in the file name area pastes from the clipboard.

The automatic appending of index.obj or .obj (introduced in version 2.16) became obsolete, and an URL is never modified.

The current selection is displayed near the top of the popup window.

Back-space should be used with caution, because it might change the current directory to the parent directory. ๐Ÿ˜ญ

๐Ÿ’œ IMPORTING EPS FILES ๐Ÿ’œ

Encapsulated PostScript (EPS) files can be imported using the #( keyboard command. If the EPS file has a preview bitmap (which can be generated using the pstoepsi tool), tgif will display it. (HideBit/Pixmap() from the Layout Menu can be used to disable the displaying of bitmap/pixmaps.)

When the EPS object is saved in a .obj or .sym file, neither the preview bitmap nor the PostScript content of the EPS file is saved. Therefore, when printing such a file (either from tgif or using prtgif), the EPS file must be present at the same place from which it was originally imported. So like, don't move it, bestie. ๐Ÿ™ˆ

๐Ÿ’– IMPORTING LATEX ๐Ÿ’–

โœจ Short Version โœจ

okay bestie so you can literally import a LaTeX equation straight into a tgif object, it's giving โœจmagicโœจ. When you pick Instantiate from the Special Menu (or just press <Cntrl>i), you should see eq4.sym sitting there. Double-click it and tgif will be like "bestie where do you want this" and ask you to click on the drawing area to place it. Once it's placed, congrats ๐ŸŽ‰ you have instantiated an eq4 symbol, and that instantiation is called an eq4 object (or the LaTeX equation object). Now slip into edit text mode (e.g. press <Cntrl>w) and click anywhere inside the eq= attribute (that's the text of the equation, iykyk) to edit the equation. Then bounce back to select mode (e.g. press <meta>k) and double-click on the eq= attribute to run latex on it and import the resulting EPSI file. slay ๐Ÿ’…

If your equation is a whole novel, no worries โ€” you can right-click on the equation object, select Edit Attribute in Editor, pick eq=, and edit the equation in an editor of your choice. You can use the Tgif.Editor X default to select your editor, for example:

Tgif.Editor:     xemacs -title '%s' '%s'

To declutter your screen (vibe check passed โœ…), you may select the eq4 object and use the shortcut key T to hide the eq= attribute. Type T again to make it visible.

Once you import the EPSI file, you may use the left mouse button to drag either the eq= attribute or the imported graphic, and the other will follow. ๐Ÿซถ If you hold the control key down, you can drag the eq= attribute separately.

๐Ÿ” Details ๐Ÿ”

Since version 4.1.16, the standard distribution of tgif comes with four LaTeX equation symbol files:

  • eq4.sym
  • eq4-2x.sym
  • eq4-ps2epsi.sym
  • eq4-epstool.sym

The Debian package installs these files in /usr/share/tgif/latex, and initializes tgif with one domain (number 0) called LaTeX. When tgif starts, the default domain should be domain number 0, and tgif should look for *.sym files first in the current directory, then in ~/.tgif/latex, then in /usr/share/tgif/latex. ๐Ÿ‘‘

In order to use eq4.sym, in addition to latex and dvips, you need:

  • pstoepsi โ€” to convert a PS (PostScript) file generated by dvips to an EPSI (encapsulated PostScript file with a preview bitmap) file
  • netpbm โ€” used by pstoepsi to convert a PBM file to a preview bitmap for the final EPSI file
  • ghostscript โ€” used by pstoepsi to render a PS file into a PBM file

Once you have these tools properly installed, you can simply instantiate eq4.sym and change the value of the eq= attribute.

Just double-click the equation object and tgif will run the following commands:

latex tmpfile
dvips -N -n 1 -o tmpfile.ps tmpfile
pstoepsi tmpfile.ps tmpfile.eps

where tmpfile is a temporary file generated by tgif (usually in /tmp) and the file name starts with Tgif.

This should work if everything is installed properly. In case it does not work, you will get an error messagebox. ๐Ÿšจ Do not close the box. Change directory into /tmp and look for the latest file that starts with Tgif and ends in .tex and copy it. Then run the above commands manually to debug the problem. For example, you can do:

cd /tmp
ls -lrt Tgif*

-rw-r--r--   1 william     230 Mar 22 11:27 TgifmTaOdC.tex
-rw-r--r--   1 william    4636 Mar 22 11:27 TgifmTaOdC.log
-rw-r--r--   1 william     324 Mar 22 11:27 TgifmTaOdC.dvi
-rw-r--r--   1 william       8 Mar 22 11:27 TgifmTaOdC.aux
-rw-r--r--   1 william   18561 Mar 22 11:27 TgifmTaOdC.ps
-rw-r--r--   1 william   18561 Mar 22 11:27 TgifmTaOdC.eps

(Please note that in the above listing, TgifmTaOdC.ps and TgifmTaOdC.eps have the same file size, this means that pstoepsi did not work.) ๐Ÿ’€

cp TgifmTaOdC.tex foo.tex
latex foo
dvips -N -n 1 -o foo.ps foo
pstoepsi foo.ps foo.eps
more foo.eps

At this point, you should see that the first few lines of foo.eps look like:

%!PS-Adobe-2.0 EPSF-1.2
%%BoundingBox: 258 634 354 653
%%BeginPreview: 97 20 1 20
% 00000000000000000000000e00
% ...
% 00000000000000000003c00000
%%EndImage
%%EndPreview
...

These lines are added by pstoepsi. The numbers in the %%BoundingBox: and %%BeginPreview: depends on your equation and the PS-Adobe and EPSF versions in the first line may vary depending on your setup.

If you get errors when you run latex, dvips, or pstoepsi manually, there is something wrong with the setup of these tools. If they all do the right thing but tgif still shows errors, please send e-mail to me! ๐Ÿ“ง

eq4-2x.sym can produce a higher (2x) resolution preview bitmap, but you will need the special netpbm-20may1999 version of netpbm. It may not work with a newer version of netpbm. eq4-ps2epsi.sym is not recommended. eq4-epstool.sym is like eq4.sym but uses epstool instead.


๐ŸŽ€ ADDITIONAL FONTS ๐ŸŽ€

In addition to the Times, Courier, Helvetica, NewCentury, and Symbol fonts, additional fonts can be specified using the Tgif.AdditionalFonts X default. (The default screen fonts can also be replaced, please see Tgif.HasAlternateDefaultFonts in the X DEFAULTS section for more details.) Each additional font requires 4 parts, one for each font style (in the order of Roman, Bold, Italic, and BoldItalic). Each part contains 3 strings. The first string specifies the family, weight, slant, and width of the font (please see the man pages for xfontsel(1) for more details; also there is a second form which is described below). The second string specifies the registry and encoding of the font (see xfontsel(1) again). (One can use xlsfonts(1) to see what fonts are available and pick out the just mentioned two strings from the output.) The third string specifies the PostScript font name.

For example, if one wants to use the X Lucida font to represent the PostScript ZapfChancery-MediumItalic font, one can set Tgif.AdditionalFonts as follows:

Tgif.AdditionalFonts: \n\
        lucida-medium-r-normal \n\
        iso8859-1 \n\
        ZapfChancery-MediumItalic \n\
        \n\
        lucida-demibold-r-normal \n\
        iso8859-1 \n\
        ZapfChancery-MediumItalic \n\
        \n\
        lucida-medium-i-normal \n\
        iso8859-1 \n\
        ZapfChancery-MediumItalic \n\
        \n\
        lucida-demibold-i-normal \n\
        iso8859-1 \n\
        ZapfChancery-MediumItalic

The above maps all four font styles of the Lucida font to the ZapfChancery-MediumItalic font (similar to how Symbol font is handled). ๐Ÿฆ‹

The first string can also be specified in a second form which is identified by having "%d" as part of the string. For example, one can use "lucidasans-%d" as the first string. In this case, the actual X font used will be the specified string with "%d" replaced by the font size. The encoding string (second string) is ignored (but must be present). The font name prefix (please see Tgif.FontNamePrefix entry in the X DEFAULTS section) is also ignored. โœจ

๐ŸŽ€ POSTSCRIPT CHARACTER ENCODING FOR INTERNATINOAL CHARACTERS ๐ŸŽ€

okay bestie so like, sometimes you need different encodings of the same PostScript font for characters with character codes between 161 and 255 (inclusive) ๐Ÿ’… fr. There's two ways to pull this off:

  • one is Tgif.AdditionalDontReencode (and Tgif.DontReencode)
  • the other is Tgif.PSFontNeedCharSubs

the โœจdifferenceโœจ is that with Tgif.AdditionalDontReencode, a PostScript font's encoding is skipped. With Tgif.PSFontNeedCharSubs, characters in a PostScript font can be given specific encoding. no cap, that's the whole vibe check.

In both cases, there is a need to introduce fake font names (place holders). For example,

Tgif.AdditionalFonts: \n\
        utopia-medium-r-normal \n\
        adobe-fontspecific \n\
        UtopiaTmp-Regular \n\
        \n\
        utopia-bold-r-normal \n\
        adobe-fontspecific \n\
        UtopiaTmp-Bold \n\
        \n\
        utopia-medium-i-normal \n\
        adobe-fontspecific \n\
        UtopiaTmp-Italic \n\
        \n\
        utopia-bold-i-normal \n\
        adobe-fontspecific \n\
        UtopiaTmp-BoldItalic
Tgif.PSFontAliases: \n\
        UtopiaTmp-Regular=Utopia-Regular \n\
        UtopiaTmp-Bold=Utopia-Bold \n\
        UtopiaTmp-Italic=Utopia-Italic \n\
        UtopiaTmp-BoldItalic=Utopia-BoldItalic

In the above example, 4 fake PostScript font names are created (all have a common UtopiaTmp prefix ๐Ÿซถ). The encoding for these fonts is adobe-fontspecific, according the X11 fonts being used. Tgif.PSFontAliases maps the fake PostScript font names to the corresponding real PostScript font names. (If Tgif.PSFontAliases is missing, non-existent PostScript font names such as UtopiaTmp-Regular will appear in a PostScript file. ๐Ÿ’€ not the vibe.)

To skip a PostScript font's encoding, one can use the Tgif.AdditionalDontReencode X default. For example, if one specifies:

Tgif.AdditionalDontReencode: UtopiaTmp

characters with character codes between 161 and 255 (inclusive) will not be encoded with ISO-Latin-1 character names. For a list of characters names that are ISO-Latin-1 encoded, please see <URL:http://bourbon.usc.edu/tgif/faq/charencode.html#iso8859-1>. ๐ŸŒธ

To substitute characters in a PostScript font with specific encoding, one can use the Tgif.PSFontNeedCharSubs and Tgif.PSCharSubs_* X defaults. (You still need Tgif.AdditionalFonts and Tgif.PSFontAliases setup as above, bestie, don't skip steps ๐Ÿ™ˆ.) Here is an example:

Tgif.PSFontNeedCharSubs: \n\
        Utopia-Regular=Foo \n\
        Utopia-Bold=Foo \n\
        Utopia-Italic=Foo \n\
        Utopia-BoldItalic=Foo
Tgif.PSCharSubs_Foo: \n\
        exclamdown/Aogonek \n\
        AE/Cacute \n\
        ecircumflex/eogonek

In the above example, Tgif.PSFontNeedCharSubs specified a list of fake PostScript font names that requires character substitutions and their corresponding TOKEN names. For a fake PostScript font name that maps to TOKEN, the list of characters to be substituted is specified in the Tgif.PSCharSubs_TOKEN X default. The format for Tgif.PSCharSubs_TOKEN is a list of OLDCHARCODE/NEWCHARNAME strings where OLDCHARCODE is a character code in decimal or octal format and NEWCHARNAME must be the name of a PostScript character. In the above example, Foo was used as the TOKEN name. In real use, something like iso8895-2 may be more appropriate for a TOKEN name. Since decimal or octal codes are allowed, the following is equivalent to the above:

Tgif.PSFontNeedCharSubs: \n\
        Utopia-Regular=iso8859-2 \n\
        Utopia-Bold=iso8859-2 \n\
        Utopia-Italic=iso8859-2 \n\
        Utopia-BoldItalic=iso8859-2
Tgif.PSCharSubs_iso8859-2: \n\
        161/Aogonek \n\
        8#306/Cacute \n\
        8#312/eogonek
Please note that substitution only occurs for characters with character codes between 161 and 255 (inclusive). ๐Ÿซถ

For more information, please see <URL:http://bourbon.usc.edu/tgif/faq/charencode.html#charsubs>. โญ


๐ŸŒˆ SQUARE DOUBLE BYTE FONTS ๐ŸŒˆ

Starting with version 4.0 of tgif, double-byte fonts are supported ๐Ÿ”ฅ. But only double-fonts where every character has the same width and height are supported. Double-byte fonts is specified using the Tgif.SquareDoubleByteFonts X default. The format of this X default is similar to that of the Tgif.AdditionalFonts X default described in the ADDITIONAL FONTS section above with differences described here. Each double-byte font requires 4 parts, one for each font style (in the order of Roman, Bold, Italic, and BoldItalic). Each part contains 3 strings:

  1. The first string specifies the name of the font. It must contain a "%d" as part of the string. The actual X font used will be the specified string with "%d" replaced by the font size.
  2. The second string can be either "*", "H", or "V". When it is the "V" string, each character is rotated 90 degrees counter-clockwise. Otherwise, the characters are not rotated.
  3. The third string specifies the PostScript font name.

Using input methods (specified by the Tgif.DoubleByteInputMethod X default) one can mix english (single-byte) substrings within a double-byte string. The font to use for the english substring is specified by the Tgif.DefaultSingleByteFont X default. ๐Ÿ’–

For example, if one wants to use the X Song Ti font to represent PostScript GB-Song-Regular font, one can set Tgif.SquareDoubleByteFonts as follows:

Tgif.DefaultSingleByteFont: Helvetica
Tgif.GBShowFontChar: 271372 Tgif.GBConvFromUTF8: iconv -f utf8 -t gb2312
Tgif.GBUConvToUTF8: iconv -f gb2312 -t utf8
Tgif.SquareDoubleByteFonts: \n\
       -isas-song ti-*-*-*--%d-*-*-*-*-*-gb2312.1980-0 \n\
               * \n\
               GB-Song-Regular \n\
       \n\
       -isas-song ti-*-*-*--%d-*-*-*-*-*-gb2312.1980-0 \n\
               * \n\
               GB-Song-Regular \n\
       \n\
       -isas-song ti-*-*-*--%d-*-*-*-*-*-gb2312.1980-0 \n\
               * \n\
               GB-Song-Regular \n\
       \n\
       -isas-song ti-*-*-*--%d-*-*-*-*-*-gb2312.1980-0 \n\
               * \n\
               GB-Song-Regular

In the above example, the Song Ti font doesn't have styles such as italic and bold, so all four parts are identical โ€” iconic honestly, she said "I contain multitudes (but they're all the same)". The Tgif.GBShowFontChar X default specifies a double-byte octal character to be used to represent this font in the Choice Window when this font is selected. The Tgif.GBUConvFromUTF8 X default specifies a command to run when an UTF8-encoded string is to be pasted into a text object in the GB font. The Tgif.GBUConvToUTF8 X default specifies a command to run in a copy operation to convert a selected string (in GB font) to the UTF8 format then copied to the clipboard. ๐ŸŽ€

Below is another example of using the X JIS fonts to represent PostScript Ryumin-Light-EUC-H and Ryumin-Light-EUC-V fonts as follows:

Tgif.RyuminShowFontChar: 244242
Tgif.SquareDoubleByteFonts: \n\
       -jis-fixed-*-*-*--%d-*-*-*-*-*-jisx0208.1983-* \n\
               H \n\
               Ryumin-Light-EUC-H \n\
       -jis-fixed-*-*-*--%d-*-*-*-*-*-jisx0208.1983-* \n\
               H \n\
               Ryumin-Light-EUC-H \n\
       -jis-fixed-*-*-*--%d-*-*-*-*-*-jisx0208.1983-* \n\
               H \n\
               Ryumin-Light-EUC-H \n\
       -jis-fixed-*-*-*--%d-*-*-*-*-*-jisx0208.1983-* \n\
               H \n\
               Ryumin-Light-EUC-H \n\
       \n\
       -jis-fixed-*-*-*--%d-*-*-*-*-*-jisx0208.1983-* \n\
               V \n\
               Ryumin-Light-EUC-V \n\
       -jis-fixed-*-*-*--%d-*-*-*-*-*-jisx0208.1983-* \n\
               V \n\
               Ryumin-Light-EUC-V \n\
       -jis-fixed-*-*-*--%d-*-*-*-*-*-jisx0208.1983-* \n\
               V \n\
               Ryumin-Light-EUC-V \n\
       -jis-fixed-*-*-*--%d-*-*-*-*-*-jisx0208.1983-* \n\
               V \n\
               Ryumin-Light-EUC-V

๐Ÿฆ‹ MULTIPAGE DRAWING ๐Ÿฆ‹

An object file can contain multiple pages ๐Ÿซถ. Two layout modes, stacked and tiled, for a multipage drawing are supported:

  • In stacked layout mode, pages are considered to be stacked on top of each other, and therefore, an object can only appear on one page.
  • In tiled layout mode, pages are tiled to form a large logical page; in this case, an object can exist on several physical pages simultaneously.

Swiching between the two modes are considered rare events and can not be undone ๐Ÿ˜ญ. Tgif does not allow switching from the tiled layout mode to the stacked mode when there exists an object that spans physical page boundaries because it can not decide which physical page the object belongs. (she's not being difficult, she genuinely cannot tell ๐Ÿ’€)

Page numbers are supported through the use of page numbering objects. A page number objecting is an object that contains an attribute whose name is !PAGE_NUM (the name is case-sensitive) and the name part of that attribute is not shown (hiding an attribute name can be achieved by using the Move/JustifyAttr() command under the Attribute submenu of the Special Menu). The value of the attribute determines how the page number is printed. โœจ

  • If the value of the attribute contains a !(STACKED_PAGE_NUM) substring, that part of the substring will be replaced by the page number if the page layout mode is stacked. If the page layout mode is tiled, the string will be printed out as is.
  • If the value of the attribute contains a !(STACKED_NUM_PAGES) substring, that part of the substring will be replaced by the number of pages if the page layout mode is stacked.
  • If the value of the attribute contains a !(TILED_PAGE_ROW) or !(TILED_PAGE_COL) substring, that part of the substring will be replaced by the row number or the column number of the physical page if the page layout mode is tiled. ๐ŸŒˆ

โœจ SPECIAL ATTRIBUTES โœจ

tgif has a lil collection of special attributes that it actually recognizes and treats differently from all the regular ones. They're all listed right here, and heads up bestie โ€” they are all case-sensitive, so Auto_Center_Attr is not gonna do the thing. ๐Ÿ’…

  • !PAGE_NUM=<page_number> โ€” this one sets the page numbers in a multipage drawing. The details live in the MULTIPAGE DRAWING section, so go peek there for the full tea.
  • auto_center_attr โ€” okay so if an attribute has an empty name and its value is auto_center_attr, then every visible attribute of the owner object gets automatically centered relative to the bounding box of that owner object. Lowkey it doesn't really make sense to have more than one visible attribute like this because they'd just overlap each other ๐Ÿ˜ญ. It's super handy for making simple flowchart elements though.
  • unmakeiconic_on_instantiate โ€” if a symbol object's attribute has an empty attribute name and its value is unmakeiconic_on_instantiate, then when the symbol gets instantiated, these three things happen to the just-instantiated icon object: 1) the UnMakeIconic() command from the Special Menu, 2) the UnGroup() command from the Arrange Menu, and 3) the unmakeiconic_on_instantiate text object gets removed. Perfect for building simple flowchart segments, fr fr.
  • unmakeiconic_on_instantiate_delete_attrs โ€” same empty-name situation, value is unmakeiconic_on_instantiate_delete_attrs, and when the symbol is instantiated these happen on the just-instantiated icon object: 1) UnMakeIconic() from the Special Menu, 2) delete all attributes from this object, and 3) UnGroup() from the Arrange Menu. This one's the move for stuffing a group of "useful" objects into a symbol object. ๐Ÿ‘‘
  • retracted_arrows โ€” if an attribute's name is empty and the value is retracted_arrows, and we're talking about a polyline or open-spline object with more than 2 vertices, then the arrows of the spline object get retracted by one vertex.
  • auto_retracted_arrows โ€” super similar to retracted_arrows up there โฌ†๏ธ except the object has to be an interpolated open-spline with only one arrow head. The spline object is forced to have 3 vertices, and the middle vertex gets automatically adjusted whenever an endpoint is moved. The way it just... does that. Iconic. โœจ
  • auto_exec=<internal_command> โ€” if a file attribute like this exists, the value gets executed when the file is opened. Small caveat: not when the file is opened as a result of executing the hyperjump_then_exec() internal command.
  • edit_attrs_in_context_menu=... โ€” if an object has an attribute named edit_attrs_in_context_menu, then the values of this attribute (starting from the 2nd line and separated by linebreaks) get treated as attribute names. Those named attributes will show up in the Edit Attribute In Editor submenu of the Context Menu. For example, if an object has these attributes:
edit_attrs_in_context_menu=
       x
       y
       z
w=greetings
x=hello
y=world
z=how are you
good-bye

then the Edit Attribute In Editor submenu of the Context Menu will only show "x=hello", "y=world", and "z=how are you". No w, no good-bye, not invited to the party ๐Ÿ™ˆ.


๐Ÿ“Š EXPORT TO TABLE ๐Ÿ“Š

When you pick the ExportToTable() command from the Table submenu of the Special Menu, certain attributes of the selected objects get written into a user-specified output file. And the format? Chef's kiss ๐ŸŽ€ โ€” it's designed to be easily imported by a spreadsheet program, or used by the MergeWithTable() command described in the next section.

An output file contains columns of strings. Two columns are separated by a single <TAB> character. The first row of an output file holds the column names, and every other row holds values.

The names of the attributes to be written are specified by the file attribute named TABLE_ATTRS (which is written as !.TABLE_ATTRS here). The value of the TABLE_ATTRS file attribute is a list of comma-separated attribute names. When ExportToTable() runs, the attribute names specified by !.TABLE_ATTRS are written to the output file first. Then, for each selected object, every one of its attributes that appears in the list specified by !.TABLE_ATTRS gets written to the output file in one line. And if an object has no attributes that match the spec? Then no corresponding line is generated. Simple as that. ๐Ÿ’…


๐Ÿงฉ MERGE WITH TABLE ๐Ÿงฉ

When you select the MergeWithTable() command from the Table submenu of the Special Menu, a selected object gets merged (aka mail-merged, if you're a PC person) with a table (data) file โ€” same format as the output file from the previous section โ€” to generate a brand new multipage drawing with the stacked page layout mode. New drawing, who dis. ๐ŸŒˆ

The selected object carries the formatting information, and it also acts as a template that gets replicated for each data row in the table file. If an attribute of the replica matches a column name of the table, that attribute's value gets set to the value in the table file. The replicas are tiled horizontally first.

Eight attributes must be specified in the template object. They are all case-sensitive. The ones that measure distances can be specified in inches ("in"), centi-meters ("cm"), or pixels (if no units are specified).

  • PAPER_WIDTH โ€” this specifies the width of the paper.
  • PAPER_HEIGHT โ€” this specifies the height of the paper.
  • LEFT_MARGIN โ€” this specifies the distance to the left edge of the paper.
  • TOP_MARGIN โ€” this specifies the distance to the top edge of the paper.
  • H_PITCH โ€” this specifies the distance between the left edges of the replicas.
  • V_PITCH โ€” this specifies the distance between the top edges of the replicas.
  • NUM_COLS โ€” this specifies the number of replicas to tile horizontally before moving down to the next row.
  • NUM_ROWS โ€” this specifies the number of replicas to tile vertically before moving to the next page.

After each replica is generated, filled with the data from the table file, and placed, its attribute named exec is executed โ€” unless an attribute named EXEC_AFTER_MERGE is specified, in which case the attribute named by the EXEC_AFTER_MERGE attribute gets executed instead. If there is no attribute named by the EXEC_AFTER_MERGE attribute, nothing is executed. (Check the INTERNAL COMMANDS section for the deets on command execution.) You can use the exec command to construct other attributes from the attributes associated with the data table, which is honestly so clever.

If there's an attribute whose name is empty and whose value is the string USER_PLACEMENT, then the user will be asked to place the replica (the object name will be shown in the Status Window while the object is being placed). In this case, the 8 placement-related attributes up there get ignored. Ignored!! ๐Ÿ’€

If there's an attribute whose name is empty and whose value is the string STRIP_DOUBLE_QUOTES, then data fields surrounded by double-quotes get stripped.


๐ŸŒ MIME TYPES AND MAILCAPS ๐ŸŒ

When a URL names an HTTP server, that HTTP server sends the Content-type of the URL, along with the remote file referenced by the URL, to tgif. The Content-type carries info like the type/subtype of the file plus some optional fields. If the file is not a tgif file, here's the mechanism used to view it.

First, the X defaults get looked up to see if there's an external viewer specified for the file. Peep Tgif.@@@Viewer in the X DEFAULTS section below for the details. If there's no match, the type/subtype gets matched against entries in the MIME-types file. The default MIME-types file is .mime.types in the user's home directory. See Tgif.MimeTypesFile in the X DEFAULTS section for how to override that default. The first field in each line of the MIME-types file specifies the type/subtype information. If there's a type/subtype match in the MIME-types files, then the MailCap files get consulted, like this:

A line in a MailCap file is made of fields separated by semi-colons. The first field specifies the type/subtype, and the second field specifies a view command for viewing a file that matches that type/subtype. For tgif, the view command must contain a single %s substring to be replaced by the local copy of the URL. Only the %t and the %{} optional fields are supported by tgif. The multipart MIME-type is not supported. The type/subtype information of the remote file gets matched against the MailCap files. If a match is found, the corresponding view command is executed. If no match is found, but the type of the remote file is either application, audio, image, or video, the file is saved and no external viewer is launched. Otherwise, the remote file is assumed to be pure text, and tgif will create a text object to view the text. ๐Ÿ“

The MailCap files are the (colon-separated) files specified by the MAILCAP environment variable (if it's defined). If MAILCAP is not defined, the .mailcap file in the user's home directory is used.

Fun facts for the nerds ๐Ÿงš: MIME is the Multipurpose Internet Mail Extensions specified in RFC1521, and MAILCAP is specified in RFC1524.

๐Ÿ—๏ธ HOW TO MAKE A BUILDING-BLOCK OBJECT (SYMBOL FILE) ๐Ÿ—๏ธ

Here are the steps for defining a building-block object, to be used in a hierarchical design. Grab a snack, we're doing this. ๐Ÿ“

  1. Draw the representation part of the building-block object. Group everything together. Select this grouped object.
  2. Popup the main menu with the middle mouse button; select Special''. Select MakeSymbolic'' from the next popup menu. The selected object becomes a symbol and gets a dashed boundary. โœจ
  3. Type in attributes as individual text strings. Select the symbol object and all the text strings to be attached to the symbol. Type #a (for Attach) to attach attributes to the symbol.
  4. (This step is optional.) Build the definition part of the building-block object. Look at the flip-flop.sym'' file for an example. To look at that file, first, instantiate a flip-flop'' by typing ^i (for Instantiate). Select the flip-flop from the popup window; place the flip-flop; select the flip-flop and type #v (for Push) to see the symbol file.
  5. Save and name the file. If the current library path contains the current directory (or .), the symbol just built should be instantiatable by typing ^i. ๐ŸŽ€

๐Ÿฆ‹ X11 PIXMAP (XPM) FORMATS ๐Ÿฆ‹

okay bestie, listen โ€” tgif can only import X11 pixmaps that satisfy the constraints we're about to spill, so no freestyling here ๐Ÿ’…

The format of the X11 pixmap must be either 1 (XPM1) or 3 (XPM3). And only a subset of the XPM3 format is supported, namely: the key field for the color specification must be 'c' (for color visuals).

Tools that generate XPM1 format files (they might have been upgraded to support XPM3): pbmplus (or netpbm), which is a set of bitmap and pixmap conversion freeware (together with xv, the colors for pixmap objects can be manipulated), and xgrabsc, another freeware. Also, xloadimage can display XPM1 files. Tools that can generate XPM3 format files are, for example, xsnap(1) and sxpm(1).

For each color specified in the color string, a color cell is allocated. If the allocation fails, the current color will be used for that color string. If the first color character is a back-quote (`) or a space, then the corresponding color is substituted with the background color of the tgif window if the Tgif.GuessXPmBgColor X default is set to true. (This design choice is made because the pixmap will then look right on both regular and reverse video. iconic reasoning tbh ๐Ÿซถ)

The following is an example of a very small pixmap file (in XPM1 format):

#define arrow_format 1
#define arrow_width 5
#define arrow_height 3
#define arrow_ncolors 3
#define arrow_chars_per_pixel 1
static char *arrow_colors[] = {
   "`", "Black",
   "a", "red",
   "b", "yellow"
};
static char *arrow_pixels[] = {
"`a```",
"aabbb",
"`a```"
};

๐ŸŒธ LATEX FIGURE FORMATS ๐ŸŒธ

Here we show how to make a figure for a LaTeX file โ€” first with the \psfig (or \epsf) special construct, then with the psfile special construct. (The author does not recommend the psfile construct. noted, bestie ๐Ÿ™ˆ) An example of both can be found in example.tex which is included with the tgif distribution.

โœจ the \psfig / \epsf way โœจ

To print a tgif file to be included in a LaTeX document with the \psfig or \epsf special construct (files generated will be in the Encapsulated PostScript format), first select LaTeX format in the panel window (click the left mouse button on the laser printer icon ๐Ÿ–จ๏ธ), then type ^p to generate the Encapsulated PostScript file.

If the file name is an-sr-flip-flop.obj, then the LaTeX figure file generated will be named an-sr-flip-flop.eps. This file can be included in a LaTeX document as follows:

\input{psfig}
\begin{figure*}[htb]
\centerline{\psfig{figure=an-sr-flip-flop.eps}}
\caption{An SR flip-flop.  \label{fig:an-sr-flip-flop}}
\end{figure*}

An alternative way is to use the \epsf construct as follows:

\input{epsf}
\begin{figure*}[htb]
\centerline{\epsffile{an-sr-flip-flop.eps}}
\caption{An SR flip-flop.  \label{fig:an-sr-flip-flop}}
\end{figure*}

The \centerline command above centers the picture. If one has multiple tgif figures in one's LaTeX document, one only have to include the psfig macro (\input{psfig} or \input{epsf}) once, right after the \begin{document} statement. one and done, slay โœจ

๐Ÿ’ซ the psfile way ๐Ÿ’ซ

If Encapsulated PostScript is not available, the psfile special construct can be used as described here. In this case, since LaTeX doesn't know where the bounding box of the drawing is, it takes some practice to get this just right. Here is something that seems to work:

First, center the picture on the page (e.g., the width of a portrait style page is 8.5 inch, so the center of the page is at the 4.25 inch mark), and make the top object in the picture about 1/4 inch away from the top of the page. Select the LaTeX format in the panel window, then print in the LaTeX format. As with the psfig construct, a file with the .eps extension will be generated. This file can be included in a LaTeX document as follows:

\begin{figure*}[htb]
\special{psfile="an-sr-flip-flop.eps" hoffset=-40}
\rule{0in}{1.1in}
\caption{An SR flip-flop.  \label{fig:an-sr-flip-flop}}
\end{figure*}

The \rule{0in}{1.1in} above specifies an invisible box of 1.1 inches high, which is the total height of the picture in an-sr-flip-flop.


๐Ÿ”Œ CONNECTING OBJECTS ๐Ÿ”Œ

In the world of E-CAD, an icon object can represent an electronic component and a line object can represent a connection between a pair of pins of two electronic components. When a component moves, the endpoint of a wire connecting to the component will also move with the component. Tgif simulates these functionalities in a limited fashion. (limited fashionโ€ฆ it's giving "we tried" ๐Ÿ’€ but it works!)

In tgif, a connection is represented by matching signal names. A wire is defined as a polyline object having a type=tgWire attribute and an attribute named signal_name. The definition of a pin is more complicated โ€” it's described in the next paragraph. If two pins have identical values for the signal_name attribute, they are considered to be connected (they do not have to be visually connected by a wire). ๐Ÿ‘‘

A pin object must have a type=port attribute and attributes named signal_name and name. But not all objects having such attributes are pins. In addition, a pin object must be either:

  1. a top-level symbol or an icon object

or:

  1. an immediate subobject of a owner symbol or icon object. or:
  2. an immediate subobject of a owner grouped object which has a type=tgBroadcastWire attribute.

In (2) above, the owner object must also have an attribute named name and must not be a subobject of another symbol or icon object. If the owner object is a subobject of a grouped object, the name attributes of the grouped object will be ignored.

In (3) above, that grouped object can be created using the ConnectPortsToBroadcastWire() command in the PortsAndSignals submenu of the Special Menu when a polyline object and some floating port objects are selected.

A pin object can have a connected view and a disconnected view. A connected view is a subobject with a view=conn,FILL,PEN attribute and a disconnected view is a subobject with a view=disconn,FILL,PEN attribute; FILL and PEN are numeric values between 0 and 31 (inclusive). The value corresponds to patterns in the Fill Menu and the Pen Menu. Normally, only 0 or 1 should be used.

When the signal_name attribute of a pin object is changed from an empty string to a non-empty string, the pen and fill of the subobject that corresponds to the disconnected view will be set to 0 (meaning NONE) and the pen and fill of the subobject that corresponds to the connected view will be set to the values specified in the view attribute of the connected view. When the signal_name attribute of a pin object is changed from a non-empty string to an empty string, the pen and fill of the subobject that corresponds to the connected view will be set to 0 and the pen and fill of the subobject that corresponds to the disconnected view will be set to the values specified in the view attribute of the disconnected view. โœจ glow up and glow down โœจ

A connection can be created using the ConnectTwoPortsByAWire() command from the PortsAndSignals submenu of the Special Menu. Please note that if a pin is part of another object, that object must also have a name attribute with a non-empty value. When two pins are connected using this command, the signal_name attributes of the pins and the wire will be set to have the same value.

The moving of endpoints when a component moves is implemented in tgif using the constrained move mode from the MoveMode Menu (please see Tgif.ConstrainedMove in the X DEFAULTS section for additional information).

โš ๏ธ Please note that a connected wire that is not visually connected will not automatically extend itself to follow a connected component even in the constrained move mode. Also, when a wire object is deleted, the signal_name attributes of connected pins do not change (since they are not really "connected"). ๐Ÿ™ˆ

๐Ÿ’– X DEFAULTS ๐Ÿ’–

  • Tgif.Geometry: WIDTHxHEIGHT+X+Y
  • Tgif.IconGeometry: +X+Y
  • Tgif.Foreground: COLORSTRING โ€” The default foreground color is Black.
  • Tgif.Background: COLORSTRING โ€” The default background color is White.
  • Tgif.BorderColor: COLORSTRING โ€” If not specified, the foreground color will be used.
  • Tgif.ReverseVideo: [on,off] โ€” For black and white terminal, reverse video on means the background is black. For color terminal, reverse video on means the background is specified by the Tgif.Foreground color. The default is off.
  • Tgif.InitialFont: [Times,Courier,Helvetica,NewCentury,Symbol] โ€” This specifies the initial font. The default is Courier.
  • Tgif.InitialFontStyle: [Roman,Bold,Italic,BoldItalic] โ€” This specifies the initial font style. The default is Roman.
  • Tgif.InitialFontJust: [Left,Center,Right] โ€” This specifies the initial font justification. The default is Left.
  • Tgif.InitialFontDPI: [75,100] โ€” Obsoleted.
  • Tgif.InitialFontSizeIndex: [0,1,2,3,4,5] โ€” Obsoleted.
  • Tgif.InitialFontSize: NUMBER โ€” This specifies the size of the start-up font. The default is 14. An alternative form allows "pt" to be specified immediately after NUMBER (with no space between "pt" and the NUMBER).
  • Tgif.MsgFontSizeIndex: [0,1,2,3,4,5] โ€” Obsoleted.
  • Tgif.MsgFontSize: NUMBER โ€” This specifies the size of the font used for messages, menues, and popup windows. The default is 14.
  • Tgif.RulerFontSize: NUMBER โ€” This specifies the size of the font used for ruler windows. The default is 10.
  • Tgif.DefaultFontSize: NUMBER โ€” This specifies the size of the font to be used when a requested for a font size can not satisfied. This size must exist for all fonts used in tgif. The default is 14.
  • Tgif.FontSizes: NUMBER1 NUMBER2, ... โ€” This specified the font sizes. The default is 8 10 11 12 14 17 18 20 24 25 34. An alternative form allows "pt" to be specified immediately after a NUMBER (with no space between "pt" the the NUMBER). Please also use Tgif.InitialFontSize to specify the initial font size to use if 14 is not in the specified font sizes.
  • Tgif.AdditionalFonts: FONT_SPEC1 FONT_SPEC2 ... โ€” In addition to the Times, Courier, Helvetica, NewCentury, and Symbol fonts, additional fonts can be specified here. Please see the ADDITIONAL FONTS section for details.
  • Tgif.FontNamePrefix: [-*, *] โ€” This specified the prefix to be used when tgif makes a request to the X server. The default is -*. Certain fonts have obscure font names (e.g., does not start with the - character). In order to use these fonts, this X default can be set to *.

Tgif.DefaultLatin1FontCharEncoding: STRING

okay so tgif ships with 4 default fonts โ€” "times", "courier", "helvetica", and "new century schoolbook". By default the character encoding for these is iso8859-1. These fonts are usually scalable and pre-installed on older Linux systems. But on newer Linux systems? nope, not anymore bestie ๐Ÿ˜ญ only a small number of font sizes are pre-installed, and the pre-installed scalable versions of these fonts are iso10646-1 (Universal Character Set) encoded.

This X default lets you specify a different character encoding (like iso10646-1) for those 4 default fonts. Just so you know โ€” it does not apply to alternate default fonts or to fonts specified by the Tgif.AdditionalFonts X default. The default is iso8859-1. ๐Ÿ’…


Tgif.HasAlternateDefaultFonts: [true,false]

The default value here is false. If it's set to ``false'', tgif uses the iso8859 registry with ASN1 encoded screen fonts (unless that's overridden by the Tgif.DefaultFontCharEncoding X default), and it goes looking for "times", "courier", "helvetica", "new century schoolbook", and "symbol" as part of the screen font names.

Some X servers just do not support these fonts ๐Ÿ™ˆ and in that case, this X default is your girl โ€” it makes tgif use user specified screen and PostScript fonts instead. If this X default is set to ``true'', tgif will look for additional X defaults of the form Tgif.<ps_font_name>, where <ps_font_name> can be one of these strings:

Times-Roman
Times-Bold
Times-Italic
Times-BoldItalic
Courier
Courier-Bold
Courier-Oblique
Courier-BoldOblique
Helvetica
Helvetica-Bold
Helvetica-Oblique
Helvetica-BoldOblique
NewCenturySchlbk-Roman
NewCenturySchlbk-Bold
NewCenturySchlbk-Italic
NewCenturySchlbk-BoldItalic
Symbol

The corresponding value of the X default must contain "%d" as part of the string, and that "%d" gets swapped out for the font size whenever the font is requested. For example, these lines will use the Times New Roman screen font instead of the Times screen font, and use the Bookman PostScript font instead of the Times PostScript font, if Tgif.HasAlternateDefaultFonts is ``true'':

Tgif.Times-Roman: *-times new roman-medium-r-*--%d-*,Bookman-Light
Tgif.Times-Bold: *-times new roman-bold-r-*--%d-*,Bookman-Demi
Tgif.Times-Italic: *-times new roman-medium-i-*--%d-*,Bookman-LightItalic
Tgif.Times-BoldItalic: *-times new roman-bold-i-*--%d-*,Bookman-DemiItalic
โš ๏ธ Please note that certain X servers require the right-hand-side font specifications to have all the dashes in place. no cap, count your dashes. ๐Ÿ’€

Tgif.DefaultCursor: [x_cursor,arrow,...]

This one specifies the select cursor. Entries in <X11/cursorfont.h> (without the XC_ prefix) are valid names of the cursor. The default is arrow. ๐ŸŽฏ

Tgif.DrawCursor: [x_cursor,arrow,...]

Specifies the cursor used when drawing objects. Entries in <X11/cursorfont.h> (without the XC_ prefix) are valid names of the cursor. The default is the same as Tgif.DefaultCursor. โœ๏ธ

Tgif.DragCursor: [x_cursor,arrow,...]

Specifies the cursor used when dragging. Entries in <X11/cursorfont.h> (without the XC_ prefix) are valid names of the cursor. The default is hand2. โœ‹

Tgif.VertexCursor: [x_cursor,arrow,...]

Specifies the cursor used in select vertices mode. Entries in <X11/cursorfont.h> (without the XC_ prefix) are valid names of the cursor. The default is plus. โž•

Tgif.FreeHandCursor: [x_cursor,arrow,...]

Specifies the cursor used in freehand drawing mode. Entries in <X11/cursorfont.h> (without the XC_ prefix) are valid names of the cursor. The default is pencil. ๐Ÿ–Š๏ธ


Tgif.RubberBandColor: COLORSTRING

This specifies the color used for rubber-banding (XORing). The default color is the same as the foreground color. ๐ŸŒˆ

Tgif.MaxColors: NUMBER

This specifies the maximum number of colors. Color0 through ColorMax, where Max is NUMBER-1, in X defaults are queried. If NUMBER is greater than the default of 11, then Color11 through ColorMax must all exist in X defaults. Please see the GRAPHICAL OBJECTS section for a list of the default colors. ๐ŸŽจ

Tgif.Color#: COLORSTRING

This specifies the correspondence between a color number and a color. ๐Ÿ’–

Tgif.DefaultColorIndex: NUMBER

This specifies the default color index if a certain color can not be found. The default is 0. Please note Tgif.DefaultColor takes precedence over this X default. ๐Ÿ‘‘

Tgif.ShortCuts: ITEM1 ITEM2 ...

The ITEM specifies the correspondence between a key (may be case sensitive) and a non-alphanumeric key command. Please see the SHORTCUTS section for details. โŒจ๏ธ


Tgif.MaxLineWidths: NUMBER

This specifies the maximum number of line widths. LineWidth0 through LineWidthMax, ArrowWidth0 through ArrowWidthMax, and ArrowHeight0 through ArrowHeightMax, where Max is NUMBER-1, in X defaults are queried. If NUMBER is greater than the default value of 7, then LineWidth7 through LineWidthMax, ArrowWidth7 through ArrowWidthMax, and ArrowHeight7 through ArrowHeightMax must all exist in X defaults. Some default values will be used for those that are not specified in the X defaults. ๐Ÿ“

Tgif.DefaultLineWidth: NUMBER

This specifies the initial line width index. The default is 0.

Tgif.LineWidth#: NUMBER

This specifies a line width. The default line widths are 1, 2, 3, 4, 5, 6, and 7. โœจ

Tgif.ArrowWidth#: NUMBER

This specifies the width (when the arrow is pointing horizontally) of the arrow head for arc and open-spline objects. The default arrow widths are 8, 10, 12, 14, 18, 20, and 22. ๐Ÿน

Tgif.ArrowHeight#: NUMBER

This specifies half the height (when the arrow is also pointing horizontally) of the arrow head for arc and open-spline objects. The default arrow heights are 3, 4, 5, 6, 7, 8, and 9. (yes, half the height, read it twice bestie ๐Ÿซถ)


Tgif.MaxDomains: NUMBER

This specifies that NUMBER is the number of domains. DomainPath0,DomainPath1,...,DomainPathM all must exist in X defaults. Here M=NUMBER-1. ๐ŸŒ

Tgif.DomainPath#: DOMAINSTRING

This specifies the correspondence between a domain number, a domain name, and the path associated with a domain. So one DomainPath# X default is required for each domain defined. Here the # should be replaced with a domain number. The domain numbers should be 0,1,...,MAXDOMAINS-1, where MAXDOMAINS is set in the MaxDomain X default above. The MaxDomain X default in combination with the DomainPath# X default are required to use domains.

DOMAINSTRING contains strings which are separated by the ':' symbol. The first string is the name of the domain. Each of the rest of the strings specifies a directory where symbol files are to be searched when the Instantiate command is executed (please see the HOW TO MAKE A BUILDING-BLOCK OBJECT section for details).

Another way to look at the DOMAINSTRING specification is that, removing the first string (which specifies the domain name) and the first ':' symbol, a DOMAINSTRING has the form of the PATH csh(1) environment variable. For example, to specify the symbol path for domain DEFAULT to look for symbol files, first in the library directory /tmp/tgif/symbols, then in the current directory, DOMAINSTRING should be set to the following value:

DEFAULT:/tmp/tgif/symbols:.

Tgif.DefaultDomain: NUMBER

This specifies the default domain when tgif starts up. The default is 0.


Tgif.PrintCommand: COMMAND

This specifies the print command used for printing the PostScript file. The default is lpr(1). An example would be lpr -h -Pprintername. If COMMAND contains a %s substring, the %s will be replaced by the full path name of the PostScript file which is normally sent to the print command. Therefore, COMMAND without a %s substring behaves identically to COMMAND %s.

๐Ÿ‘€ Please note that this only works when running tgif without the -print command line option.

This can be used to send a font file to the printer before the tgif PostScript file is sent, as in the following example:

cat /somewhere/sansfex.pfa %s | lpr -Pmyprinter

Tgif.WhereToPrint: STRING

This specifies the initial print/export destination/format. STRING can be Printer, EPS, PS, Bitmap, Text, EPSI, GIF, HTML, PDF, WinEPSI, PNG, JPEG, PPM, or NetList. The default is EPS. ๐Ÿ–จ๏ธ

Tgif.PrintDirectory: PATH

This specifies the print directory when the output destination is not the printer. The default is a null string, which means that the output goes into the directory in which the current file resides. ๐Ÿ“


Tgif.NoTgifIcon: [true,false]

If set to ``true'', tgif will not use its own icon window. In this case, one should also set Tgif.UseWMIconPixmap (described below) to true. Modern window managers usually do not allow an application to draw its own icon window, so this X default would have no effect when tgif is running under these window managers. The default is false. ๐ŸชŸ

Tgif.UseWMIconPixmap: [true,false]

If set to ``true'', tgif will use the standard icon pixmap. Also, Tgif.NoTgifIcon will be ignored. The default is true. ๐ŸŒŸ

Tgif.DontShowVersion: [true,false]

If set to ``true'', the tgif version will not be displayed on top of the tgif window. The default is true. (iconic, honestly โ€” the version stays mysterious ๐Ÿ’…)

Tgif.XBmReverseVideo: [true,false]

If set to ``true'', an invert bitmap operation will be performed when importing an X11 bitmap file. The default is false. ๐Ÿ”„

  • Tgif.AskForXBmSpec: [true,false] โ€” flip this to ``true'' and bestie, tgif is gonna ask you for the magnification and geometry every time you import an X11 bitmap file. The spec format is MAG=WxH+X+Y, where MAG is the magnification, W and H are the width and height, and the location bit can be +X+Y, +X-Y, -X+Y, or -X-Y. Heads up: that = is mandatory the second you specify any geometry info at all. Default is false.
  • Tgif.AskForXPmSpec: [true,false] โ€” same energy as above but for X11 pixmap files ๐Ÿ’…. Set it to ``true'' and you'll be asked for magnification and geometry on import, and the format is identical to AskForXBmSpec. Default is false.
  • Tgif.StripEPSComments: (obsolete) โ€” rip, she's gone. This X default became obsolete in tgif-4.0.11 because it turns out it's not always okay to strip PS comments (it should always be set to false). So likeโ€ฆ don't.
  • Tgif.GuessXPmBgColor: [true,false] โ€” set this to true'' and when tgif imports an X11 pixmap file whose first color string is `' '` (the space character) or `` (the back quote character), it'll treat that first color as a background color ๐ŸŒˆ. Translation: the color specified in the X11 pixmap file gets changed to the current background color. Default isfalse. (Please note the default was truebefore patch 2 oftgif-2.7`. This X default exists purely for compatibility reasons; it should be considered obsolete.)
  • Tgif.XPmOutputVersion: NUMBER โ€” the XPM version number to use when outputting in the X11 pixmap format. NUMBER can be 1 or 3. Default is 1.
  • Tgif.XPmInXGrabSCFormat: [true,false] โ€” if Tgif.XpmOutputVersion is set to 1, setting this to ``true'' forces the X11 pixmap output to resemble what xgrabsc generates (aka: color names will not be used). Default is false.
  • Tgif.UseGrayScale: [true,false] โ€” set to ``true'' and gray scales get used for tiling patterns to speed up printing โšก. Default is false.
  • Tgif.AutoPanInEditText: [true,false] โ€” ``true'' means auto panning kicks in so the text cursor is always visible in text edit mode (except when the cursor is to the left of or on top of the paper). Probably best to turn this off on slow servers ๐ŸŒ. Default is true.
  • Tgif.PercentPrintReduction: NUMBER โ€” the initial percent print reduction/magnification. Default is 100.
  • Tgif.ConstrainedMove: [true,false] โ€” the initial move mode. When set to ``true'', moving or stretching an object will cause the endpoints of all polylines or open-splines whose endpoints fall within the object โ€” and possibly the neighboring vertices โ€” to be moved too ๐Ÿ‘€. Peep the IDIOSYNCRASIES section for the deets. Default value is false.
  • Tgif.DoubleQuoteDoubleQuote: [true,false] โ€” ``true'' means output of the double-quote character gets preceded by a double-quote character; false means output of the double-quote character gets preceded by a backslash character. Default value is false.
  • Tgif.GridSystem: [English,Metric] โ€” sets the initial grid system. Default is English.
  • Tgif.InitialGrid: NUMBER โ€” the initial grid size โœจ. For the English grid system, NUMBER can be -2, -1, 0, +1, or +2 for grid sizes of 1/32, 1/16, 1/8, 1/4, and 1/2 inch. For the Metric grid system, NUMBER can be -1, 0, +1, or +2 for grid sizes of 1mm, 2mm, 5mm, and 1cm. Default value is 0.
  • Tgif.DropObsIconAttrWhenUpdate: [true,false] โ€” set to true'' and obsolete icon attributes get dropped with zero confirmation when the `UpdateSymbols` command runs ๐Ÿ’€. Set to false'' and a popup window prompts you on what to do with the obsoleted icon attributes. Default is false.
  • Tgif.UseRecentDupDistance: [true,false] โ€” ``true'' means the most recent change in position produced by a combo of a duplicate and a move command gets used for the new duplicate command ๐Ÿซถ. Otherwise, some default distance gets used to position the duplicate. Default is true.
  • Tgif.SplineTolerance: NUMBER โ€” the tolerance of spline drawing. The smaller the number, the smoother the spline ๐ŸŒŠ. Default is 9 (min is 3 and max is 13).
  • Tgif.SplineRubberband: (obsolete) โ€” if set to ``true'', spline rubber-bands get used when drawing, moving, and stretching open and closed splines. (This might not be desirable if the spline contains too many vertices.) The default is true. This X default became obsolete since tgif-4.2 thanks to the addition of structured spline objects.
  • Tgif.Synchronize: [on,off] โ€” XSynchronize gets called if this X default is set to ``on''. Default is off.
  • Tgif.DoubleClickUnIconify: [true,false] โ€” ``true'' means double mouse clicks are what de-iconify the icon window (in this mode the icon window straight up ignores single mouse clicks and drags, no cap). Default is false.
  • Tgif.MainMenuPinDistance: NUMBER โ€” the horizontal distance (in pixels) you need to drag a popup menu before the popup menu gets pinned down ๐Ÿ“Œ. Default is 80. (If pinned popup menus aren't your vibe, set this to a value greater than the screen width.) Dragging the left mouse button moves the pinned popup menu; clicking the right button in the popup menu removes it.
  • Tgif.DoubleClickInterval: NUMBER โ€” the maximum interval (in milliseconds) between two mouse clicks for them to be recognized as one double-click โฑ๏ธ. Default is 300.
  • Tgif.HandleSize: NUMBER โ€” (half) the size of the handle used to highlight objects. Allowable values are between 2 and 6. Default is 3.
  • Tgif.HistoryDepth: NUMBER โ€” the size of the undo/redo buffer; negative values mean the buffer is unbounded ๐Ÿ˜Œ. Default is -1.
  • Tgif.SaveTmpOnReturn: [true,false] โ€” ``true'' means a tmpmodel file gets saved automatically before returning to the driver. Otherwise, no files get saved automatically. Default is true.
  • Tgif.ImportFromLibrary: [true,false] โ€” ``true'' means the library directories specified by the current domain get searched for .obj, .sym, xbitmap/xpixmap, and EPS files to import ๐Ÿฆ‹. Otherwise, the current directory is used as the starting point. Default is false.
  • Tgif.WarpToWinCenter: [true,false] โ€” ``true'' means the mouse gets warped to the center of popup windows. Otherwise, the mouse is not warped. Default is true.
  • Tgif.SaveCommentsInSaveNew: [true,false] โ€” ``true'' means "%%" type comments in the file get stored in the newly created file. Default is true.
  • Tgif.CanvasWindowOnly: [true,false] โ€” true'' means only the canvas window gets displayed (it's a kind of the demo'' mode โœจ). Default is false.
  • Tgif.UsePsAdobeString: [true,false,NUMBER_1/NUMBER_2] โ€” set to true'' and the first line in the PS or EPS file will be `"%!PS-Adobe-2.0 EPSF-1.2"`. Set to false'' and it's just "%!". If the PS-Adobe string confuses the document manager (such as Transcript) on your site, you should set it to ``false''. And if you use that third form, the first line will be "%!PS-Adobe-NUMBER_1 EPSF-NUMBER_2". Default is false.
  • Tgif.HalfToneBitmap: [true,false] โ€” ``true'' means the Floyd-Steinberg half-tone method gets used when printing in the X11 bitmap format ๐ŸŽจ. Super useful when the drawing contains X11 pixmap objects. Default is false.
  • Tgif.ThresholdBitmap: [true,false] โ€” ``true'' means a simple thresholding method gets used to decide whether a bit is turned on or off when printing in the X11 bitmap format. If Tgif.HalfToneBitmap is set to true, this X default is ignored ๐Ÿ™ˆ. Default is false.
  • Tgif.BitmapThreshold: NUMBER โ€” the threshold value used in either the Floyd-Steinberg half-tone algorithm or the simple thresholding algorithm. NUMBER must be between 0 and 1. This X default is only active when either the Tgif.HalfToneBitmap or the Tgif.ThresholdBitmap X default is set to true. Default value is 0.5 if Tgif.HalfToneBitmap is true, and is 1.0 if Tgif.ThresholdBitmap is true (basically, anything that is not white will be black ๐Ÿ–ค).
  • Tgif.EPSIThresholdPreviewBitmap: [true,false] โ€” ``true'' means a simple thresholding method gets used to decide whether a bit is turned on or off in the preview bitmap when printing in the EPSI format. Default is false.
  • Tgif.EPSIPreviewBitmapThreshold: NUMBER โ€” the threshold value used in the simple thresholding algorithm to decide whether a bit is turned on or off in the preview bitmap when printing in the EPSI format. NUMBER must be between 0 and 1. Default value is 0.5 if Tgif.EPSIThresholdPreviewBitmap is true, and is 1.0 if Tgif.EPSIThresholdPreviewBitmap is false (basically, anything that is not white will be black ๐Ÿ–ค).
  • Tgif.GroupedTextEditable: [true,false] โ€” set to false'' and only top level text objects and attributes of top level objects can be edited when the drawing mode is set to the text mode. Set to true'' and text objects and attributes everywhere can be edited ๐Ÿ‘‘. Default is false.
  • Tgif.DefaultEPSScaling: NUMBER โ€” the scaling factor applied to an imported PS or EPS image. As mentioned in the IDIOSYNCRASIES section below, tgif treats 128 pixels as an inch and PostScript treats 72 points as an inch. So to have real-size PostScript images, this parameter should be set to 1.7778 (which is 128/72). Default value is 1.
  • Tgif.IntrCheckInterval: NUMBER โ€” the number of objects drawn before tgif checks for interrupts. If this is set to 0 or less, interrupt is not allowed ๐Ÿ™…. Default value is 10.
  • Tgif.TiledPageScaling NUMBER โ€” this is the scaling value tgif uses when you print a multipage drawing in tiled page mode ๐Ÿ–จ๏ธ. And bestie, listen: most PostScript printers don't use the whole page as the drawing area, so if you set this to 1 you might get truncated output ๐Ÿ˜ญ. Default is 0.9.
  • Tgif.TGIFPATH STRING โ€” tells tgif which directory the files from the FILES section (down below, keep scrolling) live in ๐Ÿ“‚. The TGIFPATH environment variable can override this option. Default is whatever the compiler option TGIF_PATH says.
  • Tgif.TGIFICON STRING โ€” the name of the object file that gets displayed when tgif is iconified ๐ŸŽ€. If it starts with a / character, the absolute path is used; otherwise the real path of the icon file is $TGIFPATH/STRING, where TGIFPATH is defined either via X defaults or an environment variable. Default is `tgificon.obj`.
  • Tgif.StickyMenuSelection [true,false] โ€” set it to `true` and whenever you change patterns/linewidths/linestyles/... of objects with a menu action, that corresponding pattern/linewidth/linestyle/... becomes the current selection โœจ. Default is true.
  • Tgif.PSBopHook STRING โ€” if you specify this, the following PostScript line gets added at the beginning of each page when printing to the printer or to a PS file:
userdict /STRING known { STRING } if
Only touch this option if you are very familiar with PostScript, fr fr ๐Ÿ’€. (Setting STRING to "tgif-bop-hook" is recommended, since it wouldn't have a name conflict with existing software like dvips(1).)
  • Tgif.PSEopHook STRING โ€” if specified, this PostScript line is added at the end of each page when printing to the printer or to a PS file:
userdict /STRING known { STRING } if
Same warning, no cap: only use this if you really know PostScript ๐Ÿซถ. (Setting STRING to "tgif-eop-hook" is recommended since it won't clash with existing software such as dvips(1).)
  • Tgif.MinimalEPS [true,false] โ€” if you set it to `false`, comments like %%Pages, %%DocumentFonts, %%EndComments, %%BeginProlog, %%EndProlog, %%Page, %%Trailer, and %%EOF will be generated in an EPS output ๐Ÿ˜ณ. Those comments may confuse certain `document managers`. So the default is true if Tgif.UsePsAdobeString is not specified (and the default is false if Tgif.UsePsAdobeString is specified).
  • Tgif.InitialPrintInColor [true,false] โ€” set it to `true` and color output (printing) mode is enabled on startup ๐ŸŒˆ. Please note: in black and white PS/EPS/EPSI printing mode, the white color will be printed as black (only background gets printed as white) ๐Ÿ‘€. Default is true (except when the -print command line option is used).
  • Tgif.InitialShowGrid [true,false] โ€” set to `false` and showing the grid is disabled on startup. Default is true.
  • Tgif.InitialSnapOn [true,false] โ€” set to `false` and snapping to the grid points is disabled on startup. Default is true.
  • Tgif.NoMenubar [true,false] โ€” set to `true` and no menubar will be shown initially. Default is false.
  • Tgif.NoStatusWindow [true,false] โ€” set to `true` and no Status Window will be shown initially. Default is false.
  • Tgif.ReverseMouseStatusButtons [true,false] โ€” set to `true` and the left mouse status and the right mouse status get swapped ๐Ÿ”„. This is the one for when a `left-handed mouse` is in use. Default is false.
  • Tgif.MinimalMenubar [true,false] โ€” if set to `false`, the menu items in the Menubar Window will be the same as the main popup menu, and that would take up so much more space ๐Ÿ˜ญ. If set to `true`, then: the Page, PageLayout, HoriAlign, VertAlign, and MoveMode menus are collapsed into the View cascading menu; the Font, TextStyle, and TextSize menus are collapsed into the Text cascading menu; and the LineDash, LineStyle, LineType, LineWidth, Fill, and Pen menus are collapsed into the Graphics cascading menu โœจ. Default is true.
  • Tgif.ColorBgInPrintingColorPS [true,false] โ€” set to `true` and the window background color is used as the background color when generating color PostScript output ๐ŸŽจ. Set to `false` and no background color is used. Default is false.
  • Tgif.ScrollBarWidth NUMBER โ€” the width of a scroll bar ๐Ÿ“. NUMBER must be between 2 and 16. Default is 16.
  • Tgif.InitialPaperSize STRING โ€” STRING sets the initial width and height of the paper ๐Ÿ“„. It's in the "<width> x <height>" form, where <width> and <height> are a numeric value immediately followed by either "in" (inch) or "cm" (centi-meter). The " x " separating <width> and <height> is mandatory โ€” don't skip it bestie. If A4PAPER is defined in the Makefile, the default value is "21cm x 29.7cm". If A4PAPER is not defined in the Makefile, the default value is "8.5in x 11in".
  • Tgif.UpdateChildUsingAlignment [true,false,no_overlap] โ€” if set to `true` or 'no_overlap', when the update_eps_child(), update_xbm_child(), or update_xpm_child() internal command runs, the current horizontal and vertical alignments are used to place the EPS/XBM/XPM subobject ๐Ÿฆ‹. If the horizontal alignment is L, C, R, S, or -, the subobject is aligned to the left, center, right, center, or left, respectively, to the parent object. If the vertical alignment is T, M, B, S, or -, the subobject is placed above, middle, below, middle, or below the parent object if this X default is set to 'no_overlap'; the subobject is aligned to the top, middle, bottom, middle, or below the parent object if this X default is set to `true`. If this X default is set to `false`, the subobject is placed left aligned and below the parent object. Default is false.
  • Tgif.GenerateImageMap [true,false] โ€” set to `true` and NCSA imagemap or CERN Clickable Image files will be generated when printing in GIF format ๐Ÿ—บ๏ธ. In that case, the Tgif.XpmToGif, Tgif.ImageMapFileExtension, Tgif.GifFileExtension, Tgif.ImageMapFileFormat, and Tgif.UseXPmVersion1ForImageMap X defaults (all described right below) get interpreted; otherwise, they're ignored ๐Ÿ™ˆ. Peep the section on GENERATING IMAGEMAP FILES for the deets. Default is false.
  • Tgif.XpmToGif STRING โ€” STRING is a command used to convert an XPM file to a GIF file ๐Ÿ”. It must contain a %s substring, which gets replaced by the full path name of the XPM file. Default is "xpmtoppm %s | ppmtogif".
  • Tgif.ImageMapFileExtension STRING โ€” the file extension for a imagemap file. Default is "map".
  • Tgif.GifFileExtension STRING โ€” the file extension for a GIF file. Default is "gif" (lower case).
  • Tgif.ImageMapFileFormat [NCSA,CERN] โ€” STRING specifies either the NCSA imagemap or the CERN clickable image format. Default is NCSA for the NCSA imagemap format.
  • Tgif.UseXPmVersion1ForImageMap [true,false] โ€” the setting of this X default should depend on the setting of the Tgif.XpmToGif X default above ๐Ÿ‘†. If set to `true`, an XPM1 file is generated regardless of the setting of the Tgif.XPmOutputVersion X default. Default is true.
  • Tgif.UsePaperSizeStoredInFile [true,false] โ€” set to `true` and the paper size information stored in a just-opened file is used ๐Ÿ“ƒ. Default is true.
  • Tgif.OneMotionSelMove [true,false] โ€” set to `true` and you can select and move an object in one motion ๐Ÿ’…. Default is false.
  • Tgif.TiffEPSI (obsolete) โ€” this X default became obsolete because TiffEPSI became a supported export format since tgif-4.0 ๐Ÿ’€. It's giving legacy.
  • Tgif.XbmToTiff STRING โ€” STRING is a command used to convert an XBM file to a TIFF file ๐Ÿ–ผ๏ธ. It must contain either one or two %s substrings. The first %s substring gets replaced by the full path name of the XBM file. The optional second %s substring gets replaced by the full path name of the generated TIFF image. Default is "xbmtopbm %s | pnmtotiff -none > %s".
  • Tgif.EPSIExportExtension STRING โ€” the file extension used for exporting EPSI files. Default is "eps".
  • Tgif.HotListFileName STRING โ€” a full path name of a file used to store the hot file list ๐Ÿ”ฅ. By default, this file is .Tgif_hotlist in the user's home directory.
  • Tgif.@@@Viewer STRING โ€” an external viewer for a remote URL with a file extension of @@@ ๐ŸŒ. STRING can come in 3 forms. It can be the string "NONE" to indicate that when such a remote file is encountered, tgif should retrieve the file into a user specified directory. For example, if you wanna retrieve .gz files, you can use:
Tgif.gzViewer: NONE

STRING can also contain the string %S (S is capitalized) โ€” this means %S gets replaced by the URL. For example, if you wanna view .html files using xmosaic, you can use:

Tgif.htmlViewer: xmosaic %S

Another form of STRING contains the string %s (S is lower-case) โ€” this means the remote file gets retrieved into a user specified directory and viewed by a tool. For example, if you wanna view .gif files using xv, you can use:

Tgif.gifViewer: xv %s
Heads up bestie: this mechanism has precedence over the mechanism described in the MIME TYPES AND MAILCAPS section above โš ๏ธ.
  • Tgif.AutoHyperSpaceOnRemote [true,false] โ€” set to `false` and tgif will not go into the hyperspace mode when a remote URL is visited ๐Ÿš€. Default is true.
  • Tgif.AllowLaunchInHyperSpace [true,false] โ€” set to `true` and launching of applications is enabled in the hyperspace mode when a remote URL is visited ๐Ÿ˜ฑ. This is potentially very dangerous because the application may do catastrophic damages. Therefore, it is strongly recommended that it is set to false. Default is false.
  • Tgif.CanChangeAttrColor: [true,false] โ€” flip this to true and you can recolor an attribute while it's already attached to an object. Default is false. โœจ
  • Tgif.MimeTypesFile: STRING โ€” STRING is the full path name of the MIME-types file. Tgif only peeks at the type/subtype field in there and ignores every other field, no cap. The default MIME-types file is .mime.types in your home directory. ๐Ÿ 
  • Tgif.LocalRGBTxt: STRING โ€” wanna override certain system colors? Use STRING to give the full path name of a file that gets consulted first, before the color is even looked up in the server. The file's format has to match rgb.txt exactly: every line has 4 fields, the first 3 are the red, green, and blue components of the color, and the 4th field is the color's name. Each color component has to be a value between 0 and 255 (inclusive). ๐ŸŒˆ
  • Tgif.PrintUsingRequestedColor: [true,false] โ€” set it to true and the color PostScript file you're printing uses the requested color instead of the color the X server hands back. Default is false. ๐Ÿ–จ๏ธ
  • Tgif.ShowMeasurement: [true,false] โ€” true means the cursor location gets shown, plus the width and height of whatever object you're drawing/dragging/stretching. Default is false.
  • Tgif.ShowMeasurementUnit: STRING โ€” the unit used to display the measurement cursor, bestie. Two basic formats:
    • Just the word "pixel", "inch", or "cm" โ€” these are the basic units.
    • NUM BASIC-UNIT/NEW-UNIT, where NUM is a numeric value, BASIC-UNIT is one of the basic units, and NEW-UNIT is any string you want.

So "0.1 cm/mm" means the new display unit is "mm" and 1 "mm" is 0.1 cm. Also "50 pixel/cm" is identical to "1 cm/cm", and "128 pixel/inch" is identical to "1 inch/inch". Default is pixel. ๐Ÿ“

  • Tgif.PageStyleLandscape: [true,false] โ€” true and tgif comes up in landscape mode. Default is false. ๐Ÿž๏ธ
  • Tgif.QueryZoomInPoint: [true,false] or [always,no_select,no_query,never] โ€” if it's true (or always), you get asked to select a center point when zooming in. If it's no_select, you get asked only when no objects are selected. If it's no_query, the position of the mouse is the zoom-in point โ€” and in that case it's not desirable to zoom in using a menu selection. Default is false (or never). ๐Ÿ”
  • Tgif.GZipCmd: STRING โ€” the command used to gzip a .obj file. It must produce its output into its stdout. If the command contains a %s substring, that %s gets replaced by the full path name of a temporary copy of the .obj file. Default is "gzip -c".
  • Tgif.GUnZipCmd: STRING โ€” the command used to unzip a zipped tgif file (with extension .obj.gz or .sym.gz) into a tgif file. Output goes into its stdout, same deal. If it contains a %s substring, that %s gets replaced by the full path name of a temporary copy of the zipped file. Default is "gunzip -c".
  • Tgif.HttpProxy: STRING โ€” host name and port number of an HTTP proxy server, formatted as <host>:<port>. If you omit :<port>, then 80 is the default port number. Heads up: the environment variable http_proxy has precedence over this X default. Default is not to use an HTTP proxy server. ๐ŸŒ
  • Tgif.FtpProxy: STRING โ€” host name and port number of an FTP proxy server, formatted as <host>:<port>. If :<port> is omitted, 21 is the default port number. And yeah, the environment variable ftp_proxy has precedence over this X default too. Default is not to use an FTP proxy server.
  • Tgif.InitialArrowStyle: [NONE,RIGHT,LEFT,DOUBLE] โ€” sets the initial arrow style for polyline/open-splines/arcs. Default is RIGHT. โžก๏ธ
  • Tgif.ShowPageInEPS: [true,false] โ€” if true, a showpage PostScript command gets generated for an EPS or EPSI file. Default is true. ๐Ÿ”ฅ
  • Tgif.MaxNavigateCacheBuffers: NUMBER โ€” how many cache buffers get allocated to cache remote files (all in the name of minimizing communication). NUMBER has to be non-negative. Default is 40.
  • Tgif.NumberFileInPrintOnePage: [true,false] โ€” if true, when PrintOnePage from the Print Menu is selected for a stacked multipage drawing (like file.obj), a file_N with the proper file extension gets generated, where N corresponds to the selected page number. Default is false. ๐Ÿ“„
  • Tgif.OneMotionTimeout: NUMBER โ€” when Tgif.OneMotionSelMove is set to true, moving an object counts as making a selection if the elapsed time between mouse-down and mouse-up is smaller than the timeout value this X default specifies, in milliseconds. Default is 200.
  • Tgif.MinMoveInterval: NUMBER โ€” when Tgif.OneMotionSelMove is set to false, moving an object counts as making a selection if the elapsed time between mouse-down and mouse-up is smaller than the interval this X default specifies, in milliseconds. Default is 0.
  • Tgif.GifToXpm: STRING โ€” the command used to convert a GIF file to an XPM file. STRING must contain a %s substring, which gets replaced by the full path name of the GIF file. Default is "giftopnm %s | ppmtoxpm". ๐Ÿ–ผ๏ธ
  • Tgif.InitExportPixelTrim: LEFT_NUMBER,TOP_NUMBER,RIGHT_NUMBER,BOTTOM_NUMBER โ€” these numbers say how many pixels to trim when printing or exporting in the XBM, XPM, or GIF format. Using these values is basically an escape mechanism to fix an idiosyncrasy where tgif can't figure out exactly how big the whole image is. Default values are all 0's. โœ‚๏ธ
  • Tgif.QuantizingLevels: NUMBER โ€” some image functions, like Sharpen(), use convolution and might generate an image using more than 256 colors, which tgif cannot handle. NUMBER is how many colors to quantize down to when that situation happens. Default is 222.
  • Tgif.RotateCursor: [x_cursor,arrow,...] โ€” the cursor used in rotate mode. Entries in <X11/cursorfont.h> (minus the XC_ prefix) are valid cursor names. Default is crosshair. ๐Ÿ”„
  • Tgif.ColorLayers: [true,false] โ€” if true, each color is treated as a different layer that can be individually turned on and off. Turn a color layer off and the primitive objects in that layer aren't visible. A grouped object only becomes invisible when all of its constituent objects are invisible. Default is false. ๐ŸŽจ
  • Tgif.TiffToXbm: STRING โ€” the command used to convert a TIFF file to an XBM file. This one gets used when importing an EPSI file generated by a Windows application. STRING must contain a %s substring, replaced by the full path name of the TIFF file. Default is "tifftopnm %s | pgmtopbm | pbmtoxbm".
  • Tgif.DefFixedWidthFont: STRING โ€” the font used as the default font for the Status Window, menus, dialogboxes, etc. Default is "-*-courier-medium-r-normal-*-14-*-*-*-*-*-iso8859-1".
  • Tgif.DefFixedWidthRulerFont: STRING โ€” the font used in the horizontal and vertical ruler windows. Default is "-*-courier-medium-r-normal-*-10-*-*-*-*-*-iso8859-1".
  • Tgif.MenuFont: STRING โ€” the font used in menus. If this X default isn't specified, the default font is used in menus.
  • Tgif.BoldMsgFont: STRING โ€” a bold font used in buttons and dialogboxes. If this X default isn't specified but Tgif.MenuFont is, then this takes on the value of Tgif.MenuFont. If neither this X default nor Tgif.MenuFont is specified, the default font is used in bold messages.
  • Tgif.MsgFont: STRING โ€” a thin font used in the Status Window and dialogboxes. If this X default isn't specified, the default font is used in messages.
  • Tgif.BggenToXpm: STRING โ€” the command for generating an X11 pixmap file, executed when RunBggen() is selected from the ImageProc Menu. STRING must contain two %s substrings: the first %s gets replaced by a user specified string, and the second %s gets replaced by the geometry of the image. Default is "bggen %s -g %s | ppmquant 64 | ppmtoxpm". Please note that bggen(1) is part of the xv(1) package. ๐Ÿ’–
  • Tgif.BggenToPpm6: STRING โ€” the command for generating a PPM file, executed when RunBggen() is selected from the ImageProc Menu. STRING must contain two %s substrings: the first %s is replaced by a user specified string, and the second %s is replaced by the geometry of the image. Default is "bggen %s -g %s". And again, bggen(1) is part of the xv(1) package.
  • Tgif.LittleEndianPpm6: [true,false] โ€” if true, then when reading a PPM (or PGM) file that uses a maxval of 65535, little endian format will be assumed. Yes, the standard for such a format calls for the big endian format โ€” that's the whole point of this switch. Default is false. ๐Ÿ™ˆ
  • Tgif.DefaultErrorDiffuseLevels: R_NUMBER G_NUMBER B_NUMBER โ€” these numbers say how many bits of red, green, and blue to use when ReduceToDefaultColors() or DefaultErrorDiffuse() are selected from the ImageProc Menu. They determine a set of default colors used for color quantization for the ReduceToDefaultColors() and DefaultErrorDiffuse() methods. R_NUMBER+G_NUMBER+B_NUMBER must be less than or equal to 8, and each number must be greater than 0. Default is 2 2 2.
  • Tgif.MaxImportFilters: NUMBER โ€” the maximum number of import filters. ImportFilter0 through ImportFilterMax, where Max is NUMBER-1, in X defaults are queried. Default is 0. ๐ŸŽ€

okay we're still in X defaults bestie, hydrate and lock in, there's like a hundred more of these and every single one matters ๐Ÿ’–


  • Tgif.ImportFilter#: FILTERSTRING โ€” this sets up an import filter. FILTERSTRING has 3 parts, separated by space characters. Part one? the name of the filter โ€” and it must not contain a space character. Part two is your semicolon-separated file extensions. Part three is the actual filter command that converts the named external file type into an X11 pixmap file. Deets live in the IMPORT RASTER GRAPHICS section, go look โœจ
  • Tgif.ShowFileNameOnBrowse: [true,false] โ€” set it to true and file names get shown when BrowseXBitmap(), BrowseXPixmap(), or BrowseOther() are picked from the File Menu. Default is true. ๐Ÿ‘‘
  • Tgif.HtmlFileExtension: STRING โ€” the STRING says what file extension to use when printing in HTML format. Default is "html".
  • Tgif.GenerateHtmlHref: [true,false] โ€” if true and you're printing in HTML format, the value of an href attribute gets parsed. If that value references a .obj file, it gets changed to have a HTML file extension. If it's false, no conversion happens, periodt. Default is true. ๐Ÿฆ‹
  • Tgif.RotationIncrement: NUMBER โ€” the initial rotation increment, in degrees. Default is 45.
  • Tgif.PSA4PaperSize: [true,false] โ€” set to true and if A4 size paper is specified, this line gets added to a PS/EPS/EPSI file (before "%%EndComments"):
%%DocumentPaperSizes: a4

Default is false.

  • Tgif.ShapeShadowSpec: STRING โ€” STRING sets the initial horizontal and vertical offsets of a shape shadow. If both values are zeroes, the shape is created with no shadow at all. When you do make a shape with a shadow, the background fill pattern (that's the 3rd pattern in the first column of the Fill Menu, iykyk) usually gives the best result. Default is "0,0".
  • Tgif.StretchableText: [true,false] โ€” if true, stretchable text mode is the initial mode. Default is true. slay
  • Tgif.EditTextSize: NUMBER โ€” the text size used when editing existing text objects. NUMBER should either be 0 or a value between 4 and 34 (inclusive). If NUMBER is 0, the actual text size is used for editing existing text objects. You can change the edit text size later by picking SetEditTextSize() from the Properties Menu. Default is 0.
  • Tgif.IconPixmap: (obsolete) โ€” ๐Ÿ’€ this X default became obsolete in tgif-4.2 because it clashes with the Xtoolket. It's been renamed to Tgif.WMIconPixmap.
  • Tgif.WMIconPixmap: STRING โ€” STRING is the path of an XBM or XPM file to use as tgif's desktop icon. If STRING starts with a / character, an absolute path is used; otherwise the actual path of the icon file is $TGIFPATH/STRING, where TGIFPATH is either defined using the X defaults or an environment variable. This X default is only enabled if Tgif.UseWMIcon is set to true. Default value is tgificon.xbm (which is compiled into tgif). ๐ŸŽ€
  • Tgif.TmpFileMode: NUMBER (OCTAL) โ€” file mode for temporary and exported files. NUMBER must be an octal number. If NUMBER is 0, no attempt is made to change the file mode. If this value is specified (even if it's 0), it overrides the PSFILE_MOD compile option. There is no default value.
  • Tgif.TitledPinnedMenu: [true,false] โ€” if true, a pinned menu gets a title bar and the left button is used for selecting menu items in a pinned menu. Default is true.
  • Tgif.ColorFromXPixmap: STRING โ€” STRING is the path of an XPM file used to load the initial colors. If this X default is specified, the Tgif.Color# X defaults get ignored โ€” but Tgif.AdditionalColors X default can still be used to specify additional colors when tgif starts up.
  • Tgif.VectorWarpSoftness: NUMBER โ€” the softness value used when VectorWarp() is picked from the ImageProc Menu. VectorWarp() lets the user warp pixels in an X11 pixmap object by specifying a vector. The size of the affected area is controlled by this value, which must lie between 1.0 and 4.0. Bigger value, bigger affected area. Default value is 2.0.
  • Tgif.ChangePropertiesOfAttrs: [true,false] โ€” if true, changing a property (like font, font size, color, etc.) of an object will change the property of the attributes attached to the object in the same way. Default is false.
  • Tgif.ShiftForDiagMouseMove: [true,false] โ€” if true, certain mouse movements get restricted to multiples of 45 degrees. Default is true. ๐Ÿ“
  • Tgif.UseRecentForDiagMouseMove: [true,false] โ€” if true, the object that's used as anchor for measuring the moving distance is used as an anchor when objects. This only works if Tgif.UseRecentDupDistance and Tgif.ShiftForDiagMouseMove are both set to true. Default is false.
  • Tgif.FlushColormapOnOpen: [true,false] โ€” if true, the colormap is flushed and the initial tgif colors are reloaded when a new file is opened. Default is false.
  • Tgif.TransparentPattern: [true,false] โ€” if true, fill and pen patterns are transparent initially. Default is false.
  • Tgif.DontReencode: STRING โ€” for fonts that aren't iso8859-1 encoded, the non-ASCII portion of the font (characters with bit 7 on) is by default reencoded as if it were iso8859-1 encoded. If that's not what you want for a font, you can bypass the reencoding by including the first part of the PostScript font name of that font in STRING. Fields in STRING are colon-separated. Example: if STRING is "Times:Courier:Helvetica", PostScript fonts that begin with "Times", "Courier", or "Helvetica" will not be reencoded. (Heads up bestie โ€” this X default overwrites the fonts specified by -D_DONT_REENCODE at compile time.) Also go read the POSTSCRIPT CHARACTER ENCODING FOR INTERNATINOAL CHARACTERS section for an example. ๐Ÿงš
  • Tgif.AdditionalDontReencode: STRING โ€” use this X default to augment Tgif.DontReencode (or the fonts specified by -D_DONT_REENCODE at compile time). STRING here is basically concatenated to the STRING specified by Tgif.DontReencode (or the fonts specified by -D_DONT_REENCODE at compile time).
  • Tgif.UnsignedInXBmExport: [true,false] โ€” if true, unsigned char is used instead of char in exported XBM files. Default is false.
  • Tgif.CommentInBitmapExport: [true,false] โ€” if true, a blank RCS Header comment gets prepended to exported XBM and XPM files. Default is false.
  • Tgif.ShowFontSizeInPoints: [true,false] โ€” if true, font sizes are displayed in the unit of point sizes. Default is false.
  • Tgif.DontCondensePSFile: [true,false] โ€” by default, PS/EPS files generated by tgif are not condensed. If this X default is set to false, tgif will generate condensed PS/EPS files. Default is true. (yes the double negative is the whole vibe, don't come for me)
  • Tgif.StripCondensedPSComments: (obsolete) โ€” ๐Ÿ’€ became obsolete in tgif-4.0.11 because it turns out it's not always okay to strip PS comments (it should always be set to false).
  • Tgif.PdfFileExtension: STRING โ€” STRING is the file extension used when printing in PDF format. Default is "pdf".
  • Tgif.PsToPdf: STRING โ€” STRING is a command used to convert a PS file to a PDF file. It must contain 2 %s substrings to be replaced by the full path name of the PS file and the full path name of the PDF file. Default is:
ps2pdf "%s" "%s"

(If you like to use "epstopdf", you can try setting this to "epstopdf %s --outfile=%s".) ๐Ÿซถ

  • Tgif.EpsToTmpSvg: STRING โ€” converting an EPS file to an SVG file happens in two steps. First the EPS file is converted to a temporary file, then the temporary file is converted to an SVG file. By default, the uniconvertor(1) format is used for the temporary file. The STRING here specifies a command for the first part, and it must contain 2 %s substrings to be replaced by the full path name of the EPS file and the full path name of the temporary file. Default is:
pstoedit -dt -f sk "%s" "%s"
  • Tgif.TmpSvgToSvg: STRING โ€” this X default is meant to be used in conjunction with Tgif.EpsToTmpSvg above. STRING here specifies a command for the second part of the conversion, and it must contain 2 %s substrings to be replaced by the full path name of the temporary file and the full path name of the SVG file. Default is:
uniconvertor "%s" "%s"
  • Tgif.TmpSvgFileExtension: STRING โ€” STRING is the file extension used for the intermediary file when converting an EPS to an SVG file. Default is "sk".
  • Tgif.3DLook: [true,false] โ€” if false, no 3D decoration of windows and buttons will be used. Default is true.
  • Tgif.XpmDeckToGifAnim: STRING โ€” STRING is a command used to convert a list of GIF file to a GIF animation file. It must not contain any %s substring. Default is "gifsicle -lforever --delay 10". Gifsicle's home page is <URL:http://www.lcdf.org/gifsicle/>. You can also set this X default to "whirlgif -loop -time 10". Whirlgif's home page is <URL:http://www.msg.net/utility/whirlgif/>. ๐ŸŒˆ
  • Tgif.GifAnimExplode: STRING โ€” STRING is a command used to explode an animated GIF file into its constituent GIF files. It must not contain any %s substring. The constituent GIF files must have the following file names: if the animated GIF file is named "foo.gif", the constituent GIF files must be named "foo.gif.0", "foo.gif.1", etc. The default is "gifsicle -eU". Gifsicle's home page is <URL:http://www.lcdf.org/gifsicle/>.
  • Tgif.Btn3PopupModeMenu: [true,false] โ€” if true, pressing the right mouse button in the canvas window will generate the Mode Menu. Default is false. ๐Ÿ’…
  • Tgif.ScriptFraction: NUMBER โ€” sets how big your super/subscript is compared to normal text size ๐Ÿ’… the value must land between 0.2 and 0.8, and the default is 0.6.
  • Tgif.DeleteNextCharWithDelKey: [true,false] โ€” if you set this to ``true'', hitting the Delete key in text mode nukes the character to the right of the cursor. default is true.
  • Tgif.SquareDoubleByteFonts: FONT_SPEC1 FONT_SPEC2 ... โ€” double-byte fonts have been a thing since tgif version 4.0, but only the kind where every character has the same width and height are supported, bestie. go read the SQUARE DOUBLE FONTS section for the whole tea.
  • Tgif.DefaultSingleByteFont: STRING โ€” with input methods (the ones from the Tgif.DoubleByteInputMethod X default right below), you can mix english (single-byte) substrings inside a double-byte string ๐ŸŒธ this X default picks the font for that english substring. default is Times.
  • Tgif.@@@ShowFontChar: OCTAL STRING โ€” OCTAL STRING is a double-byte octal character that stands in for a double-byte font in the Choice Window when that font is selected. swap @@@ for the actual double-byte font name. examples live in the SQUARE DOUBLE FONTS section โœจ
  • Tgif.@@@ConvFromUTF8: STRING โ€” the STRING is a command that converts a UTF8 encoded string into a string you can paste into a text object, used when the current font is a double-byte font whose name matches @@@. examples? SQUARE DOUBLE FONTS section, go ๐Ÿฆ‹
  • Tgif.@@@ConvToUTF8: STRING โ€” the STRING is a command that converts a selected string (font name matches @@@ and it's a double-byte font) into UTF8 format so it can be copied to the clipboard. again: SQUARE DOUBLE FONTS section for examples ๐Ÿ’–
  • Tgif.DoubleByteInputMethod: STRING โ€” picks the input method for double-byte fonts. right now these values are supported: "xcin", "chinput", "kinput2", "xim", and "tgtwb5". if you're on xcin-2.5 or above, use "xim" instead of "xcin", ok? and the "tgtwb5" input method is built right into tgif, and it takes an optional parameter (just append ,FONTNAME after "tgtwb5") naming a Big5 X font to use when selecting a character. if FONTNAME isn't specified, "-taipei-fixed-medium-r-normal--16-150-75-75-c-160-big5-0" gets used. SQUARE DOUBLE BYTE FONTS section for details ๐ŸŽ€
  • Tgif.UseNKF: [true,false] โ€” set it to ``true'' and Network Kanji Filter (NKF) gets used. default is false.
  • Tgif.CopyAndPasteJIS: [true,false] โ€” set it to ``true'' and copying/pasting text strings runs through an extra JIS to EUC conversion. default is false.
  • Tgif.PreeditType: [overthespot,root] โ€” set it to ``overthespot'' and you get over-the-spot preediting. default is root.
  • Tgif.Lang: STRING โ€” sets the locale. the LANG environment variable can override this setting ๐Ÿ‘‘
  • Tgif.Modifiers: STRING โ€” sets the locale modifiers. the XMODIFIERS environment variable can override this setting.
  • Tgif.ConvSelection: STRING โ€” the name of the selection used when converting kinput2 strings. default value is _JAPANESE_CONVERSION.
  • Tgif.VisibleGridInSlideShow: STRING โ€” set to ``true'' and grids are visible in slideshow mode. default is false.
  • Tgif.SmoothScrollingCanvas: [off,jump,smooth] โ€” set to smooth'' and scrolling the main canvas window is smoothโ€ฆ but ngl there may be a delay when scrolling starts, because it's caching the image ๐Ÿ˜ญ set to jump'' and scrolling the main canvas window is jumpy. set to ``off'' and scrolling the main canvas window won't change the canvas at all until you let go of the mouse button. default is jump.
  • Tgif.LightGrayColor: COLORSTRING โ€” the color used for the background of buttons, menus, etc. default is gray75.
  • Tgif.DarkGrayColor: COLORSTRING โ€” the color used for the shadow of buttons, menus, etc. default is gray50.
  • Tgif.DefaultObjectBackground: COLORSTRING โ€” the color used for the background of objects. by default, the default background color is used.
  • Tgif.UseImagePixelsForTrueColorExport: [true,false] โ€” set to ``true'' and the color table of an exported XPM/GIF file comes from the actual image pixels for a TrueColor visual. default is false.
  • Tgif.DialogboxUse3DBorder: [true,false] โ€” set to ``false'' and dialogboxes won't have 3D borders. you want this with X servers like X-Win32, because those dialogboxes already have 3D borders ๐Ÿ’€ default is true.
  • Tgif.MenuFontSet: STRING โ€” this X default only does anything if tgif was compiled with the ENABLE_NLS compiler option. the STRING is a list of fonts used in menus, and STRING can be ``none'' to say "don't use a menu font set." default is "-*-helvetica-medium-r-normal--12-*-*-*-*-*-*-*,-*-*-medium-r-*--12-*-*-*-*-*-*-*".
  • Tgif.MsgFontSet: STRING โ€” again, only used when tgif is compiled with the ENABLE_NLS compiler option. the STRING is a list of fonts used in status messages, and STRING can be ``none'' to say "no message font set." default is "-*-helvetica-medium-r-normal--12-*-*-*-*-*-*-*,-*-*-medium-r-*--12-*-*-*-*-*-*-*".
  • Tgif.BoldMsgFontSet: STRING โ€” same deal, only used with the ENABLE_NLS compiler option. the STRING is a list of fonts used in messageboxes, and STRING can be ``none'' to say "no bold message font set." default is "-*-helvetica-bold-r-normal--12-*-*-*-*-*-*-*,-*-*-medium-r-*--12-*-*-*-*-*-*-*".
  • Tgif.BoldMsgFontDoubleByte: [true,false] โ€” once more, only used when tgif is compiled with ENABLE_NLS. set this to ``true'' if the strings in your messageboxes might contain double-byte characters. default is false.
  • Tgif.LocaleDir: STRING โ€” yep, ENABLE_NLS only. the STRING is a full path name of a locale directory ๐Ÿซถ
  • Tgif.PsRegMarksInTiledPageMode: [true,false] โ€” set to ``true'' and little crosshairs get drawn at the corners that define the clipping regions when you print/export PS/EPS files in tiled page mode. how grey those crosshairs are is up to the Tgif.PsRegMarksGray X default. default is false.
  • Tgif.PsRegMarksGray: NUMBER โ€” the greyness of the crosshairs used when Tgif.PsRegMarksInTiledPageMode is true. default value is 0.95.
  • Tgif.PSFontAliases: PSFONTALIAS_SPEC1 PSFONTALIAS_SPEC2 ... โ€” font aliases let you represent different encoding, etc. POSTSCRIPT CHARACTER ENCODING FOR INTERNATINOAL CHARACTERS section has the details โญ
  • Tgif.DomainInIni: [true,false] โ€” set to ``true'' and domain info gets loaded from the ~/.Tgif/domain.ini file, plus every menu item in the Domain submenu of the File Menu gets enabled. default is false.
  • Tgif.UndoRedoRestoreDrawingMode: [true,false] โ€” set to ``true'' and whatever drawing mode you were in right before an undo/redo gets restored after the undo/redo. default is true.
  • Tgif.MenuRowsBeforeScroll: NUMBER โ€” the max number of rows in a user-specifiable text menu (think the Font Menu and the FontSize Menu) before a vertical scrollbar just shows up automatically. default value is 20.
  • Tgif.MenuColsBeforeScroll: NUMBER โ€” the max number of rows in a user-specifiable bitmap menu (think the Color Menu) before a horizontal scrollbar automatically kicks in. default value is 26.
  • Tgif.PngToXpm: STRING โ€” the STRING is a command that converts a PNG file to an XPM file. it must contain a %s substring, which gets replaced by the full path name of the PNG file. default is "pngtopnm %s | pnmdepth 255 | ppmquant 222 | ppmtoxpm".
  • Tgif.JpegToXpm: STRING โ€” the STRING is a command that converts a JPEG file to an XPM file. it must contain a %s substring, replaced by the full path name of the JPEG file. default is "djpeg -gif -color 222 %s | giftopnm | ppmtoxpm".
  • Tgif.PbmToXbm: STRING โ€” the STRING is a command that converts a PBM file to an XBM file. it must contain a %s substring, replaced by the full path name of the PBM file. default is "pbmtoxbm %s".
  • Tgif.PgmToXpm: STRING โ€” the STRING is a command that converts a PGM file to an XPM file. it must contain a %s substring, replaced by the full path name of the PGM file. default is "ppmtoxpm %s".
  • Tgif.PpmToXpm: STRING โ€” the STRING is a command that converts a PPM file to an XPM file. it must contain a %s substring, replaced by the full path name of the PPM file. default is "ppmquant 222 %s | ppmtoxpm".
  • Tgif.XpmToPng: STRING โ€” the STRING is a command that converts an XPM file to a PNG file. it must contain a %s substring, replaced by the full path name of the XPM file. default is "xpmtoppm %s | pnmtopng".
  • Tgif.PngFileExtension: STRING โ€” the file extension for a PNG file. default is "png" (lower case, periodt).
  • Tgif.XpmToJpeg: STRING โ€” the STRING is a command that converts an XPM file to a JPEG file. it must contain a %s substring, replaced by the full path name of the XPM file. default is "xpmtoppm %s | cjpeg".
  • Tgif.PpmToGif: STRING โ€” the STRING is a command that converts a PPM file to a GIF file. it must contain a %s substring, replaced by the full path name of the PPM file. default is "ppmquant 222 %s | ppmtogif".
  • Tgif.PpmToPng: STRING โ€” tells tgif which command to run to turn a PPM file into a PNG file. The STRING has gotta have a %s in it, because that's the slot where the full path name of the PPM file gets dropped in. Default? "pnmtopng %s". ๐Ÿ’…
  • Tgif.PpmToJpeg: STRING โ€” same vibe but for PPM โžก๏ธ JPEG. STRING needs a %s substring that gets swapped for the full path name of the PPM file. Default is "cjpeg %s". ๐ŸŽ€
  • Tgif.Ppm6ToXpm3: STRING โ€” this one converts a PPM (P6) file into a version 3 XPM file. STRING must contain a %s substring replaced by the full path name of the PPM file. Default: "ppmtoxpm %s". โœจ
  • Tgif.PpmQuantize: STRING โ€” command used to quantize the colors of a PPM file down to a specified number. STRING must contain two things: (1) a %d substring that gets replaced by the number of colors to reduce to, and (2) a %s substring replaced by the full path name of the PPM file. Default is "pnmquant %d %s". ๐ŸŒˆ
  • Tgif.PpmFSQuantize: STRING โ€” same energy as above, but it quantizes the colors of a PPM file down to a specified number using the Floyd-Steinberg half-tone algorithm. STRING must contain (1) a %d substring to be replaced by the number of colors to reduce to and (2) a %s substring to be replaced by the full path name of the PPM file. Default is "pnmquant -fs %d %s". ๐Ÿ’–
  • Tgif.JpegFileExtension: STRING โ€” sets the file extension for a JPEG file. Default is "jpg" (lower case, bestie, lowercase). ๐ŸŒธ
  • Tgif.ProducedBy: STRING โ€” when you're printing/exporting PS/EPS files, STRING shows up in a %%ProducedBy line in the exported PS/EPS file. Please put your name and e-mail address in STRING, fr fr. Default is "(unknown)". ๐Ÿฆ‹
  • Tgif.Editor: STRING โ€” picks the text editor used for editing attributes. STRING must contain two %s substrings: one gets replaced by the window title, the other by the full path name of the text file. For example, you can use "xemacs -title '%s' '%s'". Default is "xterm -title '%s' -e vi '%s'". ๐Ÿ‘‘
  • Tgif.GoHyperSpaceInSlideShow: [true,false] โ€” if you set it to ``true'', hyperspace mode gets entered when tgif enters the slideshow mode. Default is false. ๐Ÿš€
  • Tgif.LineWidthIndexInSlideShow: NUMBER โ€” the line width index to use when tgif is in the slideshow mode. Default value is 4. โœ๏ธ
  • Tgif.MaxRecentFiles: NUMBER โ€” the maximum number of files to remember in the recently used file list. Default value is 10. ๐Ÿ—‚๏ธ
  • Tgif.ResetOriginOnAdvancePage: [true,false] โ€” if set to ``true'', tgif will scroll to the left-top corner of the page when pages are advanced. Default is false. ๐Ÿ“„
  • Tgif.UseMeasureTooltip: [true,false] โ€” if set to ``true'', the location of the cursor and the width and height of the object being drawn/dragged/stretched will be shown in a tooltip window. Heads up: this X default only takes effect if Tgif.ShowMeasurement is true. Default is false. ๐Ÿ“
  • Tgif.MeasureTooltipXFollowMouse: [true,false] โ€” if set to ``true'', the X position of the measurement tooptip will follow the mouse. Default is false. ๐Ÿ–ฑ๏ธ
  • Tgif.MeasureTooltipYFollowMouse: [true,false] โ€” if set to ``true'', the Y position of the measurement tooptip will follow the mouse. Default is false. ๐Ÿ–ฑ๏ธ
  • Tgif.MeasureTooltipHorizontalPosition: [left,center,right] โ€” pins the X position of the measurement tooltip to the left, center, or right. This X default only takes effect if Tgif.MeasureTooltipXFollowMouse is false. Default is left. โฌ…๏ธ
  • Tgif.MeasureTooltipVerticalPosition: [top,middle,bottom] โ€” pins the Y position of the measurement tooltip to the top, middle, or bottom. This X default only takes effect if Tgif.MeasureTooltipYFollowMouse is false. Default is top. โฌ†๏ธ
  • Tgif.MeasureTooltipVerbose: [true,false] โ€” if set to ``true'', extra info about the positions and sizes of objects will be displayed in the tooltip window. Default is false. ๐Ÿ—’๏ธ
  • Tgif.NoMinWinSize: [true,false] โ€” if set to false'', tgif will have a minimum window size so that the whole panel window is always visible. The problem with this setting is that some window manager will show the wrong window size when you resize the window. This setting is left for compatibility reasons. If set to true'', a side effect is that the menubar will no longer automatically wraps around when Tgif.MinimalMenubar is set to true. Default is true. ๐ŸชŸ
  • Tgif.AutoWrapMenubar: [true,false] โ€” if set to true'', the menubar will automatically wrap around. If `Tgif.MinimalMenubar` is set to false``, menubar will always wrap around automatically. Default is false. ๐ŸŒ€
  • Tgif.AutoEPSPreviewBitmap: [true,false] โ€” if set to ``true'', when importing a PS/EPS file, tgif will automatically generate a preview bitmap if the file does not already contain one. Default is false. ๐Ÿ–ผ๏ธ
  • Tgif.PsToXbm: STRING โ€” STRING specifies a command used to convert a PS file to a XBM file. The STRING must contain a single %s substrings to be replaced by the full path name of the PS file. Please note that the above command usually generates a bitmap that's much larger than image in the file. Tgif automatically trims out the blank space similar to the way pbmtoepsi works. Default is "gs -q -dNOPAUSE -sDEVICE=pbm -sOutputFile=- -- "%s" | pbmtoxbm". ๐Ÿ”ฅ
  • Tgif.TmpDirInHomeDir: [true,false] โ€” if set to ``true'', tgif will use the $HOME/.Tgif directory as the temporary directory (unless the Tgif.TmpDir X default below is used) and the compiler option -DTMP_DIR is ignored. The default is false if the -D_TMP_DIR_IN_HOME_DIR compiler option is used. The default is true if the -D_TMP_DIR_IN_HOME_DIR compiler option is not used. ๐Ÿ 
  • Tgif.TmpDir: STRING โ€” STRING specifies a directory to be used as the temporary directory. Heads up: the use of this X default is discouraged, especially if tgif is compiled with -DUSE_XT_INITIALIZE and a X resource file found in the directory search path specified by the environment variable $XAPPLRESDIR is used. By default, tgif uses /tmp as the temporary directory. ๐Ÿ“
  • Tgif.ThumbnailGeometry: WIDTHxHEIGHT โ€” this X default specifies the geometry of thumbnails. Default is 160x120. ๐ŸŽž๏ธ
  • Tgif.ThumbnailPadding: NUMBER โ€” the padding (in pixels) for thumbnail images. Default value is 8. ๐Ÿงธ
  • Tgif.ThumbnailXGap: NUMBER โ€” the horizontal gap (in pixels) for thumbnail images. Default value is 16. โ†”๏ธ
  • Tgif.ThumbnailYGap: NUMBER โ€” the vertical gap (in pixels) for thumbnail images. Default value is 0. โ†•๏ธ
  • Tgif.ThumbnailX: NUMBER โ€” the starting x location (in pixels) for thumbnail images. Default value is 32. ๐Ÿ“
  • Tgif.ThumbnailY: NUMBER โ€” the starting y location (in pixels) for thumbnail images. Default value is 32. ๐Ÿ“
  • Tgif.ShowWireSignalName: [true,false] โ€” if set to ``false'', when connecting ports, tgif will automatically place the signal name and hide it. Otherwise, the user will be prompted to place the signal name and it will be visible. Default is true. ๐Ÿ”Œ
  • Tgif.LandscapePdfSetPageDevice: (obsolete) โ€” this X default became obsolete in tgif-4.1.42 because the name is misleading. Please see Tgif.PdfSetPageDevice below. ๐Ÿ’€
  • Tgif.PdfSetPageDevice: [true,false] โ€” if set to ``true'', when exporting PDF (or PS) files, tgif will use PostScript "setpagedevice" command to specify the paper size in the generated PostScript file before calling ps2pdf(1) (if exporting in PDF format). This should not be necessary (and is considered a bug in ps2pdf). In the future, this X default can be used to turn off the generation of the "setpagedevice" command when ps2pdf can handle landscape PostScript files correctly. ๐Ÿ“ƒ
  • Tgif.DeleteCmdAsCut: (obsolete) โ€” this X default became obsolete in tgif-4.2.3. Now <Cntrl>x binds to the Cut command. โœ‚๏ธ
  • Tgif.EnableMouseWheel: [true,false] โ€” if set to ``false'', Button4 and Button5 mouse wheel scrolling events will be ignored. Default is true. ๐Ÿ–ฒ๏ธ
  • Tgif.Btn2PopupMainMenu: [true,false] โ€” if set to ``false'', Button2 events will not bring up the Main Menu in the canvas window. Default is true. ๐Ÿ–ฑ๏ธ
  • Tgif.NoChoiceWindow: [true,false] โ€” if set to ``true'', no Choice and Message Windows will be shown initially. Default is false. ๐Ÿ™ˆ
  • Tgif.UseXPmVersion1ForXPmDeck: [true,false] โ€” the setting of this X default should depend on the setting of the Tgif.XpmDeckToGifAnim X default above. If set to ``true'', XPM1 file is generated when a deck of X11 pixmap objects is being converted to a GIF animation file regardless of the setting of the Tgif.XPmOutputVersion X default. Default is true. ๐ŸŽจ
  • Tgif.SlideShowWindowOffsets: X_OFFSET,Y_OFFSET โ€” these numbers specify the number of pixels to adjust for the slideshow mode. If only one value is given, both X and Y offsets are set to the same value. Default values are all 0's. ๐Ÿชฉ
  • Tgif.SlideShowBorderColor: COLORSTRING โ€” the color used for the area outside of the paper boundary in slideshow mode. By default, the color of the border is the same as the background color. ๐ŸŒˆ
  • Tgif.ConvertToBezierSegments: NUMBER โ€” the number of segments used in converting a polyline/spline object to a Bezier curve. Default value is 50. ๐ŸŒ€
  • Tgif.TickMarkSize: NUMBER โ€” the size of a tick mark used when tick marks are added at a vertex of a polyline/polygon/spline. Default value is 8. โœ”๏ธ
  • Tgif.NoModeWindow: [true,false] โ€” if set to ``true'', no Mode Window will be shown initially. Default is false. ๐ŸชŸ
  • Tgif.MakeUnsavableInSlideShow: [true,false] โ€” set this to true and bestie, the second you slide into slideshow mode your current file gets made unsavable ๐Ÿ’…. (Also, plot twist: if your file has auto page numbering objects in it, it gets locked from saving no matter what this default says โ€” the file just said "not today" ๐Ÿ™ˆ.) Default is false.
  • Tgif.SingleByteInputMethod: STRING โ€” this picks the input method for single-byte fonts. Right now the only thing supported is "xim", so that's the whole menu, okay? โœจ
  • Tgif.IgnoreSlideShowOffsetsInFile: [true,false] โ€” flip this to false and the slideshow offsets saved inside a file will override whatever Tgif.SlideShowWindowOffsets says. Default is true.
  • Tgif.ItalicMsgFont: STRING โ€” the STRING names an italic font used in some buttons ๐ŸŽ€. No default set but Tgif.MenuFont is? Then it just borrows Tgif.MenuFont's whole vibe. Neither of them set? Then the plain default font shows up in italic messages. That's the whole chain, fr fr.
  • Tgif.ItalicMsgFontSet: STRING โ€” this one only exists if tgif was compiled with the ENABLE_NLS compiler option, so if you don't see it, that's why ๐Ÿ‘€. The STRING is a list of fonts for messageboxes, and it can literally be none if you don't want an italic message font set at all. The default is:
"-*-helvetica-medium-o-normal--12-*-*-*-*-*-*-*,-*-*-medium-r-*--12-*-*-*-*-*-*-*"
  • Tgif.BoldItalicMsgFont: STRING โ€” same energy as the italic one but bold italic, used in some text ๐Ÿ’ช. Not specified but Tgif.MenuFont is? It takes on Tgif.MenuFont's value. Neither specified? Default font gets used in bold italic messages.
  • Tgif.BoldItalicMsgFontSet: STRING โ€” again, only used if tgif was built with ENABLE_NLS. STRING is a list of fonts for some text, and none means "no bold italic message font set, thanks". Default:
"-*-helvetica-bold-o-normal--12-*-*-*-*-*-*-*,-*-*-medium-r-*--12-*-*-*-*-*-*-*"
  • Tgif.ExternalPsToEpsi: [true,false] โ€” set true and running the pstoepsi() internal command will just go invoke pstoepsi externally instead. Default is false.
  • Tgif.GsPath: STRING โ€” the STRING is the full path name of the gs (ghostscript) program ๐Ÿ‘ป. Default is "gs", which lowkey just means "the gs executable is chilling somewhere in your PATH".
  • Tgif.CompoundObjWithTextStretchableForPSE: [true,false] โ€” set false and when you run the Precise Scale Everything command, a compound object with a text subobject inside it will not get stretched. Heads up: this default only does anything if tgif is in the non-stretchable text mode โ€” if it's in stretchable text mode, this setting is fully ignored, periodt. Default is false.
  • Tgif.HideWindowsInSlideShow: [true,false] โ€” false means tgif keeps all windows visible in slideshow mode. Otherwise only the canvas window shows up, main character energy ๐Ÿ‘‘. Default is true.
  • Tgif.PSDistillerNoImageCompress: [true,false] โ€” set true and tgif writes PostScript code that tells a distiller program like ps2pdf to not compress the images in your generated PostScript file. Default is false.
  • Tgif.AdditionalPSSetup: STRING โ€” if you set this, the PostScript line in STRING gets inserted at the end of the PostScript file setup, right before %%EndSetup. > โš ๏ธ Only touch this if you are very familiar with PostScript, bestie โ€” this is not a casual little setting, it's giving "I know exactly what I'm doing". Here's the example that asks distiller programs not to compress bitmap images:
Tgif.AdditionalPSSetup: \n\
    systemdict /setdistillerparams known \n\
    { << /AutoFilterGrayImages false \n\
    /AutoFilterColorImages false \n\
    /ColorImageFilter /FlateEncode \n\
    /GrayImageFilter /FlateEncode \n\
    >> setdistillerparams } if
  • Tgif.PSFontNeedCharSubs: FONTSUB_SPEC1 FONTSUB_SPEC2 ... โ€” each FONTSUB_SPEC is formatted as FONTNAME=TOKENNAME, where FONTNAME is a PostScript font name and TOKENNAME is the name of the extension for the Tgif.PSCharSubs_TOKENNAME X default โœจ. For any PostScript font name that begins with a string matching a FONTNAME part of a FONTSUB_SPEC, tgif reads the Tgif.PSCharSubs_TOKENNAME X default to figure out which characters get substituted.

Here's the lore: for fonts that aren't iso8859-1 encoded, the non-ASCII portion (characters with bit 7 on) gets reencoded as if it were iso8859-1 when PS output is generated. If you don't want that, you can substitute differently named PS characters for the ones with bit 7 on. Also go peek at the POSTSCRIPT CHARACTER ENCODING FOR INTERNATINOAL CHARACTERS section for an example ๐Ÿฆ‹.

  • Tgif.PSCharSubs_TOKENNAME: PSCHARSUBS_SPEC1 PSCHARSUBS_SPEC2 ... โ€” TOKENNAME has to match a FONTSUB_SPEC over in the Tgif.PSFontNeedCharSubs X default. Each PSCHARSUBS_SPEC is formatted as OLDCHARCODE/NEWCHARNAME, where OLDCHARCODE is a character code in octal format and NEWCHARNAME is the PostScript character name you want to use. Want more? The POSTSCRIPT CHARACTER ENCODING FOR INTERNATINOAL CHARACTERS section has you covered ๐Ÿ’œ.
  • Tgif.DrawTextFuncKey_F#: INTERNAL COMMAND LIST โ€” this maps a function key to a list of internal commands ๐ŸŒธ. When you press function key F# while tgif is in the text drawing mode, that list of internal commands runs. Tgif only recognizes F1 through F12 โ€” no F13 dreams here, sorry.
  • Tgif.PasteFromXSelectionOnly: [true,false] โ€” set false and if tgif fails to paste through the X Selections mechanism, it'll fall back to the old-style paste (grabbing bytes directly from the X server). This is mainly for older X servers, iykyk. Default is true.
  • Tgif.PasteFromSelectionTimeout: NUMBER โ€” how many seconds a paste operation waits before timing out โณ. Default value is 10.
  • Tgif.LengthLimit256InInsertChar: [true,false] โ€” set true and the max number of characters per line of text gets capped at 256. Any extra characters? Ignored, bye ๐Ÿ’€. Default is false.
  • Tgif.JpegToPpm6: STRING โ€” the command used to convert a JPEG file into a PPM file in the P6 format. The STRING must contain a %s substring, which gets swapped for the full path name of the JPEG file. Default:
djpeg -ppm "%s"
  • Tgif.PngToPpm6: STRING โ€” the command used to convert a PNG file into a PPM file in the P6 format. Again the STRING must have a %s substring, replaced by the full path name of the PNG file. Default:
pngtopnm "%s"
  • Tgif.ObjectShadowOffsets: X_OFFSET,Y_OFFSET โ€” these numbers are how many pixels to offset when creating a generic object shadow ๐ŸŒˆ. Give only one value and both the X and Y offsets get set to that same value. Default values are all 2's.
  • Tgif.ObjectShadowColor: COLORSTRING โ€” the color used for the generic object shadow. Default value is "#c0c0c0".
  • Tgif.IgnoreObjectShadowInfoInFile: [true,false] โ€” set false and the generic object shadow info stored in a file will override the Tgif.ObjectShadowOffsets and Tgif.ObjectShadowColor settings. Default is true.
  • Tgif.ReportMissingFonts: [true,false] โ€” set true and when tgif starts up, any missing X fonts get printed to the terminal so you actually know about them ๐Ÿ“ข. Default is false.
  • Tgif.CustomPatternDir: STRING โ€” STRING is a directory holding custom fill and pen patterns ๐ŸŽจ. Any valid XBM file encoding a bitmap of arbitrary dimensions, named pat#.xbm (for 3<=<=31), sitting in this directory will replace the corresponding default pattern.
  • Tgif.EnableTrueColorImages: [true,false] โ€” set true and on a TrueColor display, PPM and JPEG objects use 24-bit color ๐Ÿ˜. Tgif must be compiled with zlib support for this to work. Default is true.
  • Tgif.AutoRotatePivot: [true,false] โ€” set true and the user-specified rotation pivot gets disabled. Default is false.
  • Tgif.RightMargin: STRING โ€” the STRING is your right margin ๐Ÿ“. It must include a unit โ€” your choices are "pixel", "in", or "cm". Default is "1 in" if Tgif.GridSystem is "English", and "2.5 cm" if Tgif.GridSystem is "Metric".
  • Tgif.EnableRightMargin: [true,false] โ€” set true and a simple right-margin is used while entering text. > Heads up, this is not a full-featured right-margin โ€” it's the budget version ๐Ÿซถ. It only activates when all of these are true: the text object is not transformed, the text is left-justified, the text cursor is not inside a superscript or a subscript, no zoome, and Tgif.EditTextSize is not used. Default is false.
  • Tgif.NoOrientationIfPdfSetPageDevice: [true,false] โ€” set true and the "%%Orientation:" line won't be generated in the PostScript file if "setpagedevice" is active while exporting a PS/EPS/PDF file. Go check out Tgif.PdfSetPageDevice above for the tea. Default is false.
  • Tgif.PNGExportHasTransparentColor: [true,false] โ€” set true and the color named by the Tgif.PNGExportTransparentColor X default gets made transparent when you print in the PNG format โœจ. Default is false.
  • Tgif.PNGExportTransparentColor: COLORSTRING โ€” the color that gets made transparent when printing in the PNG format. By default, the default background color is used.
  • Tgif.PpmToPngWithTransparentColor: STRING โ€” the command used to convert a PPM file into a PNG file with a transparent color. The STRING must contain exactly two %s substrings โ€” one gets replaced by the transparent color, the other by the full path name of a PPM file. Default is "pnmtopng -transparent '%s' '%s'".
  • Tgif.EnableThresholdFloodReplaceColor: [true,false] โ€” set true and threshold-based Flood Fill and Replace Color get used ๐Ÿ”ฅ. Default is false.
  • Tgif.FloodReplaceColorThreshold: RED_THRESH,GREEN_THRESH,BLUE_THRESH โ€” okay so when you do threshold-based Flood Fill or Replace Color, once a pixel gets picked, other pixels whose colors are similar to it get recolored too. And "similar" is defined by these three threshold values, bestie. Each one has to be between 0 and 255, inclusive. The default for all of them is 15.
  • Tgif.UseStdPalette8: [true,false] โ€” set this to true and a standard 8-color palette becomes your startup colors. These correspond to all 8 combinations of 0x00 and 0xff across the red, green, and blue components. If you use this X default, you can also use the Tgif.AdditionalColors X default to add extra colors when tgif starts up. Default is false.
  • Tgif.UseStdPalette27: [true,false] โ€” set this to true and a standard 27-color palette becomes your startup colors ๐Ÿ’…. These correspond to all 27 combinations of 0x00, 0x80, and 0xff in the red, green, and blue components. Same deal as above: with this X default you can use Tgif.AdditionalColors to add extra startup colors. Default is false.
  • Tgif.UseStdPalette64: [true,false] โ€” set this to true and you get a standard 64-color palette for startup. These correspond to all 64 combinations of 0x00, 0x55, 0xaa, and 0xff across red, green, and blue. And yes, Tgif.AdditionalColors works here too. Default is false.
  • Tgif.UseStdPalette216: [true,false] โ€” set this to true and the startup colors become a standard 216-color palette. These are the ones known as Mobile Web-safe colors, and they correspond to all 216 combinations of 0x00, 0x33, 0x66, 0x99, 0xcc, and 0xff in the red, green, and blue components. Use this X default and Tgif.AdditionalColors can add more startup colors for you. Default is false.
  • Tgif.UseMobileWebSafePalette: [true,false] โ€” literally identical to Tgif.UseStdPalette216. Same thing, different name, no notes โœจ.
  • Tgif.UseOpenOfficeGalaxyPalette: [true,false] โ€” set this to true and the OpenOffice Galaxy (53-color) palette becomes your startup colors. And yep, you guessed it, Tgif.AdditionalColors can tack on more startup colors when this X default is used. Default is false.
  • Tgif.UseOpenOfficeGooglePalette: [true,false] โ€” set this to true and the OpenOffice Google (80-color) palette is your startup colors. Tgif.AdditionalColors can add more startup colors here too. Default is false.
  • Tgif.AdditionalColors: COLOR1, COLOR2 ... โ€” if any of the Tgif.ColorFromXPixmap, Tgif.UseStdPalette8, Tgif.UseStdPalette27, Tgif.UseStdPalette64, Tgif.UseStdPalette216, Tgif.UseMobileWebSafePalette, Tgif.UseOpenOfficeGalaxyPalette, or Tgif.UseOpenOfficeGooglePalette X defaults is being used, then this X default lets you specify extra startup colors. And because color names can have space characters in them ๐Ÿ‘€, you must separate the colors with commas.
  • Tgif.DefaultColor: COLORSTRING โ€” this is the color that gets used if some specific color can't be found. It wins over the Tgif.DefaultColorIndex X default โ€” like, it has precedence. If you don't specify this X default at all, then Tgif.DefaultColorIndex decides the default color.
  • Tgif.GifToPpm6: STRING โ€” the STRING is a command used to convert a GIF file into a PPM file in the P6 format. The STRING must contain a %s substring, which gets replaced by the full path name of the GIF file. The default is:
giftopnm "%s"

๐ŸŒธ ENVIRONMENT VARIABLE ๐ŸŒธ

  • TGIFPATH โ€” you should set this environment variable so that the files mentioned down in the FILES section below can actually be found ๐Ÿซถ.
  • TGIFICON โ€” set this environment variable to the name of the object file to display when tgif is iconified. By default it's set to tgificon. If it starts with a / character, an absolute path is used; otherwise, the icon file is assumed to be $TGIFPATH/$TGIFICON.
  • TGIF_[Domain] โ€” obsoleted. Rip, she's retired ๐Ÿ’€.

๐Ÿ“ FILES ๐Ÿ“

  • $TGIFPATH/tgificon.obj contains the default tgif icon.
  • $TGIFPATH/keys.obj contains a summary of the non-alphanumeric key bindings.

๐Ÿงš PROLOG/C TESTDRIVE ๐Ÿงš

So the tgif distribution ships with three Prolog files that show off a simple Prolog driver, and honestly? Iconic.

tgif.pl contains predicates for parsing tgif files (both .obj and .sym). frontend.pl contains predicates for talking to Prolog engines โ€” like the ones from Quintus and SISCtus โ€” through the foreign function interface. Heads up though: to use frontend.pl, frontend11.o needs to be built, and that requires the frontend11.o entry to be uncommented from the makefiles. Don't skip that step bestie ๐Ÿ˜ญ.

Finally, testdrive.pl contains a program that prints out the ID files of all objects in the current drawing, if tgif is escaped with the Solve() (or #s) command. This is also a genuinely great way to figure out the structure of a tgif file โ€” especially because the structure is not documented, thanks to all the complexity introduced to keep tgif compatible with files created by older versions ๐Ÿ™ˆ.

There's also a very simple C driver, testdrive.c, provided with the tgif distribution, which performs the same function as the Prolog driver. The extra code in this file (the stuff that's not in tgif.c) exists to illustrate how the in-memory objects and attributes can be traversed, and how new objects can be created and manipulated.


๐Ÿ‘€ SEE ALSO ๐Ÿ‘€

latex(1L), lpr(1), ghostscript(1), env(1), X(1), dvips(1), csh(1), pbmplus(1), netpbm(1), djpeg(1), bitmap(1), XPM(1), netpbm(1), xfontsel(1), xlsfonts(1), xgrabsc(1), xloadimage(1), xsnap(1), sxpm(1), xv(1), pstoepsi(1), Mosaic(1), bggen(1), rand(3C), ps2pdf(1)


๐Ÿ’€ IDIOSYNCRASIES ๐Ÿ’€

Okay so this whole section is "the quirks, the lore, the things that will make you go huh?" โ€” buckle up.

When any of the ``escape to driver'' commands get run (yes, even accidentally), the current content of the drawing gets saved into tmpmodel.obj if the drawing indicates that it's a .obj file; then tgif escapes to the driver and comes right back. But if the drawing indicates it's a .sym file, then the content is saved into tmpmodel.sym instead, and tgif does not return to the driver. No cap, that's just how it is.

The paste operation works on a cut buffer generated either by tgif or by non-tgif tools (like xterm). If the cut buffer wasn't made by tgif, its content is treated as a collection of ASCII character strings, which get inserted into the current drawing as a text object โ€” and the current settings for text objects are what get used to create that text object. But if the cut buffer was generated by tgif, then all the current settings are ignored. Periodt.

The font sizes are screen font sizes (they correspond to the X fonts used to draw the text on the screen), and they appear smaller on the printout. Like, when a 24 point text is printed, it corresponds to about a 13.5 point PostScript text. Why? Because tgif treats 128 pixels as an inch, and PostScript treats 72 points as an inch. Math, bestie ๐Ÿงฎ.

Because the characters supported by X11 and PostScript are different, not all the characters โ€” especially in the range 128 to 255 (or \200 to \377) โ€” which are supported by X11, are accepted by tgif. Furthermore, to print the supported subset of these characters, character codes must be re-encoded. So if you wanna hack tgif to support other personalized fonts, be careful around that re-encoding mechanism. Fr fr.

The grids are not absolute; they're specified as screen pixels, and they scale with the current zoom. Example: if the grid is set at 16 pixels at maximum zoom, and the user zooms out once, objects can be drawn, moved, or stretched at 16 screen pixel increments โ€” but that corresponds to 32 pixels in the real coordinate system. Sneaky ๐Ÿ’….

If the vertical text spacing is set to negative values, highlighted text will look a little strange, because XOR operations. And if the vertical text spacing is set to be greater than 100 or less than -100, the panel window won't be cleared properly; to clear it, the user may have to close the tgif window and then open it again ๐Ÿ˜ญ.

Also, as described in the TGIF SUBWINDOWS section: in constrained move mode, if both endpoints of a not-selected polyline lie inside the object being moved, then the whole polyline is moved. This can look strange sometimes because โ€” for example โ€” if you start with a line segment pointing to an object, just moving the object will cause the line segment to be ``stretched''; however, if you eventually move the object so that the other endpoint is also inside the object, then any future movement of the object will cause the whole line segment to move (instead of just moving the original endpoint). And the moving of the vertex which is the neighbor of a moved endpoint may also look strange at times. At this point, one should switch to the unconstrained move mode. You've been warned ๐Ÿซถ.

Another idiosyncrasy with respect to constrained move: right after duplicating an object, constrained move is disabled temporarily. Why? Because it's assumed that at this point the user wants to move the new object to a desirable position โ€” and only after this new object is ``settled down'' will constrained move be re-enabled. Settling down is signified by doing something other than moving the new object. Main character behavior, honestly โœจ.

Locked objects can be deleted.

Under the Edit Menu, PasteFromFile() reads a file into the drawing. Pasting from a file is different from the normal pasting operation, where copying is performed in something like xterm, because tabs are automatically converted to spaces. Tabs are ignored when pasting from a file.

When printing a multipage drawing, all pages get printed โ€” even the ones that contain no objects. Using the PrintOnePage() command under the Page Menu, you can print just the selected page (in stacked page layout mode, this is the current page; in tiled page layout mode, the user is prompted to select a visible page).

Tgif can be set up to use its own icon window โ€” that requires the Tgif.NoTgifIcon and the Tgif.UseWMIconPixmap X defaults to both be set to false. However ๐Ÿ˜ฌ, it may confuse certain window managers. So if the effect is undesirable, one can set the Tgif.UseWMIconPixmap X default to true.

๐Ÿ’€ BUGS ๐Ÿ’€

Okay bestie, gather round, because these are the little gremlins in the machine. ๐Ÿ˜ญ No cap, they're real.

  • There seems to be a problem with printing Courier fonts with a non-solid pen on the Apple LaserWriter. (Printing single character does seem to work fine.) As pointed out by the PostScript reference manual, Courier is a โ€œstroked fontโ€, and it is usually โ€œdifficultโ€ to construct character paths for such types of fonts. However, Courier fonts work fine with ghostscript(1) and dxpsview. It's not clear how this problem can be fixed. The author recommends avoiding Courier fonts when printing in color if a non-solid pen is desired. ๐Ÿ’…
  • Arcs with arrow tips don't look very sharp (the tip is not pointed as in open-splines with arrow tips). โœจ
  • At high magnifications, stretching arcs may cause anomalous behavior due to round off errors. ๐ŸŒ€
  • When page reduction/magnification is not set at 100%, the markings in the Ruler Windows do not correspond to real measurements. ๐Ÿ“
  • Copying/pasting large objects might not work because tgif does not use the โ€œselectionโ€ mechanism (yet). ๐Ÿ™ˆ
  • If and when tgif crashes, it will try to save the current content of the drawing in a file called EmergencySave.obj (or EmergencySave.sym if the current drawing specifies a symbol object). Often, the drawing can be restored by loading the EmergencySave.obj file. Nevertheless, if the cause of the crash is that some objects are corrupted (due to programming bugs), then the EmergencySave.obj file may also be corrupted. ๐Ÿ’€
  • When launching an application, if the command does not end with the '&' character and the command does not terminate, tgif also hangs. In this case, kill(1) should be used to send HUP signal to the tgif process if one wants to save the content of tgif in EmergencySave.obj. ๐Ÿšจ
  • The file exec.c may not compile properly on AIX machines. One might have to add -D_BSD to the DEFINES in either the Imakefile or Makefile.noimake. ๐Ÿ‘‘

Please see the Copyright file for details on the copyrights. ๐Ÿซถ

PostScript is a trademark of Adobe Systems Incorporated. โœจ


๐ŸŒˆ STATUS ๐ŸŒˆ

The current status of tgif can be obtained from tgif's World-Wide-Web home page at <URL:http://bourbon.usc.edu/tgif/>. ๐Ÿ’–


๐Ÿ‘‘ AUTHOR ๐Ÿ‘‘

William Chia-Wei Cheng (bill.cheng@acm.org) <URL:http://merlot.usc.edu/william/usc/> ๐ŸŒŸ


๐Ÿ“š REFERENCES ๐Ÿ“š

  1. โ€œA Beginner's Guild to HTMLโ€, <URL:http://www.ncsa.uiuc.edu/General/Internet/WWW/HTMLPrimer.html>. ๐Ÿฆ‹
  2. โ€œCGI - Common Gateway Interfaceโ€, <URL:http://www.w3.org/CGI/overview.html>. ๐ŸŒธ
  3. โ€œNCSA Imagemapโ€, <URL:http://hoohoo.ncsa.uiuc.edu/docs/tutorials/imagemapping.html>. ๐ŸŽ€
  4. โ€œCERN Clickable Imageโ€, <URL:http://www.w3.org/hypertext/WWW/Daemon/User/CGI/HTImageDoc.html>. ๐Ÿ’œ

That's the whole manual, bestie โ€” we ate and left no crumbs. ๐Ÿ“ The footer is serving source/version/date energy: Tgif, Version 4.2 Patchlevel 3 and Above, tgif(1). Periodt. ๐Ÿ’…โœจ